
Memory-mapped I/O without mysterious macros - ingve
https://lwn.net/SubscriberLink/780710/ece0f8b930151422/
======
monocasa
On a tangentially related note, I love the PowerPC instruction to act as a
mmio barrier: Enforce In Order Execution of I/O, or eieio.

For those anglophones that remember the kids' song "Old McDonald Had a Farm",
your code can pretty easily follow the song.

    
    
      read_a_register_right_here();
      eieio();
      then_write_a_register_right_here();
      eieio();
    
      bookkeep_here();
      bookkeep_there();
      a_lot_more_bookkeep_everywhere();
    
      then_write_a_register_right_here();
      eieio();

~~~
teddyh
EIEIO is also an error code typedef in GNU libc:

[https://www.gnu.org/software/libc/manual/html_node/Error-
Cod...](https://www.gnu.org/software/libc/manual/html_node/Error-
Codes.html#index-EIEIO)

“Computer bought the farm.”

------
userbinator
_While I /O memory looks like memory, and it can be tempting to access it by
simply dereferencing a pointer, that does not always work on every
architecture_

Unfortunate that there's no examples, because that sounds more like something
which is not actually MMIO (like the I/O space on x86) or a bug, since one of
the reasons for using MMIO is that it behaves like memory.

~~~
ajross
Even memory doesn't behave like memory. The order that DRAM sees your writes
doesn't necessarily match the order in which you thought they were written,
even though the CPUs themselves take extraordinarily complicated pains to make
it look the same everywhere. You might thing you're writing into a uniform
space with byte granularity, but under the hood the bus is logically 512 bits
wide and accessed almost exclusively in whole cache lines.

There are long specifications in every architecture that detail exactly how
the memory model works. Nothing is simple.

And in the case of MMIO devices, they tend to care about things software
doesn't (like, you must write 32 bit words aligned on 128 bit boundaries or it
doesn't work -- stuff like that), so the rules get even hairier.

------
twtw
I need to take a look at the patches (on mobile now), but can anyone comment
on how a barrier at unlock can provide ordering between mmio accesses under
the same lock? Or is it required that every register have a unique lock?

~~~
AnssiH
It doesn't, this is about this case:

    
    
      CPU1:
      lock()
      write1
      unlock()
      
      CPU2, after CPU1:
      lock()
      write2
      unlock()
    

Until now it was not guaranteed on all platforms that the writes arrive in the
same order even if the CPU2 entered the critical section after CPU1.

This was because spinlocks only implied regular memory barriers, not mmiowb
barriers.

