1. 9

  2. 2

    This is a fantastic list. I don’t think I’d seen more than 70% of the variants, though I can see why they’d exist. The venerable 16550 contains a depressing number of them and also some fun legacy bits. Two adjacent 8-bit registers are set up so that, with a latch set, an 8-bit system can do a 16-bit write and have the two 8-bit bus messages end up in the right place. On modern systems, the registers are extended to 32-bits for the wider bus and so that little convenience becomes annoying.

    The last section is a bit light and it would be nice if it mentioned TDISP or, at least, SR-IOV.

    1. 1

      Interesting. I actually didn’t know about TDISP, and unfortunately I don’t have a copy of the spec (donations welcomed).

      SR-IOV is interesting but not sure it really changes anything from a register map perspective. Happy to add any other patterns if you can think of them.

      1. 1

        I’m not sure either change the register map itself, but both change how you get it and the semantics. With SR-IOV it’s a communication channel between the CPU a virtual device, with TDISP it’s a communication channel between a [virtual] device and a specific VM / enclave. S-IOV makes it more interesting by moving where the state is stored. Probably the interesting thing is that the ‘device registers’ abstraction is somewhat creaky under those layers and it really is a message channel.

        Oh, there’s one other mode made possible by recent CPUs: Modern Arm and x86 CPUs have instructions to do 64 byte stores to uncached as a single atomic operation, which lets you write an entire PCIe message directly from software.

        1. 1

          64 byte stores… that’s really interesting. But what do you mean by a PCIe message? Are there devices which give the host direct access to generate PCIe TLPs? If so, what devices (sounds fun to hack on)?