3 ms·
Yes, you can use memory barriers for MMIO but you'd have to put them between every single statement that touches the MMIO address range. Not only will that blo
by Avernar 11y ago
Yes, you can use memory barriers for MMIO but you'd have to put them between every single statement that touches the MMIO address range. Not only will that bloat your code it would slow down access to all your regular variables as the compiler would have to reload everything constantly and the processor wouldn't be able to out of order anything.
Why do you think volatile won't work for MMIO with the proper MTRR/PAT setup? The volatile keeps the compiler for messing with the read/writes and the MTRR/PAT makes the processor perform all reads and writes exactly in the order the instructions tell it to without any caching or write combining.
"This is more complicated than just doing the access from assembly." and "It's also not something you can rely on if you want to write portable code." So in one paragraph you're telling me to do it in assembly and in another you want portable code.
The linux kernel has gone above and beyond using volatile but in embedded it's how IO is done when using C.
- burfog 11y agoI make the assumption that you put the inline assembly in a macro. This keeps your C portable. The macro gets pulled in from a header file that is specific to the CPU. MTRR/PAT won't save you, at least without a huge performance loss, when you want write combining (etc.) for most of the addresses in a page of address space but not all of them. MTRR/PAT won't save you from reordering that happens in a PCI bridge. It's allowed and it is done.
- Avernar 11y agoWe're into semantics here. Portable requiring a CPU shim vs portable not requiring one. More complicated cpu/bus interfaces require the first one but if you can just use volatile for IO as done in embedded work you get much smaller and/or faster code. If a device has registers that are sensitive to multiple read/writes of the same address and ones that need caching and write combining for performance in the same 4K page then it was designed poorly. :) PCI bridges need to support legacy mode. Otherwise DOS programs and drivers wouldn't run correctly. The BIOS sets up a compatibility MTRR setup for this reason and you can see the Linux kernel print it out on boot. So I'm basically agreeing and disagreeing with you on this one. Once the hardware gets past a certain complexity you need to move from volatile to accessor functions/macros.