diff options
author | Liav A <liavalb@gmail.com> | 2022-09-23 11:50:26 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-09-23 17:22:15 +0100 |
commit | f46cc90f82ccd28cc72d8a07c4473fcd509615af (patch) | |
tree | 20e6298d8c0c65e2d5895cac7f0e2311a743497e /Documentation/Kernel | |
parent | 05ba0340006e57aaa62d0b962238fa7686df8e06 (diff) | |
download | serenity-f46cc90f82ccd28cc72d8a07c4473fcd509615af.zip |
Documentation: Add a document about the Kernel IOWindow concept
Diffstat (limited to 'Documentation/Kernel')
-rw-r--r-- | Documentation/Kernel/IOWindow.md | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/Documentation/Kernel/IOWindow.md b/Documentation/Kernel/IOWindow.md new file mode 100644 index 0000000000..8be29b702c --- /dev/null +++ b/Documentation/Kernel/IOWindow.md @@ -0,0 +1,62 @@ +# The IOWindow class + +## Introduction to port-mapped IO and memory-mapped IO + +### Port-mapped IO + +Port mapped IO is a x86-specific method to access hardware registers. It uses a +set of specific instructions in the x86 architecture to invoke Input and Output operations +on hardware that is present in the platform board. + +```c++ +IOAddress io(0x3f0) +u8 ide_status = io.offset(0).in<u8>() +``` + + +### Memory-mapped IO + +Memory mapped IO is a platform-agnostic method to access hardware registers. It uses a +set of memory access instructions in many computer architectures to invoke Input and Output operations +on hardware that is present in the platform board. + +```c++ +auto mapping = Memory::TypedMapping::map_typed_writable<u16>(0xb8000); +*mapping = 0x001b; +``` + +## The `IOWindow` class to rule them all (almost)! + +The entire idea behind the `IOWindow` class is to make it much more easier to compile +the Kernel for non-x86 builds, so the class abstracts platform-specific methods to access +hardware such as the port-mapped IO method. In compile-time, when generating a Kernel for +non-x86 target, the entire port-mapped IO code is omitted as it's not relevant for non-x86 +targets. + +In many cases, devices (such as PCI devices) can either use the IO space or memory space +to expose their registers for the CPU to utilize as the host software invokes IO operations +for various reasons. Some devices expose equivalent registers in both the IO space and memory space +to help legacy host software to interact with the hardware. One example to this is old AHCI controllers +which could be used in legacy mode - i.e. exposing SFF IDE registers in the IO space, or to enable memory +mapped registers as being defined in the SATA AHCI HBA specification. + +The general rule in kernel driver programming is to know that there are only two valid +cases on whether to use the `IOWindow` structure or not: +1. The device is known to either use the IO space, memory space or both, taking into +consideration that variants of the device can disable either of the options. In this case, +we need to use the `IOWindow` structure as it will help us to correctly use the IO window +in either case. +2. The device is known to use only the memory space, therefore we can ignore the `IOWindow` +structure and instead use the `Memory::TypedMapping` structure to help navigating in +the memory-mapped registers of the device. + +# A note about 64 bit access for memory mapped IO + +As far as we can tell, writing to 64 bit register can actually be done for the most part +with two 32 bit IO access operations. When genuine 64 bit access is needed, `IOWindow` is +probably not the appropriate solution anyway, because the device is only supporting memory-mapped IO +and there's no way it can provide register access via port mapped IO - that method simply doesn't +support generating 64 bit IO access, so you should use the `Memory::TypedMapping` mapping method instead. + +Therefore, to ensure we keep everything simple, there's simply no API to generate pure 64 bit IO access with +the `IOWindow` class. |