* IO, ANSI vs GCC structs
@ 2003-07-25 15:30 Kent Borg
2003-07-25 15:51 ` Bret Indrelee
0 siblings, 1 reply; 7+ messages in thread
From: Kent Borg @ 2003-07-25 15:30 UTC (permalink / raw)
To: linuxppc-embedded
The PPC arch likes to access physical devices with C structures that
correspond to a memory map of device registers. But a colleague says
that structure layout is not guaranteed. In fact, he cited two
instances when he got burned by assuming he could predict structure
layout. But neither of those examples were with GCC.
Does GCC make guarantees beyond what ANSI requires? Is there some
subtle detail that forces struct layout ("volatile" in the definition
perhaps)?
Thanks,
-kb
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: IO, ANSI vs GCC structs 2003-07-25 15:30 IO, ANSI vs GCC structs Kent Borg @ 2003-07-25 15:51 ` Bret Indrelee 2003-07-25 16:19 ` Wolfgang Denk 0 siblings, 1 reply; 7+ messages in thread From: Bret Indrelee @ 2003-07-25 15:51 UTC (permalink / raw) To: Kent Borg; +Cc: linuxppc-embedded On Fri, 25 Jul 2003, Kent Borg wrote: > The PPC arch likes to access physical devices with C structures that > correspond to a memory map of device registers. But a colleague says > that structure layout is not guaranteed. In fact, he cited two > instances when he got burned by assuming he could predict structure > layout. But neither of those examples were with GCC. > > Does GCC make guarantees beyond what ANSI requires? Is there some > subtle detail that forces struct layout ("volatile" in the definition > perhaps)? There is nothing that guarentees this, in ANSI or GCC. There are several things you can do which will work on all compilers I've ever used (works in practice) and allow you to detect if the assumptions are ever violated. You can't use bit-fields. Don't even try. You should always use fixed-width named types. I think you can use stdint on most systems, when I started doing this there wasn't a common include I could use everywhere so I ended up making my own. What you basically want is the integer types uint8_t, uint16_t, uint32_t. Make sure that the structure stays properly aligned, no 16-bit or 32-bit quantities starting on an odd address or 32-bit quantities starting on an address that isn't 4-byte aligned. Define your structures using only these types. Make sure you put in filler for address space that doesn't have registers in them. In your code, do a check on the sizeof() the structure, make sure that it matches what you expect. Example: typedef struct mm_foobolizer { uint8_t bar1; uint8_t bar2; uint16_t filler002; /* I use the offeset address in naming fillers */ uint32_t sna; uint16_t fu; uint16_t filler00a; uint8_t buffer[0xa1]; uint8_t filler0ad; uint16_t filler0ae; uint32_t word_buf[0x100]; } my_reg_def_t; #define EXPECTED_REG_SIZE 0x500 In your code, do the equivilent of: assert(EXPECTED_REG_SIZE == sizeof(my_reg_def_t)); That should get you past the worst of the problems. -Bret -- Bret Indrelee QLogic Corporation Bret.Indrelee@qlogic.com 6321 Bury Drive, St 13, Eden Prairie, MN 55346 ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: IO, ANSI vs GCC structs 2003-07-25 15:51 ` Bret Indrelee @ 2003-07-25 16:19 ` Wolfgang Denk 2003-07-25 17:47 ` Kent Borg 0 siblings, 1 reply; 7+ messages in thread From: Wolfgang Denk @ 2003-07-25 16:19 UTC (permalink / raw) To: Bret Indrelee; +Cc: Kent Borg, linuxppc-embedded In message <Pine.LNX.4.44.0307251038370.22864-100000@spider.ancor.com> you wrote: > > > Does GCC make guarantees beyond what ANSI requires? Is there some > > subtle detail that forces struct layout ("volatile" in the definition > > perhaps)? > > There is nothing that guarentees this, in ANSI or GCC. You can use "__attribute__ ((packed))" with GCC which guaratees you control over the alignment used by the compiler (it will use the smallest possible alignment = one byte for a variable, and one bit for a field, unless you specify a larger value with the `aligned' attribute). Best regards, Wolfgang Denk -- Software Engineering: Embedded and Realtime Systems, Embedded Linux Phone: (+49)-8142-4596-87 Fax: (+49)-8142-4596-88 Email: wd@denx.de The human race has one really effective weapon, and that is laughter. - Mark Twain ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: IO, ANSI vs GCC structs 2003-07-25 16:19 ` Wolfgang Denk @ 2003-07-25 17:47 ` Kent Borg 2003-07-25 19:22 ` Wolfgang Denk 2003-07-25 21:45 ` Paul Mackerras 0 siblings, 2 replies; 7+ messages in thread From: Kent Borg @ 2003-07-25 17:47 UTC (permalink / raw) To: linuxppc-embedded How important is it to the kernel coding style that hardware be accessed through a structure? Is it acceptable to do: #define MYHW (MY_MBAR+42) ... out_be32(MYHW, 0xco1df00d); ? Thanks, -kb ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: IO, ANSI vs GCC structs 2003-07-25 17:47 ` Kent Borg @ 2003-07-25 19:22 ` Wolfgang Denk 2003-07-25 21:45 ` Paul Mackerras 1 sibling, 0 replies; 7+ messages in thread From: Wolfgang Denk @ 2003-07-25 19:22 UTC (permalink / raw) To: Kent Borg; +Cc: linuxppc-embedded In message <20030725134734.J29161@borg.org> you wrote: > > How important is it to the kernel coding style that hardware be I cannot speak for the powers that be, but... > accessed through a structure? Is it acceptable to do: > > #define MYHW (MY_MBAR+42) > > ... > > out_be32(MYHW, 0xco1df00d); ...I would not accept such code. There is one fundamental difference: a field in a struct has a type, i. e. the compiler "knows" how big it is (8, 16, 32, ... bits), if special attributes apply (volatile), etc. There is no such information with a #define like yours above. OK, you can write #define FOO ((volatile uint32_t *)(FOO_BASE+FOO_OFFSET)) but this isn't really readable, is it? Just my $0.02 Best regards, Wolfgang Denk -- Software Engineering: Embedded and Realtime Systems, Embedded Linux Phone: (+49)-8142-4596-87 Fax: (+49)-8142-4596-88 Email: wd@denx.de They say a little knowledge is a dangerous thing, but it is not one half so bad as a lot of ignorance. - Terry Pratchett, _Equal Rites_ ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: IO, ANSI vs GCC structs 2003-07-25 17:47 ` Kent Borg 2003-07-25 19:22 ` Wolfgang Denk @ 2003-07-25 21:45 ` Paul Mackerras 1 sibling, 0 replies; 7+ messages in thread From: Paul Mackerras @ 2003-07-25 21:45 UTC (permalink / raw) To: Kent Borg; +Cc: linuxppc-embedded Kent Borg writes: > How important is it to the kernel coding style that hardware be > accessed through a structure? Is it acceptable to do: > > #define MYHW (MY_MBAR+42) > > ... > > out_be32(MYHW, 0xco1df00d); Hmmm. You should be using a value returned from ioremap() (or equivalent) rather than a hard-coded constant. Yes I know that people set up 1-1 mappings with io_block_mapping and then do out_be32 to hard-coded constant addresses but that is deprecated. My preference is to define the offsets for individual registers as constants rather than using a structure. Paul. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <5.1.0.14.2.20030725123123.03855f58@mail.ebshome.net>]
* Re: IO, ANSI vs GCC structs [not found] <5.1.0.14.2.20030725123123.03855f58@mail.ebshome.net> @ 2003-07-25 19:59 ` Bret Indrelee 0 siblings, 0 replies; 7+ messages in thread From: Bret Indrelee @ 2003-07-25 19:59 UTC (permalink / raw) To: Eugene Surovegin; +Cc: Wolfgang Denk, Kent Borg, linuxppc-embedded On Fri, 25 Jul 2003, Eugene Surovegin wrote: > At 12:22 PM 7/25/2003, Wolfgang Denk wrote: > > > accessed through a structure? Is it acceptable to do: > > > > > > #define MYHW (MY_MBAR+42) > > > > > > ... > > > > > > out_be32(MYHW, 0xco1df00d); > > > >...I would not accept such code. > > > >There is one fundamental difference: a field in a struct has a type, > >i. e. the compiler "knows" how big it is (8, 16, 32, ... bits), if > >special attributes apply (volatile), etc. > > Although functions like out_be32 also *know* the size :). > > IMHO, it's not a good idea to access IO remmaped registers simply through C > struct, it's better and safe to use out_* and in_*. Wouldn't best practices also include using a base address rather than a constant, so that when a new board places the hardware in a different location all you have to do is find it? out_be32(my_bar + offsetof(myregs_t, sna_reg), 0xdeadbeef); > There are issues that C struct cannot deal with - load/store reodering (of > course you can insert wmb() and friends if you know what you are doing :). > > I think the best practice is to use C struct (for readability) and > out_*/in_* on structure members for actual access. I've always written low level I/O routines for everything in a driver because it is easier to adapt when someone changes how they want to do access to the device. The code all calls the low level IO routines. -Bret -- Bret Indrelee QLogic Corporation Bret.Indrelee@qlogic.com 6321 Bury Drive, St 13, Eden Prairie, MN 55346 ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-07-25 21:45 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-07-25 15:30 IO, ANSI vs GCC structs Kent Borg
2003-07-25 15:51 ` Bret Indrelee
2003-07-25 16:19 ` Wolfgang Denk
2003-07-25 17:47 ` Kent Borg
2003-07-25 19:22 ` Wolfgang Denk
2003-07-25 21:45 ` Paul Mackerras
[not found] <5.1.0.14.2.20030725123123.03855f58@mail.ebshome.net>
2003-07-25 19:59 ` Bret Indrelee
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).