From 5e767970d8e11ea00d52e7561a438ec054e9ffff Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2020 02:50:18 -0700 Subject: [PATCH] x86: Change how IO port devices are structured in the PC platform. Before, for historical reasons, the PCI host device was the default responder on the IO bus, meaning that when there was any type of transaction which didn't have a device to go to, it would end up looking like a PCI config transaction. It's very unlikely that this is what it actually was, and what would happen would be arbitrary and probably not helpful. Also, there was no device in place to respond to accesses in x86's IO port address space. On a real system, these accesses just return junk and are otherwise legal. On systems where there would be physical bus wires they would probably return whatever the last data on the bus was. This would have been helpful when the platform was first being set up because it would make it obvious when the OS tried to access a device that wasn't implemented, but there were a few cases where it would purposefully fiddle with ports with nothing on them. These had one off backing devices in the config which would handle the accesses harmlessly, but if the OS changed and tried to access other ports, the configs would need to be updated. Now, the PCI host is just another device on the bus. It claims all of the PCI config space addresses, so any config access, even ones which don't go with a device, will go to it, and it can respond with all 1s like it's supposed to. In it's place, the default responder is now a bus. On that bus is a device which responds to the entire IO port address range with 0s. The default on *that* bus is a device which will mark any accesses as bad. With this setup, accesses which don't go to a device, including a device on the IO port address space, will go to the IO bus's default port. There, if the access was an IO access, it will go to the device which replies successfully with all 0s. If not, it's marked as an error. The device which backs the entire IO address space doesn't conflict with the actual IO devices, since the access will only go towards it if it's otherwise unclaimed, and the devices on the default bus don't participate in routing on the higher level IO bus. Change-Id: Ie02ad7165dfad3ee6f4a762e2f01f7f1b8225168 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35515 Reviewed-by: Matthew Poremba Maintainer: Gabe Black Tested-by: kokoro --- src/dev/x86/Pc.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/dev/x86/Pc.py b/src/dev/x86/Pc.py index a0a98253d..0ed264854 100644 --- a/src/dev/x86/Pc.py +++ b/src/dev/x86/Pc.py @@ -27,12 +27,13 @@ from m5.params import * from m5.proxy import * -from m5.objects.Device import IsaFake +from m5.objects.Device import IsaFake, BadAddr from m5.objects.Platform import Platform from m5.objects.SouthBridge import SouthBridge from m5.objects.Terminal import Terminal from m5.objects.Uart import Uart8250 from m5.objects.PciHost import GenericPciHost +from m5.objects.XBar import IOXBar def x86IOAddress(port): IO_address_space_base = 0x8000000000000000 @@ -52,14 +53,6 @@ class Pc(Platform): south_bridge = SouthBridge() pci_host = PcPciHost() - # "Non-existant" ports used for timing purposes by the linux kernel - i_dont_exist1 = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1) - i_dont_exist2 = IsaFake(pio_addr=x86IOAddress(0xed), pio_size=1) - - # Ports behind the pci config and data regsiters. These don't do anything, - # but the linux kernel fiddles with them anway. - behind_pci = IsaFake(pio_addr=x86IOAddress(0xcf8), pio_size=8) - # Serial port and terminal com_1 = Uart8250() com_1.pio_addr = x86IOAddress(0x3f8) @@ -73,14 +66,24 @@ class Pc(Platform): # A device to catch accesses to the non-existant floppy controller. fake_floppy = IsaFake(pio_addr=x86IOAddress(0x3f2), pio_size=2) + # A bus for accesses not claimed by a specific device. + default_bus = IOXBar() + + # A device to handle accesses to unclaimed IO ports. + empty_isa = IsaFake(pio_addr=x86IOAddress(0), pio_size='64kB', + ret_data8=0, ret_data16=0, ret_data32=0, ret_data64=0, + pio=default_bus.mem_side_ports) + + # A device to handle any other type of unclaimed access. + bad_addr = BadAddr(pio=default_bus.default) + def attachIO(self, bus, dma_ports = []): self.south_bridge.attachIO(bus, dma_ports) - self.i_dont_exist1.pio = bus.mem_side_ports - self.i_dont_exist2.pio = bus.mem_side_ports - self.behind_pci.pio = bus.mem_side_ports self.com_1.pio = bus.mem_side_ports self.fake_com_2.pio = bus.mem_side_ports self.fake_com_3.pio = bus.mem_side_ports self.fake_com_4.pio = bus.mem_side_ports self.fake_floppy.pio = bus.mem_side_ports - self.pci_host.pio = bus.default + self.pci_host.pio = bus.mem_side_ports + + self.default_bus.cpu_side_ports = bus.default -- 2.30.2