[U-Boot] [PATCH] include/ns16550.h: Unify structure declaration for registers
Shinya Kuribayashi
skuribay at pobox.com
Wed Apr 29 20:51:02 CEST 2009
Detlev Zundel wrote:
> As I said, I understand now why there were different data-types involved
> although this was kind of non-obvious. So I take it, you had a working
> configuration with REG_SIZE = 4, correct?
I might be unclear. I used to use REG_SIZE = -16, as 16550 registers
are located at 0, +0x10, +0x20, ..., .
In this case, I don't think REG_SIZE = 4/-4 works. Let's see:
REG_SIZE = 4
------------
struct NS16550 {
unsigned char prepad_rbr[3];
unsigned char rbr;
unsigned char prepad_ier[3];
unsigned char ier;
:
:
};
REG_SIZE = -4
-------------
struct NS16550 {
unsigned char rbr;
unsigned char postpad_rbr[3];
unsigned char ier;
unsigned char postpad_ier[3];
:
:
};
because 16550 registers can be aligned in 16-bytes-interval.
And make things worse, REG_SIZE = 16/-16 also don't work.
REG_SIZE = 16
-------------
struct NS16550 {
unsigned char prepad_rbr[15];
unsigned char rbr;
unsigned char prepad_ier[15];
unsigned char ier;
:
:
};
REG_SIZE = -16
--------------
struct NS16550 {
unsigned char rbr;
unsigned char postpad_rbr[15];
unsigned char ier;
unsigned char postpad_ier[15];
:
:
};
What I need is something like this:
struct NS16550 {
unsigned char prepad_rbr[3];
unsigned char rbr;
unsigned char postpad_rbr[12];
:
:
};
or this also might work,
struct NS16550 {
unsigned long rbr;
unsigned long pre_padrbr[3];
: ^^^^
:
};
Makes sense?
> Can you enlighten me, why exactly the 8-bit accesses do not work on your
> hardware? Is this because of a "too simplistic" address decoding logic?
> What endianness is your CPU using?
I don't know much about precise hardware logics, but the byte addresses
under 16-bytes-border are ignored. I'm using a big-endian mips machine.
> I see. Actually I was looking a lot at the Linux driver but was hoping
> that we could away without introducing serial_{in,out}...
In my horrible opinion, the combinations of base addres + reg_shift
+ iotype (char, long, or whatever), are simpler, more configurable,
more slid, easy to use, than what we used to have or what you
consolidated this time.
> diff --git a/include/ns16550.h b/include/ns16550.h
> index ce606b5..7924396 100644
> --- a/include/ns16550.h
> +++ b/include/ns16550.h
> @@ -21,16 +21,20 @@
> * will not allocate storage for arrays of size 0
> */
>
> +#if !defined(CONFIG_SYS_NS16550_REG_TYPE)
> +#define UART_REG_TYPE unsigned char
> +#endif
> +
> #if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
> #error "Please define NS16550 registers size."
> #elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
> -#define UART_REG(x) \
> - unsigned char prepad_##x[CONFIG_SYS_NS16550_REG_SIZE - 1]; \
> - unsigned char x;
> +#define UART_REG(x) \
> + UART_REG_TYPE prepad_##x[CONFIG_SYS_NS16550_REG_SIZE - sizeof(UART_REG_TYPE)]; \
> + UART_REG_TYPE x;
> #elif (CONFIG_SYS_NS16550_REG_SIZE < 0)
> #define UART_REG(x) \
> - unsigned char x; \
> - unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
> + UART_REG_TYPE x; \
> + UART_REG_TYPE postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - sizeof(UART_REG_TYPE)];
> #endif
>
> struct NS16550 {
>
>
> Then you could do a
>
> #define CONFIG_SYS_NS16550_REG_SIZE 4
> #define CONFIG_SYS_NS16550_REG_TYPE unsigned long
>
> This of course needs to be documented once it works ;)
Looks to me like playing with macros...
Shinya
More information about the U-Boot
mailing list