All of lore.kernel.org
 help / color / mirror / Atom feed
* 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

* 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.