Re: [PATCH v6 2/2] clocksource: add J-Core timer/clocksource driver

From: Arnd Bergmann
Date: Wed Aug 24 2016 - 18:04:15 EST


On Wednesday, August 24, 2016 5:44:44 PM CEST Rich Felker wrote:
> On Wed, Aug 24, 2016 at 10:22:13PM +0100, Mark Rutland wrote:
> > On Wed, Aug 24, 2016 at 04:52:26PM -0400, Rich Felker wrote:
> > As Arnd and others mentioned, the vastly common case is that the endianness of
> > CPUs and devices is not fixed to each other, and devices are typically
> > little-endian.
>
> Since it's not used in other designs, I can't say anything meaningful
> about how it hypothetically might be, but the intent on all current
> and currently-planned systems is that 32-bit loads/stores be performed
> using values that are meaningful as values on the cpu, i.e. with no
> byte swapping regardless of cpu endianness. The current hardware is
> designed as big-endian, and the proposed patches for supporting little
> endian just involve flipping the low bits of the address for 16- and
> 8-bit accesses (not relevant to mmio registers that are only
> accessible in 32-bit units).
>
> > > >
> > > > Exceptions to this are:
> > > >
> > > > * Some architectures (e.g. PowerPC) typically run big-endian code,
> > > > and hardware designers decided to make the MMIO registers the
> > > > same. In this case, you can generally use ioread32_be/iowrite32_be.
> > >
> > > This is something like our case, but the mmio registers are accessed
> > > as 32-bit values and the endianness does not come into play.
> >
> > This really depends on you endianness model, bus, etc. The above sounds like
> > BE32 rather than BE8, assuming I've understood correctly, which is an unusual
> > case nowadays.

Correct, which is the last case I had in my list, not the first one:

> > > * Some (usually very old) SoCs have configurable endianess, but
> > > don't actually change the behavior of the SoC or the MMIO devices,
> > > but only flip the address lines on the memory interface.
> > > This is similar to the previous one, but has additional problems
> > > with FIFO registers. You generally cannot use portable drivers
> > > here.

With your description above, that would probably be called LE32, given
that the native ordering is big-endian, and the little-endian mode
is only approximated using address magic. ARM BE32 mode (e.g. on IXP4xx)
did it the other way round.

> I'm not familiar with those classifications, but from what I can tell,
> BE32 describes it correctly. I'll see if I can get someone to verify
> this. Is there a reason it's not widely used anymore? Perhaps
> something related to supporting misaligned word-sized loads/stores?

The main problem I see is that you can't easily use MMIO registers that
are not 32-bit wide -- you end up having to flip not just the register
contents but also the lower bits of the address in order to reach
the right contents of the register.

If you can guarantee that all registers are 32-bit wide, you can
create a header file with your own MMIO accessors that wrap around
readl/write or ioread32_be/iowrite32_be depending on the kernel
endianess, and don't provide readb/writeb or readw/writew wrappers.

However, what everyone else does these days is to flip the register
values in load/store instructions when the opposite endianess is
selected, or to have two sets of load/store instructions and leave
it up to the compiler to pick which one to use (probably not
an option for you, since you use an existing instruction set).
If you do that, all portable device drivers should work fine
on your architecture.

Arnd