IMO memory-mapped IO is the coolest thing since sliced bread. It's a great example in computing where many different kinds of hardware can all be brought together under a relatively simple abstraction.
It was a glorious "click" when learning embedded programming. Even when writing Rust in typical desktop uses, it all feels... abstract. Computer program logic. Where does the magic happen? Where do you go from abstract logic to making things happen? The answer is in voltatile memory reads and writes to memory-mapped IO. You write a word to a memory address, and a voltage changes. Etc.
The volatile keyword in C has nothing to do with cache coherence and does not prevent cache coherence issues.
It just forces the compiler to generate all memory accesses on this variable. And if this variable is in a cached memory region, then it opens the door to very usual cache coherency problems
You'd still have to tell the compiler it's volatile if you were writing into the DMA buffer directly for some reason. GP just used the wrong words to say what they meant.