summaryrefslogtreecommitdiff
path: root/Documentation/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-09-23 11:50:26 +0300
committerLinus Groh <mail@linusgroh.de>2022-09-23 17:22:15 +0100
commitf46cc90f82ccd28cc72d8a07c4473fcd509615af (patch)
tree20e6298d8c0c65e2d5895cac7f0e2311a743497e /Documentation/Kernel
parent05ba0340006e57aaa62d0b962238fa7686df8e06 (diff)
downloadserenity-f46cc90f82ccd28cc72d8a07c4473fcd509615af.zip
Documentation: Add a document about the Kernel IOWindow concept
Diffstat (limited to 'Documentation/Kernel')
-rw-r--r--Documentation/Kernel/IOWindow.md62
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.