Files
gem5/src/dev/x86/Pc.py
Gabe Black 5e767970d8 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 <matthew.poremba@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
2020-10-10 00:54:23 +00:00

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