How does writing CPU's I/O ports let CPU control I/O devices
Posted: Fri May 17, 2019 6:41 pm
From the programmer's point of view, communicating with I/O devices is really simple and straightforward with a consistent, backward compatible interface. Usually, the way communication happens with the I/O devices is by issuing CPU instructions that write to CPU's I/O ports. Hardware device controllers have internal registers that controls them (Requesting stuff from th device, r/w stuff from/to the device ...etc.). Those internal registers, of each device controller, are mapped to the CPU's I/O ports so that writing and reading to CPU's I/O ports is actually writing and reading to the device's registers and thus controlling the device. That's an interesting way to make life easier on the programmer by abstracting all the horrible physical details and the underlying system's architecture.
However, we all know that there is more than this on the physical system level, I/O devices have different interfaces (IDE, SCSI, LPI ... etc) based on their nature and needs. And they are connected on different types of buses (AT, PCI, PCIe, IDE). CPUs gets connected by high speed, special purpose proprietary buses with the RAM. They connect on standardized high speed buses like PCIe with other high speed devices like Ethernet cards and Graphics cards and all gets linked through some kind of a north bridge that contains the PCI controller hub and other stuff. Low speed and legacy devices (Keyboards, IDE drives, BIOS ... etc) are bridged through a platform controller hub or a south bridge (Intel's terminology).
Now, the thing that i don't clearly see is how does the communication happen in real life with all those details and buses ? I mean how does writing some integer value into some CPU's I/O port by issuing a simple CPU instruction like
movb $PORT, %dh
outb %al, %dh
gets propagated through all the system's hardware components (Buses, Bridges, Controllers ... etc.) and eventually gets written to, let's say, the IDE's disk controller's commands register and thus commands the disk to perform some action (R/W a sector) ?
What puzzles me more is that the same port, the same instructions causes the same things to happen even after years of radical architectural changes (Changes in buses specifications, system architecture ... etc.) !! Does the chipset and the hardware manufacturer makes sure to forward the writes to their exact locations in hardwired manner ? For instance, an IDE command might be translated to a PCI request to traverse the PCI bus down to the south bridge than gets translated to something else until it reaches the IDE controller ?
I just want to understand how all this happens and how does the manufacturers always makes sure things are consistent and backward compatible whatever the underlying architecture looks like ?
By the way i am looking for some kind of a book or an article that explains that stuff in details, so a help in this regard will be much appreciated.
However, we all know that there is more than this on the physical system level, I/O devices have different interfaces (IDE, SCSI, LPI ... etc) based on their nature and needs. And they are connected on different types of buses (AT, PCI, PCIe, IDE). CPUs gets connected by high speed, special purpose proprietary buses with the RAM. They connect on standardized high speed buses like PCIe with other high speed devices like Ethernet cards and Graphics cards and all gets linked through some kind of a north bridge that contains the PCI controller hub and other stuff. Low speed and legacy devices (Keyboards, IDE drives, BIOS ... etc) are bridged through a platform controller hub or a south bridge (Intel's terminology).
Now, the thing that i don't clearly see is how does the communication happen in real life with all those details and buses ? I mean how does writing some integer value into some CPU's I/O port by issuing a simple CPU instruction like
movb $PORT, %dh
outb %al, %dh
gets propagated through all the system's hardware components (Buses, Bridges, Controllers ... etc.) and eventually gets written to, let's say, the IDE's disk controller's commands register and thus commands the disk to perform some action (R/W a sector) ?
What puzzles me more is that the same port, the same instructions causes the same things to happen even after years of radical architectural changes (Changes in buses specifications, system architecture ... etc.) !! Does the chipset and the hardware manufacturer makes sure to forward the writes to their exact locations in hardwired manner ? For instance, an IDE command might be translated to a PCI request to traverse the PCI bus down to the south bridge than gets translated to something else until it reaches the IDE controller ?
I just want to understand how all this happens and how does the manufacturers always makes sure things are consistent and backward compatible whatever the underlying architecture looks like ?
By the way i am looking for some kind of a book or an article that explains that stuff in details, so a help in this regard will be much appreciated.