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 <matthew.poremba@amd.com> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
90 lines
3.7 KiB
Python
90 lines
3.7 KiB
Python
# Copyright (c) 2008 The Regents of The University of Michigan
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met: redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer;
|
|
# redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution;
|
|
# neither the name of the copyright holders nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
from m5.params import *
|
|
from m5.proxy import *
|
|
|
|
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
|
|
return IO_address_space_base + port;
|
|
|
|
class PcPciHost(GenericPciHost):
|
|
conf_base = 0xC000000000000000
|
|
conf_size = "16MB"
|
|
|
|
pci_pio_base = 0x8000000000000000
|
|
|
|
class Pc(Platform):
|
|
type = 'Pc'
|
|
cxx_header = "dev/x86/pc.hh"
|
|
system = Param.System(Parent.any, "system")
|
|
|
|
south_bridge = SouthBridge()
|
|
pci_host = PcPciHost()
|
|
|
|
# Serial port and terminal
|
|
com_1 = Uart8250()
|
|
com_1.pio_addr = x86IOAddress(0x3f8)
|
|
com_1.device = Terminal()
|
|
|
|
# Devices to catch access to non-existant serial ports.
|
|
fake_com_2 = IsaFake(pio_addr=x86IOAddress(0x2f8), pio_size=8)
|
|
fake_com_3 = IsaFake(pio_addr=x86IOAddress(0x3e8), pio_size=8)
|
|
fake_com_4 = IsaFake(pio_addr=x86IOAddress(0x2e8), pio_size=8)
|
|
|
|
# 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.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.mem_side_ports
|
|
|
|
self.default_bus.cpu_side_ports = bus.default
|