Add default responder to bus
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 6 Jul 2006 18:41:01 +0000 (14:41 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 6 Jul 2006 18:41:01 +0000 (14:41 -0400)
Update configuration for new default responder on bus
Update to devices to handle their own pci config space without pciconfigall
Remove most of pciconfigall, it now is a dumbdevice which gets it's address based on the bus it's supposed to respond for
Remove need for pci config space from platform, add registerPciDevice function to prevent more than one device from having same
bus:dev:func and interrupt
Remove pciconfigspace from pci devices, and py files
Add calcConfigAddr that returns address for config space based on bus/dev/function + offset

configs/test/fs.py:
    Update configuration for new default responder on bus
src/dev/ide_ctrl.cc:
src/dev/ide_ctrl.hh:
src/dev/ns_gige.cc:
src/dev/ns_gige.hh:
src/dev/pcidev.cc:
src/dev/pcidev.hh:
    Update to handle it's own pci config space without pciconfigall
src/dev/io_device.cc:
src/dev/io_device.hh:
    change naming for pio port
    break out recvTiming into two functions to reuse code
src/dev/pciconfigall.cc:
src/dev/pciconfigall.hh:
    removing most of pciconfigall, it now is a dumbdevice which gets it's address based on the bus it's supposed to respond for
src/dev/pcireg.h:
    add a max size for PCI config space (per PCI spec)
src/dev/platform.cc:
src/dev/platform.hh:
    remove need for pci config space from platform, add registerPciDevice function to prevent more than one device from having same
    bus:dev:func and interrupt
src/dev/sinic.cc:
    remove pciconfigspace as it's no longer a needed parameter
src/dev/tsunami.cc:
src/dev/tsunami.hh:
src/dev/tsunami_pchip.cc:
src/dev/tsunami_pchip.hh:
    add calcConfigAddr that returns address for config space based on bus/dev/function + offset (per PCI spec)
src/mem/bus.cc:
src/mem/bus.hh:
src/python/m5/objects/Bus.py:
    add idea of default responder to bus
src/python/m5/objects/Pci.py:
    add config port for pci devices
    add latency, bus and size parameters for pci config all (min is 8MB, max is 256MB see pci spec)

--HG--
extra : convert_revision : 99db43b0a3a077f86611d6eaff6664a3885da7c9

23 files changed:
configs/test/fs.py
src/dev/ide_ctrl.cc
src/dev/ide_ctrl.hh
src/dev/io_device.cc
src/dev/io_device.hh
src/dev/ns_gige.cc
src/dev/ns_gige.hh
src/dev/pciconfigall.cc
src/dev/pciconfigall.hh
src/dev/pcidev.cc
src/dev/pcidev.hh
src/dev/pcireg.h
src/dev/platform.cc
src/dev/platform.hh
src/dev/sinic.cc
src/dev/tsunami.cc
src/dev/tsunami.hh
src/dev/tsunami_pchip.cc
src/dev/tsunami_pchip.hh
src/mem/bus.cc
src/mem/bus.hh
src/python/m5/objects/Bus.py
src/python/m5/objects/Pci.py

index aa530dd55c1343ec3a2e1495a4ec0f757124b411..e0dd38e415424c8b745dac50aa12ef1f225a35f2 100644 (file)
@@ -1,6 +1,6 @@
 import m5
 from m5.objects import *
-import os
+import os,optparse,sys
 from SysPaths import *
 
 parser = optparse.OptionParser(option_list=m5.standardOptions)
@@ -98,7 +98,7 @@ class SpecwebFilesetDisk(IdeDisk):
 class BaseTsunami(Tsunami):
     cchip = TsunamiCChip(pio_addr=0x801a0000000)
     pchip = TsunamiPChip(pio_addr=0x80180000000)
-    pciconfig = PciConfigAll(pio_addr=0x801fe000000)
+    pciconfig = PciConfigAll()
     fake_sm_chip = IsaFake(pio_addr=0x801fc000370)
 
     fake_uart1 = IsaFake(pio_addr=0x801fc0002f8)
@@ -151,16 +151,18 @@ class MyLinuxAlphaSystem(LinuxAlphaSystem):
     tsunami = LinuxTsunami()
     tsunami.cchip.pio = magicbus.port
     tsunami.pchip.pio = magicbus.port
-    tsunami.pciconfig.pio = magicbus.port
+    tsunami.pciconfig.pio = magicbus.default
     tsunami.fake_sm_chip.pio = magicbus.port
     tsunami.ethernet.pio = magicbus.port
     tsunami.ethernet.dma = magicbus.port
+    tsunami.ethernet.config = magicbus.port
     tsunami.fake_uart1.pio = magicbus.port
     tsunami.fake_uart2.pio = magicbus.port
     tsunami.fake_uart3.pio = magicbus.port
     tsunami.fake_uart4.pio = magicbus.port
     tsunami.ide.pio = magicbus.port
     tsunami.ide.dma = magicbus.port
+    tsunami.ide.config = magicbus.port
     tsunami.fake_ppc.pio = magicbus.port
     tsunami.fake_OROM.pio = magicbus.port
     tsunami.fake_pnp_addr.pio = magicbus.port
index 63435e87c166ba008689531439ddcfa7e101bf1b..5ffc02d34959d490343d4979190ba9eaa59cde7b 100644 (file)
@@ -227,177 +227,143 @@ IdeController::setDmaComplete(IdeDisk *disk)
 // Read and write handling
 ////
 
-void
-IdeController::readConfig(int offset, uint8_t *data)
+Tick
+IdeController::readConfig(Packet *pkt)
 {
-    if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::readConfig(offset, data);
-    } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + 1) <= IDE_CTRL_CONF_END) {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
+    if (offset < PCI_DEVICE_SPECIFIC)
+        return  PciDev::readConfig(pkt);
+    assert(offset >= IDE_CTRL_CONF_START && (offset + 1) <= IDE_CTRL_CONF_END);
 
+    pkt->allocate();
+
+    switch (pkt->getSize()) {
+      case sizeof(uint8_t):
         switch (offset) {
           case IDE_CTRL_CONF_DEV_TIMING:
-            *data = config_regs.sidetim;
+            pkt->set<uint8_t>(config_regs.sidetim);
             break;
           case IDE_CTRL_CONF_UDMA_CNTRL:
-            *data = config_regs.udmactl;
+            pkt->set<uint8_t>(config_regs.udmactl);
             break;
           case IDE_CTRL_CONF_PRIM_TIMING+1:
-            *data = htole(config_regs.idetim0) >> 8;
+            pkt->set<uint8_t>(htole(config_regs.idetim0) >> 8);
             break;
           case IDE_CTRL_CONF_SEC_TIMING+1:
-            *data = htole(config_regs.idetim1) >> 8;
+            pkt->set<uint8_t>(htole(config_regs.idetim1) >> 8);
             break;
           case IDE_CTRL_CONF_IDE_CONFIG:
-            *data = htole(config_regs.ideconfig) & 0xFF;
+            pkt->set<uint8_t>(htole(config_regs.ideconfig) & 0xFF);
             break;
           case IDE_CTRL_CONF_IDE_CONFIG+1:
-            *data = htole(config_regs.ideconfig) >> 8;
+            pkt->set<uint8_t>(htole(config_regs.ideconfig) >> 8);
             break;
           default:
             panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
                     offset);
         }
-
-    } else {
-        panic("Read of unimplemented PCI config. register: %x\n", offset);
-    }
-    DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n",
-                offset, (uint32_t)*data);
-}
-
-void
-IdeController::readConfig(int offset, uint16_t *data)
-{
-    if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::readConfig(offset, data);
-    } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + 2) <= IDE_CTRL_CONF_END) {
-
+        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", offset,
+                (uint32_t)pkt->get<uint8_t>());
+        break;
+      case sizeof(uint16_t):
         switch (offset) {
           case IDE_CTRL_CONF_PRIM_TIMING:
-            *data = config_regs.idetim0;
+            pkt->set<uint16_t>(config_regs.idetim0);
             break;
           case IDE_CTRL_CONF_SEC_TIMING:
-            *data = config_regs.idetim1;
+            pkt->set<uint16_t>(config_regs.idetim1);
             break;
           case IDE_CTRL_CONF_UDMA_TIMING:
-            *data = config_regs.udmatim;
+            pkt->set<uint16_t>(config_regs.udmatim);
             break;
           case IDE_CTRL_CONF_IDE_CONFIG:
-            *data = config_regs.ideconfig;
+            pkt->set<uint16_t>(config_regs.ideconfig);
             break;
           default:
             panic("Invalid PCI configuration read for size 2 offset: %#x!\n",
                     offset);
         }
-
-    } else {
-        panic("Read of unimplemented PCI config. register: %x\n", offset);
+        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset,
+                (uint32_t)pkt->get<uint16_t>());
+        break;
+      case sizeof(uint32_t):
+        panic("No 32bit reads implemented for this device.");
+        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset,
+                (uint32_t)pkt->get<uint32_t>());
+        break;
+      default:
+        panic("invalid access size(?) for PCI configspace!\n");
     }
-    DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset, *data);
-}
+    pkt->result = Packet::Success;
+    return configDelay;
 
-void
-IdeController::readConfig(int offset, uint32_t *data)
-{
-    if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::readConfig(offset, data);
-    } else {
-        panic("Read of unimplemented PCI config. register: %x\n", offset);
-    }
-    DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset, *data);
 }
-void
-IdeController::writeConfig(int offset, const uint8_t data)
-{
-    if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::writeConfig(offset, data);
-    } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + 1) <= IDE_CTRL_CONF_END) {
 
-        switch (offset) {
-          case IDE_CTRL_CONF_DEV_TIMING:
-            config_regs.sidetim = data;
-            break;
-          case IDE_CTRL_CONF_UDMA_CNTRL:
-            config_regs.udmactl = data;
-            break;
-          case IDE_CTRL_CONF_IDE_CONFIG:
-            config_regs.ideconfig = (config_regs.ideconfig & 0xFF00) | (data);
-            break;
-          case IDE_CTRL_CONF_IDE_CONFIG+1:
-            config_regs.ideconfig = (config_regs.ideconfig & 0x00FF) | data << 8;
-            break;
-          default:
-            panic("Invalid PCI configuration write for size 1 offset: %#x!\n",
-                    offset);
-        }
 
-    } else {
-        panic("Read of unimplemented PCI config. register: %x\n", offset);
-    }
-    DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
-                offset, (uint32_t)data);
-}
-
-void
-IdeController::writeConfig(int offset, const uint16_t data)
+Tick
+IdeController::writeConfig(Packet *pkt)
 {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::writeConfig(offset, data);
-    } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + 2) <= IDE_CTRL_CONF_END) {
+        PciDev::writeConfig(pkt);
+    } else {
+        assert(offset >= IDE_CTRL_CONF_START && (offset + 1) <= IDE_CTRL_CONF_END);
 
-        switch (offset) {
-          case IDE_CTRL_CONF_PRIM_TIMING:
-            config_regs.idetim0 = data;
-            break;
-          case IDE_CTRL_CONF_SEC_TIMING:
-            config_regs.idetim1 = data;
+        switch (pkt->getSize()) {
+          case sizeof(uint8_t):
+            switch (offset) {
+              case IDE_CTRL_CONF_DEV_TIMING:
+                config_regs.sidetim = pkt->get<uint8_t>();
+                break;
+              case IDE_CTRL_CONF_UDMA_CNTRL:
+                config_regs.udmactl = pkt->get<uint8_t>();
+                break;
+              case IDE_CTRL_CONF_IDE_CONFIG:
+                config_regs.ideconfig = (config_regs.ideconfig & 0xFF00) |
+                    (pkt->get<uint8_t>());
+                break;
+              case IDE_CTRL_CONF_IDE_CONFIG+1:
+                config_regs.ideconfig = (config_regs.ideconfig & 0x00FF) |
+                    pkt->get<uint8_t>() << 8;
+                break;
+              default:
+                panic("Invalid PCI configuration write for size 1 offset: %#x!\n",
+                        offset);
+            }
+            DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
+                    offset, (uint32_t)pkt->get<uint8_t>());
             break;
-          case IDE_CTRL_CONF_UDMA_TIMING:
-            config_regs.udmatim = data;
+          case sizeof(uint16_t):
+            switch (offset) {
+              case IDE_CTRL_CONF_PRIM_TIMING:
+                config_regs.idetim0 = pkt->get<uint16_t>();
+                break;
+              case IDE_CTRL_CONF_SEC_TIMING:
+                config_regs.idetim1 = pkt->get<uint16_t>();
+                break;
+              case IDE_CTRL_CONF_UDMA_TIMING:
+                config_regs.udmatim = pkt->get<uint16_t>();
+                break;
+              case IDE_CTRL_CONF_IDE_CONFIG:
+                config_regs.ideconfig = pkt->get<uint16_t>();
+                break;
+              default:
+                panic("Invalid PCI configuration write for size 2 offset: %#x!\n",
+                        offset);
+            }
+            DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n",
+                    offset, (uint32_t)pkt->get<uint16_t>());
             break;
-          case IDE_CTRL_CONF_IDE_CONFIG:
-            config_regs.ideconfig = data;
+          case sizeof(uint32_t):
+            panic("Write of unimplemented PCI config. register: %x\n", offset);
             break;
           default:
-            panic("Invalid PCI configuration write for size 2 offset: %#x!\n",
-                    offset);
+            panic("invalid access size(?) for PCI configspace!\n");
         }
-
-    } else {
-        panic("Write of unimplemented PCI config. register: %x\n", offset);
     }
-    DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n", offset, data);
-
-    /* Trap command register writes and enable IO/BM as appropriate. */
-    if (offset == PCI_COMMAND) {
-        if (letoh(config.command) & PCI_CMD_IOSE)
-            io_enabled = true;
-        else
-            io_enabled = false;
-
-        if (letoh(config.command) & PCI_CMD_BME)
-            bm_enabled = true;
-        else
-            bm_enabled = false;
-    }
-
-}
-
-void
-IdeController::writeConfig(int offset, const uint32_t data)
-{
-    if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::writeConfig(offset, data);
-    } else {
-        panic("Read of unimplemented PCI config. register: %x\n", offset);
-    }
-
-    DPRINTF(IdeCtrl, "PCI write offset: %#x size: 4 data: %#x\n", offset, data);
 
+    /* Trap command register writes and enable IO/BM as appropriate as well as
+     * BARs. */
     switch(offset) {
       case PCI0_BASE_ADDR0:
         if (BARAddrs[0] != 0)
@@ -423,9 +389,24 @@ IdeController::writeConfig(int offset, const uint32_t data)
         if (BARAddrs[4] != 0)
             bmi_addr = BARAddrs[4];
         break;
+
+      case PCI_COMMAND:
+        if (letoh(config.command) & PCI_CMD_IOSE)
+            io_enabled = true;
+        else
+            io_enabled = false;
+
+        if (letoh(config.command) & PCI_CMD_BME)
+            bm_enabled = true;
+        else
+            bm_enabled = false;
+        break;
     }
+    pkt->result = Packet::Success;
+    return configDelay;
 }
 
+
 Tick
 IdeController::read(Packet *pkt)
 {
@@ -770,7 +751,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
 
     SimObjectParam<System *> system;
     SimObjectParam<Platform *> platform;
-    SimObjectParam<PciConfigAll *> configspace;
     SimObjectParam<PciConfigData *> configdata;
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
@@ -784,7 +764,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
 
     INIT_PARAM(system, "System pointer"),
     INIT_PARAM(platform, "Platform pointer"),
-    INIT_PARAM(configspace, "PCI Configspace"),
     INIT_PARAM(configdata, "PCI Config data"),
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
@@ -800,7 +779,6 @@ CREATE_SIM_OBJECT(IdeController)
     params->name = getInstanceName();
     params->platform = platform;
     params->system = system;
-    params->configSpace = configspace;
     params->configData = configdata;
     params->busNum = pci_bus;
     params->deviceNum = pci_dev;
index 1d30c8b31fd41b62d5b75e7ba7b6363ea03455c0..5842d322efd39c3b5b27ddb77373d6887b4a9b05 100644 (file)
@@ -204,12 +204,8 @@ class IdeController : public PciDev
     IdeController(Params *p);
     ~IdeController();
 
-    virtual void writeConfig(int offset, const uint8_t data);
-    virtual void writeConfig(int offset, const uint16_t data);
-    virtual void writeConfig(int offset, const uint32_t data);
-    virtual void readConfig(int offset, uint8_t *data);
-    virtual void readConfig(int offset, uint16_t *data);
-    virtual void readConfig(int offset, uint32_t *data);
+    virtual Tick writeConfig(Packet *pkt);
+    virtual Tick readConfig(Packet *pkt);
 
     void setDmaComplete(IdeDisk *disk);
 
index e769ef0372fd11a123e2180d13ff7fa939ea055c..cb4850108f8cb9dbf2920e9134ace7cbc84eea0d 100644 (file)
@@ -34,8 +34,8 @@
 #include "sim/builder.hh"
 
 
-PioPort::PioPort(PioDevice *dev, Platform *p)
-    : Port(dev->name() + "-pioport"), device(dev), platform(p)
+PioPort::PioPort(PioDevice *dev, Platform *p, std::string pname)
+    : Port(dev->name() + pname), device(dev), platform(p)
 { }
 
 
@@ -79,19 +79,23 @@ PioPort::SendEvent::process()
     port->transmitList.push_back(packet);
 }
 
+void
+PioPort::resendNacked(Packet *pkt) {
+    pkt->reinitNacked();
+    if (transmitList.size()) {
+         transmitList.push_front(pkt);
+    } else {
+        if (!Port::sendTiming(pkt))
+            transmitList.push_front(pkt);
+    }
+};
 
 
 bool
 PioPort::recvTiming(Packet *pkt)
 {
     if (pkt->result == Packet::Nacked) {
-        pkt->reinitNacked();
-        if (transmitList.size()) {
-             transmitList.push_front(pkt);
-        } else {
-            if (!Port::sendTiming(pkt))
-                transmitList.push_front(pkt);
-        }
+        resendNacked(pkt);
     } else {
         Tick latency = device->recvAtomic(pkt);
         // turn packet around to go back to requester
index a2b61c7f4330aa074a6bb30023fe862355fc4d18..40edf687574db7fa40626dbb210a7188ad01ce94 100644 (file)
@@ -82,6 +82,8 @@ class PioPort : public Port
 
     virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop);
 
+    void resendNacked(Packet *pkt);
+
     /**
      * This class is used to implemented sendTiming() with a delay. When a delay
      * is requested a new event is created. When the event time expires it
@@ -113,7 +115,7 @@ class PioPort : public Port
     virtual void recvRetry();
 
   public:
-    PioPort(PioDevice *dev, Platform *p);
+    PioPort(PioDevice *dev, Platform *p, std::string pname = "-pioport");
 
   friend class PioPort::SendEvent;
 };
index 360fe8c9bed047226062f994546f604a90ae946f..179a2c62ddfe19371cc6b0df9f51f9288c80e01e 100644 (file)
@@ -465,11 +465,12 @@ NSGigE::regStats()
 /**
  * This is to write to the PCI general configuration registers
  */
-void
-NSGigE::writeConfig(int offset, const uint16_t data)
+Tick
+NSGigE::writeConfig(Packet *pkt)
 {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset < PCI_DEVICE_SPECIFIC)
-        PciDev::writeConfig(offset,  data);
+        PciDev::writeConfig(pkt);
     else
         panic("Device specific PCI config space not implemented!\n");
 
@@ -484,6 +485,8 @@ NSGigE::writeConfig(int offset, const uint16_t data)
             ioEnable = false;
         break;
     }
+    pkt->result = Packet::Success;
+    return configDelay;
 }
 
 /**
@@ -508,14 +511,7 @@ NSGigE::read(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return readConfig(pkt);
     } else if (daddr >= MIB_START && daddr <= MIB_END) {
         // don't implement all the MIB's.  hopefully the kernel
         // doesn't actually DEPEND upon their values
@@ -733,14 +729,7 @@ NSGigE::write(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            writeConfig(daddr & 0xff, pkt->get<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            writeConfig(daddr & 0xff, pkt->get<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            writeConfig(daddr & 0xff, pkt->get<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return writeConfig(pkt);
     } else if (daddr > 0x3FC)
         panic("Something is messed up!\n");
 
@@ -2807,7 +2796,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
 
     SimObjectParam<System *> system;
     SimObjectParam<Platform *> platform;
-    SimObjectParam<PciConfigAll *> configspace;
     SimObjectParam<PciConfigData *> configdata;
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
@@ -2841,7 +2829,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
 
     INIT_PARAM(system, "System pointer"),
     INIT_PARAM(platform, "Platform pointer"),
-    INIT_PARAM(configspace, "PCI Configspace"),
     INIT_PARAM(configdata, "PCI Config data"),
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
@@ -2879,7 +2866,6 @@ CREATE_SIM_OBJECT(NSGigE)
     params->name = getInstanceName();
     params->platform = platform;
     params->system = system;
-    params->configSpace = configspace;
     params->configData = configdata;
     params->busNum = pci_bus;
     params->deviceNum = pci_dev;
index 2f47026f3810a6a01f66a52701d055bb98cac581..ea72437770f7c5f903375742170ccb40fcb309f2 100644 (file)
@@ -114,7 +114,6 @@ struct dp_rom {
 
 class NSGigEInt;
 class Packet;
-class PciConfigAll;
 
 /**
  * NS DP83820 Ethernet device model
@@ -376,7 +375,7 @@ class NSGigE : public PciDev
     ~NSGigE();
     const Params *params() const { return (const Params *)_params; }
 
-    virtual void writeConfig(int offset, const uint16_t data);
+    virtual Tick writeConfig(Packet *pkt);
 
     virtual Tick read(Packet *pkt);
     virtual Tick write(Packet *pkt);
index 785774ff4508ae38b19522f86450b7680aa06d3d..68013eab89595fbb3eed198fdf7eefccdbbee6c4 100644 (file)
  * PCI Configspace implementation
  */
 
-#include <deque>
-#include <string>
-#include <vector>
-#include <bitset>
-
 #include "base/trace.hh"
 #include "dev/pciconfigall.hh"
-#include "dev/pcidev.hh"
 #include "dev/pcireg.h"
 #include "dev/platform.hh"
 #include "mem/packet.hh"
 using namespace std;
 
 PciConfigAll::PciConfigAll(Params *p)
-    : BasicPioDevice(p)
+    : PioDevice(p)
 {
-    pioSize = 0xffffff;
-
-    // Set backpointer for pci config. Really the config stuff should be able to
-    // automagically do this
-    p->platform->pciconfig = this;
-
-    // Make all the pointers to devices null
-    for(int x=0; x < MAX_PCI_DEV; x++)
-        for(int y=0; y < MAX_PCI_FUNC; y++)
-            devices[x][y] = NULL;
+    pioAddr = p->platform->calcConfigAddr(params()->bus,0,0);
 }
 
-// If two interrupts share the same line largely bad things will happen.
-// Since we don't track how many times an interrupt was set and correspondingly
-// cleared two devices on the same interrupt line and assert and deassert each
-// others interrupt "line". Interrupts will not work correctly.
-void
-PciConfigAll::startup()
-{
-    bitset<256> intLines;
-    PciDev *tempDev;
-    uint8_t intline;
-
-    for (int x = 0; x < MAX_PCI_DEV; x++) {
-        for (int y = 0; y < MAX_PCI_FUNC; y++) {
-           if (devices[x][y] != NULL) {
-               tempDev = devices[x][y];
-               intline = tempDev->interruptLine();
-               if (intLines.test(intline))
-                   warn("Interrupt line %#X is used multiple times"
-                        "(You probably want to fix this).\n", (uint32_t)intline);
-               else
-                   intLines.set(intline);
-           } // devices != NULL
-        } // PCI_FUNC
-    } // PCI_DEV
-
-}
 
 Tick
 PciConfigAll::read(Packet *pkt)
 {
     assert(pkt->result == Packet::Unknown);
-    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
-
-    Addr daddr = pkt->getAddr() - pioAddr;
-    int device = (daddr >> 11) & 0x1F;
-    int func = (daddr >> 8) & 0x7;
-    int reg = daddr & 0xFF;
 
     pkt->allocate();
 
-    DPRINTF(PciConfigAll, "read  va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr,
+    DPRINTF(PciConfigAll, "read  va=%#x size=%d\n", pkt->getAddr(),
             pkt->getSize());
 
     switch (pkt->getSize()) {
       case sizeof(uint32_t):
-         if (devices[device][func] == NULL)
-             pkt->set<uint32_t>(0xFFFFFFFF);
-         else
-             devices[device][func]->readConfig(reg, pkt->getPtr<uint32_t>());
+         pkt->set<uint32_t>(0xFFFFFFFF);
          break;
       case sizeof(uint16_t):
-         if (devices[device][func] == NULL)
-             pkt->set<uint16_t>(0xFFFF);
-         else
-             devices[device][func]->readConfig(reg, pkt->getPtr<uint16_t>());
+         pkt->set<uint16_t>(0xFFFF);
          break;
       case sizeof(uint8_t):
-         if (devices[device][func] == NULL)
-             pkt->set<uint8_t>(0xFF);
-         else
-             devices[device][func]->readConfig(reg, pkt->getPtr<uint8_t>());
+         pkt->set<uint8_t>(0xFF);
          break;
       default:
         panic("invalid access size(?) for PCI configspace!\n");
     }
     pkt->result = Packet::Success;
-    return pioDelay;
+    return params()->pio_delay;
 }
 
 Tick
 PciConfigAll::write(Packet *pkt)
 {
     assert(pkt->result == Packet::Unknown);
-    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
-    assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) ||
-            pkt->getSize() == sizeof(uint32_t));
-    Addr daddr = pkt->getAddr() - pioAddr;
-
-    int device = (daddr >> 11) & 0x1F;
-    int func = (daddr >> 8) & 0x7;
-    int reg = daddr & 0xFF;
-
-    if (devices[device][func] == NULL)
-        panic("Attempting to write to config space on non-existant device\n");
-
-    DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n",
-            pkt->getAddr(), pkt->getSize(), pkt->get<uint32_t>());
-
-    switch (pkt->getSize()) {
-      case sizeof(uint8_t):
-        devices[device][func]->writeConfig(reg, pkt->get<uint8_t>());
-        break;
-      case sizeof(uint16_t):
-        devices[device][func]->writeConfig(reg, pkt->get<uint16_t>());
-        break;
-      case sizeof(uint32_t):
-        devices[device][func]->writeConfig(reg, pkt->get<uint32_t>());
-        break;
-      default:
-        panic("invalid pci config write size\n");
-    }
-    pkt->result = Packet::Success;
-    return pioDelay;
+    panic("Attempting to write to config space on non-existant device\n");
 }
 
 void
-PciConfigAll::serialize(std::ostream &os)
+PciConfigAll::addressRanges(AddrRangeList &range_list)
 {
-    /*
-     * There is no state associated with this object that requires
-     * serialization.  The only real state are the device pointers
-     * which are all setup by the constructor of the PciDev class
-     */
+    range_list.clear();
+    range_list.push_back(RangeSize(pioAddr, params()->size));
 }
 
-void
-PciConfigAll::unserialize(Checkpoint *cp, const std::string &section)
-{
-    /*
-     * There is no state associated with this object that requires
-     * serialization.  The only real state are the device pointers
-     * which are all setup by the constructor of the PciDev class
-     */
-}
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll)
 
-    Param<Addr> pio_addr;
     Param<Tick> pio_latency;
+    Param<int> bus;
+    Param<Addr> size;
     SimObjectParam<Platform *> platform;
     SimObjectParam<System *> system;
 
@@ -202,8 +106,9 @@ END_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigAll)
 
-    INIT_PARAM(pio_addr, "Device Address"),
     INIT_PARAM(pio_latency, "Programmed IO latency"),
+    INIT_PARAM(bus, "Bus that this object handles config space for"),
+    INIT_PARAM(size, "The size of config space"),
     INIT_PARAM(platform, "platform"),
     INIT_PARAM(system, "system object")
 
@@ -211,11 +116,13 @@ END_INIT_SIM_OBJECT_PARAMS(PciConfigAll)
 
 CREATE_SIM_OBJECT(PciConfigAll)
 {
-    BasicPioDevice::Params *p = new BasicPioDevice::Params;
-    p->pio_addr = pio_addr;
+    PciConfigAll::Params *p = new PciConfigAll::Params;
     p->pio_delay = pio_latency;
     p->platform = platform;
     p->system = system;
+    p->bus = bus;
+    p->size = size;
+
     return new PciConfigAll(p);
 }
 
index e60fd949b65f6cdcc34fc36e3fe188df554d07f8..07eaf811254ae2dde6b62931be9b338cec0a0e79 100644 (file)
 #include "dev/io_device.hh"
 
 
-static const uint32_t MAX_PCI_DEV = 32;
-static const uint32_t MAX_PCI_FUNC = 8;
-
-class PciDev;
-
 /**
  * PCI Config Space
  * All of PCI config space needs to return -1 on Tsunami, except
@@ -54,45 +49,28 @@ class PciDev;
  * space and passes the requests on to TsunamiPCIDev devices as
  * appropriate.
  */
-class PciConfigAll : public BasicPioDevice
+class PciConfigAll : public PioDevice
 {
-  private:
-    /**
-      * Pointers to all the devices that are registered with this
-      * particular config space.
-      */
-    PciDev* devices[MAX_PCI_DEV][MAX_PCI_FUNC];
-
   public:
+    struct Params :  public PioDevice::Params
+    {
+        Tick pio_delay;
+        Addr size;
+        int bus;
+    };
+    const Params *params() const { return (const Params *)_params; }
+
     /**
      * Constructor for PCIConfigAll
      * @param p parameters structure
      */
     PciConfigAll(Params *p);
 
-    /**
-     * Check if a device exists.
-     * @param pcidev PCI device to check
-     * @param pcifunc PCI function to check
-     * @return true if device exists, false otherwise
-     */
-    bool deviceExists(uint32_t pcidev, uint32_t pcifunc)
-                     { return devices[pcidev][pcifunc] != NULL ? true : false; }
-
-    /**
-     * Registers a device with the config space object.
-     * @param pcidev PCI device to register
-     * @param pcifunc PCI function to register
-     * @param device device to register
-     */
-    void registerDevice(uint8_t pcidev, uint8_t pcifunc, PciDev *device)
-                        { devices[pcidev][pcifunc] = device; }
-
     /**
      * Read something in PCI config space. If the device does not exist
      * -1 is returned, if the device does exist its PciDev::ReadConfig (or the
      * virtual function that overrides) it is called.
-     * @param pkt Contains the address of the field to read.
+     * @param pkt Contains information about the read operation
      * @return Amount of time to do the read
      */
     virtual Tick read(Packet *pkt);
@@ -101,31 +79,17 @@ class PciConfigAll : public BasicPioDevice
      * Write to PCI config spcae. If the device does not exit the simulator
      * panics. If it does it is passed on the PciDev::WriteConfig (or the virtual
      * function that overrides it).
-     * @param req Contains the address to write to.
-     * @param data The data to write.
-     * @return The fault condition of the access.
+     * @param pkt Contains information about the write operation
+     * @return Amount of time to do the read
      */
 
     virtual Tick write(Packet *pkt);
 
-    /**
-     * Start up function to check if more than one person is using an interrupt line
-     * and print a warning if such a case exists
-     */
-    virtual void startup();
+    void addressRanges(AddrRangeList &range_list);
 
-    /**
-     * Serialize this object to the given output stream.
-     * @param os The stream to serialize to.
-     */
-    virtual void serialize(std::ostream &os);
+  private:
+    Addr pioAddr;
 
-    /**
-     * Reconstruct the state of this object from a checkpoint.
-     * @param cp The checkpoint use.
-     * @param section The section name of this object
-     */
-    virtual void unserialize(Checkpoint *cp, const std::string &section);
 };
 
 #endif // __PCICONFIGALL_HH__
index f8db2efbcb0712f3c3e3cff5a3470726e4ba18d2..62a7324ad47eb33476f4f152dee653983e7474ba 100644 (file)
 
 using namespace std;
 
-PciDev::PciDev(Params *p)
-    : DmaDevice(p), plat(p->platform), configData(p->configData),
-      pioDelay(p->pio_delay)
-{
-    // copy the config data from the PciConfigData object
-    if (configData) {
-        memcpy(config.data, configData->config.data, sizeof(config.data));
-        memcpy(BARSize, configData->BARSize, sizeof(BARSize));
-        memcpy(BARAddrs, configData->BARAddrs, sizeof(BARAddrs));
-    } else
-        panic("NULL pointer to configuration data");
 
-    // Setup pointer in config space to point to this entry
-    if (p->configSpace->deviceExists(p->deviceNum, p->functionNum))
-        panic("Two PCI devices occuping same dev: %#x func: %#x",
-              p->deviceNum, p->functionNum);
-    else
-        p->configSpace->registerDevice(p->deviceNum, p->functionNum, this);
-}
-
-void
-PciDev::readConfig(int offset, uint8_t *data)
+PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid,
+        int funcid, Platform *p)
+        : PioPort(dev,p,"-pciconf"), device(dev), busId(busid), deviceId(devid),
+        functionId(funcid)
 {
-    if (offset >= PCI_DEVICE_SPECIFIC)
-        panic("Device specific PCI config space not implemented!\n");
+    configAddr = platform->calcConfigAddr(busId, deviceId, functionId);
+}
 
-    *data = config.data[offset];
 
-    DPRINTF(PCIDEV,
-            "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, *data);
+Tick
+PciDev::PciConfigPort::recvAtomic(Packet *pkt)
+{
+    assert(pkt->result == Packet::Unknown);
+    assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr +
+            PCI_CONFIG_SIZE);
+    return device->recvConfig(pkt);
 }
 
 void
-PciDev::addressRanges(AddrRangeList &range_list)
+PciDev::PciConfigPort::recvFunctional(Packet *pkt)
 {
-    int x = 0;
-    range_list.clear();
-    for (x = 0; x < 6; x++)
-        if (BARAddrs[x] != 0)
-            range_list.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+    assert(pkt->result == Packet::Unknown);
+    assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr +
+            PCI_CONFIG_SIZE);
+    device->recvConfig(pkt);
 }
 
 void
-PciDev::readConfig(int offset, uint16_t *data)
+PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
 {
-    if (offset >= PCI_DEVICE_SPECIFIC)
-        panic("Device specific PCI config space not implemented!\n");
+    snoop.clear();
+    resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
+}
 
-    *data = *(uint16_t*)&config.data[offset];
 
-    DPRINTF(PCIDEV,
-            "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, *data);
+bool
+PciDev::PciConfigPort::recvTiming(Packet *pkt)
+{
+    if (pkt->result == Packet::Nacked) {
+        resendNacked(pkt);
+    } else {
+        assert(pkt->result == Packet::Unknown);
+        assert(pkt->getAddr() >= configAddr && pkt->getAddr() < configAddr +
+                PCI_CONFIG_SIZE);
+        Tick latency = device->recvConfig(pkt);
+        // turn packet around to go back to requester
+        pkt->makeTimingResponse();
+        sendTiming(pkt, latency);
+    }
+    return true;
 }
 
-void
-PciDev::readConfig(int offset, uint32_t *data)
+PciDev::PciDev(Params *p)
+    : DmaDevice(p), plat(p->platform), configData(p->configData),
+      pioDelay(p->pio_delay), configDelay(p->config_delay),
+      configPort(NULL)
 {
-    if (offset >= PCI_DEVICE_SPECIFIC)
-        panic("Device specific PCI config space not implemented!\n");
-
-    *data = *(uint32_t*)&config.data[offset];
+    // copy the config data from the PciConfigData object
+    if (configData) {
+        memcpy(config.data, configData->config.data, sizeof(config.data));
+        memcpy(BARSize, configData->BARSize, sizeof(BARSize));
+        memcpy(BARAddrs, configData->BARAddrs, sizeof(BARAddrs));
+    } else
+        panic("NULL pointer to configuration data");
 
-    DPRINTF(PCIDEV,
-            "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, *data);
+    plat->registerPciDevice(0, p->deviceNum, p->functionNum,
+            letoh(configData->config.interruptLine));
 }
 
-
 void
-PciDev::writeConfig(int offset,  const uint8_t data)
+PciDev::init()
 {
+    if (!configPort)
+        panic("pci config port not connected to anything!");
+   configPort->sendStatusChange(Port::RangeChange);
+   PioDevice::init();
+}
+
+Tick
+PciDev::readConfig(Packet *pkt)
+{
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset >= PCI_DEVICE_SPECIFIC)
         panic("Device specific PCI config space not implemented!\n");
 
-    DPRINTF(PCIDEV,
-            "write device: %#x function: %#x reg: %#x size: 1 data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, data);
-
-    switch (offset) {
-      case PCI0_INTERRUPT_LINE:
-        config.interruptLine = data;
-      case PCI_CACHE_LINE_SIZE:
-        config.cacheLineSize = data;
-      case PCI_LATENCY_TIMER:
-        config.latencyTimer = data;
+    pkt->allocate();
+
+    switch (pkt->getSize()) {
+      case sizeof(uint8_t):
+        pkt->set<uint8_t>(config.data[offset]);
+        DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint8_t>());
         break;
-      /* Do nothing for these read-only registers */
-      case PCI0_INTERRUPT_PIN:
-      case PCI0_MINIMUM_GRANT:
-      case PCI0_MAXIMUM_LATENCY:
-      case PCI_CLASS_CODE:
-      case PCI_REVISION_ID:
+      case sizeof(uint16_t):
+        pkt->set<uint16_t>(*(uint16_t*)&config.data[offset]);
+        DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint16_t>());
+        break;
+      case sizeof(uint32_t):
+        pkt->set<uint32_t>(*(uint32_t*)&config.data[offset]);
+        DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint32_t>());
         break;
       default:
-        panic("writing to a read only register");
+        panic("invalid access size(?) for PCI configspace!\n");
     }
+    pkt->result = Packet::Success;
+    return configDelay;
+
 }
 
 void
-PciDev::writeConfig(int offset, const uint16_t data)
+PciDev::addressRanges(AddrRangeList &range_list)
 {
-    if (offset >= PCI_DEVICE_SPECIFIC)
-        panic("Device specific PCI config space not implemented!\n");
-
-    DPRINTF(PCIDEV,
-            "write device: %#x function: %#x reg: %#x size: 2 data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, data);
-
-    switch (offset) {
-      case PCI_COMMAND:
-        config.command = data;
-      case PCI_STATUS:
-        config.status = data;
-      case PCI_CACHE_LINE_SIZE:
-        config.cacheLineSize = data;
-        break;
-      default:
-        panic("writing to a read only register");
-    }
+    int x = 0;
+    range_list.clear();
+    for (x = 0; x < 6; x++)
+        if (BARAddrs[x] != 0)
+            range_list.push_back(RangeSize(BARAddrs[x],BARSize[x]));
 }
 
-
-void
-PciDev::writeConfig(int offset, const uint32_t data)
+Tick
+PciDev::writeConfig(Packet *pkt)
 {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset >= PCI_DEVICE_SPECIFIC)
         panic("Device specific PCI config space not implemented!\n");
 
-    DPRINTF(PCIDEV,
-            "write device: %#x function: %#x reg: %#x size: 4 data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, data);
-
-    switch (offset) {
-      case PCI0_BASE_ADDR0:
-      case PCI0_BASE_ADDR1:
-      case PCI0_BASE_ADDR2:
-      case PCI0_BASE_ADDR3:
-      case PCI0_BASE_ADDR4:
-      case PCI0_BASE_ADDR5:
-
-        uint32_t barnum, bar_mask;
-        Addr base_addr, base_size, space_base;
-
-        barnum = BAR_NUMBER(offset);
-
-        if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) {
-            bar_mask = BAR_IO_MASK;
-            space_base = TSUNAMI_PCI0_IO;
-        } else {
-            bar_mask = BAR_MEM_MASK;
-            space_base = TSUNAMI_PCI0_MEMORY;
+    switch (pkt->getSize()) {
+      case sizeof(uint8_t):
+        switch (offset) {
+          case PCI0_INTERRUPT_LINE:
+            config.interruptLine = pkt->get<uint8_t>();
+          case PCI_CACHE_LINE_SIZE:
+            config.cacheLineSize = pkt->get<uint8_t>();
+          case PCI_LATENCY_TIMER:
+            config.latencyTimer = pkt->get<uint8_t>();
+            break;
+          /* Do nothing for these read-only registers */
+          case PCI0_INTERRUPT_PIN:
+          case PCI0_MINIMUM_GRANT:
+          case PCI0_MAXIMUM_LATENCY:
+          case PCI_CLASS_CODE:
+          case PCI_REVISION_ID:
+            break;
+          default:
+            panic("writing to a read only register");
         }
+        DPRINTF(PCIDEV,
+            "write device: %#x function: %#x register: %#x 1 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint8_t>());
+        break;
+      case sizeof(uint16_t):
+        switch (offset) {
+          case PCI_COMMAND:
+            config.command = pkt->get<uint8_t>();
+          case PCI_STATUS:
+            config.status = pkt->get<uint8_t>();
+          case PCI_CACHE_LINE_SIZE:
+            config.cacheLineSize = pkt->get<uint8_t>();
+            break;
+          default:
+            panic("writing to a read only register");
+        }
+        DPRINTF(PCIDEV,
+            "write device: %#x function: %#x register: %#x 2 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint16_t>());
+        break;
+      case sizeof(uint32_t):
+        switch (offset) {
+          case PCI0_BASE_ADDR0:
+          case PCI0_BASE_ADDR1:
+          case PCI0_BASE_ADDR2:
+          case PCI0_BASE_ADDR3:
+          case PCI0_BASE_ADDR4:
+          case PCI0_BASE_ADDR5:
+
+            uint32_t barnum, bar_mask;
+            Addr base_addr, base_size, space_base;
+
+            barnum = BAR_NUMBER(offset);
+
+            if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) {
+                bar_mask = BAR_IO_MASK;
+                space_base = TSUNAMI_PCI0_IO;
+            } else {
+                bar_mask = BAR_MEM_MASK;
+                space_base = TSUNAMI_PCI0_MEMORY;
+            }
 
-        // Writing 0xffffffff to a BAR tells the card to set the
-        // value of the bar to size of memory it needs
-        if (letoh(data) == 0xffffffff) {
-            // This is I/O Space, bottom two bits are read only
-
-            config.baseAddr[barnum] = letoh(
-                    (~(BARSize[barnum] - 1) & ~bar_mask) |
+            // Writing 0xffffffff to a BAR tells the card to set the
+            // value of the bar to size of memory it needs
+            if (letoh(pkt->get<uint32_t>()) == 0xffffffff) {
+                // This is I/O Space, bottom two bits are read only
+
+                config.baseAddr[barnum] = letoh(
+                        (~(BARSize[barnum] - 1) & ~bar_mask) |
+                        (letoh(config.baseAddr[barnum]) & bar_mask));
+            } else {
+                config.baseAddr[barnum] = letoh(
+                    (letoh(pkt->get<uint32_t>()) & ~bar_mask) |
                     (letoh(config.baseAddr[barnum]) & bar_mask));
-        } else {
-            config.baseAddr[barnum] = letoh(
-                (letoh(data) & ~bar_mask) |
-                (letoh(config.baseAddr[barnum]) & bar_mask));
 
-            if (letoh(config.baseAddr[barnum]) & ~bar_mask) {
-                base_addr = (letoh(data) & ~bar_mask) + space_base;
-                base_size = BARSize[barnum];
-                BARAddrs[barnum] = base_addr;
+                if (letoh(config.baseAddr[barnum]) & ~bar_mask) {
+                    base_addr = (letoh(pkt->get<uint32_t>()) & ~bar_mask) + space_base;
+                    base_size = BARSize[barnum];
+                    BARAddrs[barnum] = base_addr;
 
-            pioPort->sendStatusChange(Port::RangeChange);
+                pioPort->sendStatusChange(Port::RangeChange);
+                }
             }
+            break;
+
+          case PCI0_ROM_BASE_ADDR:
+            if (letoh(pkt->get<uint32_t>()) == 0xfffffffe)
+                config.expansionROM = htole((uint32_t)0xffffffff);
+            else
+                config.expansionROM = pkt->get<uint32_t>();
+            break;
+
+          case PCI_COMMAND:
+            // This could also clear some of the error bits in the Status
+            // register. However they should never get set, so lets ignore
+            // it for now
+            config.command = pkt->get<uint32_t>();
+            break;
+
+          default:
+            DPRINTF(PCIDEV, "Writing to a read only register");
         }
+        DPRINTF(PCIDEV,
+            "write device: %#x function: %#x register: %#x 4 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset,
+            (uint32_t)pkt->get<uint32_t>());
         break;
-
-      case PCI0_ROM_BASE_ADDR:
-        if (letoh(data) == 0xfffffffe)
-            config.expansionROM = htole((uint32_t)0xffffffff);
-        else
-            config.expansionROM = data;
-        break;
-
-      case PCI_COMMAND:
-        // This could also clear some of the error bits in the Status
-        // register. However they should never get set, so lets ignore
-        // it for now
-        config.command = data;
-        break;
-
       default:
-        DPRINTF(PCIDEV, "Writing to a read only register");
+        panic("invalid access size(?) for PCI configspace!\n");
     }
+    pkt->result = Packet::Success;
+    return configDelay;
+
 }
 
 void
index 92786427b363d67f0192230be3ada16fdc61dd39..20ab9364a8879cd31c213a2b55e61cc5952a9602 100644 (file)
@@ -47,8 +47,6 @@
 #define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
 #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
 
-class PciConfigAll;
-
 
 /**
  * This class encapulates the first 64 bytes of a singles PCI
@@ -78,24 +76,41 @@ class PciConfigData : public SimObject
     Addr BARAddrs[6];
 };
 
+
 /**
  * PCI device, base implemnation is only config space.
- * Each device is connected to a PCIConfigSpace device
- * which returns -1 for everything but the pcidevs that
- * register with it. This object registers with the PCIConfig space
- * object.
  */
 class PciDev : public DmaDevice
 {
-  public:
-    struct Params : public ::PioDevice::Params
+    class PciConfigPort : public PioPort
     {
-        /**
-         * A pointer to the configspace all object that calls us when
-         * a read comes to this particular device/function.
-         */
-        PciConfigAll *configSpace;
+      protected:
+        PciDev *device;
+
+        virtual bool recvTiming(Packet *pkt);
+
+        virtual Tick recvAtomic(Packet *pkt);
+
+        virtual void recvFunctional(Packet *pkt) ;
+
+        virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop);
+
+        int busId;
+        int deviceId;
+        int functionId;
+
+        Addr configAddr;
+
+      public:
+        PciConfigPort(PciDev *dev, int busid, int devid, int funcid,
+                Platform *p);
 
+      friend class PioPort::SendEvent;
+    };
+
+  public:
+    struct Params : public PioDevice::Params
+    {
         /**
          * A pointer to the object that contains the first 64 bytes of
          * config space
@@ -113,6 +128,9 @@ class PciDev : public DmaDevice
 
         /** The latency for pio accesses. */
         Tick pio_delay;
+
+        /** The latency for a config access. */
+        Tick config_delay;
     };
 
   public:
@@ -164,6 +182,25 @@ class PciDev : public DmaDevice
     Platform *plat;
     PciConfigData *configData;
     Tick pioDelay;
+    Tick configDelay;
+    PciConfigPort *configPort;
+
+    /**
+     * Write to the PCI config space data that is stored locally. This may be
+     * overridden by the device but at some point it will eventually call this
+     * for normal operations that it does not need to override.
+     * @param pkt packet containing the write the offset into config space
+     */
+    virtual Tick writeConfig(Packet *pkt);
+
+
+    /**
+     * Read from the PCI config space data that is stored locally. This may be
+     * overridden by the device but at some point it will eventually call this
+     * for normal operations that it does not need to override.
+     * @param pkt packet containing the write the offset into config space
+     */
+    virtual Tick readConfig(Packet *pkt);
 
   public:
     Addr pciToDma(Addr pciAddr) const
@@ -171,21 +208,25 @@ class PciDev : public DmaDevice
 
     void
     intrPost()
-    { plat->postPciInt(configData->config.interruptLine); }
+    { plat->postPciInt(letoh(configData->config.interruptLine)); }
 
     void
     intrClear()
-    { plat->clearPciInt(configData->config.interruptLine); }
+    { plat->clearPciInt(letoh(configData->config.interruptLine)); }
 
     uint8_t
     interruptLine()
-    { return configData->config.interruptLine; }
+    { return letoh(configData->config.interruptLine); }
 
     /** return the address ranges that this device responds to.
      * @params range_list range list to populate with ranges
      */
     void addressRanges(AddrRangeList &range_list);
 
+    /** Do a PCI Configspace memory access. */
+    Tick recvConfig(Packet *pkt)
+    { return pkt->isRead() ? readConfig(pkt) : writeConfig(pkt); }
+
     /**
      * Constructor for PCI Dev. This function copies data from the
      * config file object PCIConfigData and registers the device with
@@ -193,30 +234,7 @@ class PciDev : public DmaDevice
      */
     PciDev(Params *params);
 
-    /**
-     * Write to the PCI config space data that is stored locally. This may be
-     * overridden by the device but at some point it will eventually call this
-     * for normal operations that it does not need to override.
-     * @param offset the offset into config space
-     * @param size the size of the write
-     * @param data the data to write
-     */
-    virtual void writeConfig(int offset, const uint8_t data);
-    virtual void writeConfig(int offset, const uint16_t data);
-    virtual void writeConfig(int offset, const uint32_t data);
-
-
-    /**
-     * Read from the PCI config space data that is stored locally. This may be
-     * overridden by the device but at some point it will eventually call this
-     * for normal operations that it does not need to override.
-     * @param offset the offset into config space
-     * @param size the size of the read
-     * @param data pointer to the location where the read value should be stored
-     */
-    virtual void readConfig(int offset, uint8_t *data);
-    virtual void readConfig(int offset, uint16_t *data);
-    virtual void readConfig(int offset, uint32_t *data);
+    virtual void init();
 
     /**
      * Serialize this object to the given output stream.
@@ -230,5 +248,19 @@ class PciDev : public DmaDevice
      * @param section The section name of this object
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+    virtual Port *getPort(const std::string &if_name, int idx = -1)
+    {
+        if (if_name == "config") {
+            if (configPort != NULL)
+                panic("pciconfig port already connected to.");
+            configPort = new PciConfigPort(this, params()->busNum,
+                    params()->deviceNum, params()->functionNum,
+                    params()->platform);
+            return configPort;
+        }
+        return DmaDevice::getPort(if_name, idx);
+    }
+
 };
 #endif // __DEV_PCIDEV_HH__
index 0aa4ba8ef1c5dba8d6af4505f13dc54c183d5218..a48abd4fa507892766619d0e1c92f52b41795a61 100644 (file)
@@ -142,6 +142,7 @@ union PCIConfig {
 
 // Device specific offsets
 #define PCI_DEVICE_SPECIFIC            0x40    // 192 bytes
+#define PCI_CONFIG_SIZE         0xFF
 
 // Some Vendor IDs
 #define PCI_VENDOR_DEC                 0x1011
index ed021e3b673e414bd1bb04e5e1648b56a56c5f29..8546b7805f58b89824ca2ab950cd41fc2e61a2a6 100644 (file)
@@ -63,5 +63,21 @@ Platform::pciToDma(Addr pciAddr) const
    panic("No PCI dma support in platform.");
 }
 
+void
+Platform::registerPciDevice(uint8_t bus, uint8_t dev, uint8_t func, uint8_t intr)
+{
+    uint32_t bdf = bus << 16 | dev << 8 | func << 0;
+    if (pciDevices.find(bdf) != pciDevices.end())
+        fatal("Two PCI devices have same bus:device:function\n");
+
+    if (intLines.test(intr))
+        fatal("Two PCI devices have same interrupt line: %d\n", intr);
+
+    pciDevices.insert(bdf);
+
+    intLines.set(intr);
+}
+
+
 DEFINE_SIM_OBJECT_CLASS_NAME("Platform", Platform)
 
index 0e6f4ba4a86d5bcf794a97db20f50fdd67327759..1940dcad61284dbb79d7190ab4f44668515687a6 100644 (file)
@@ -37,6 +37,9 @@
 #ifndef __DEV_PLATFORM_HH__
 #define __DEV_PLATFORM_HH__
 
+#include <bitset>
+#include <set>
+
 #include "sim/sim_object.hh"
 #include "arch/isa_traits.hh"
 
@@ -52,9 +55,6 @@ class Platform : public SimObject
     /** Pointer to the interrupt controller */
     IntrControl *intrctrl;
 
-    /** Pointer to the PCI configuration space */
-    PciConfigAll *pciconfig;
-
     /** Pointer to the UART, set by the uart */
     Uart *uart;
 
@@ -64,13 +64,20 @@ class Platform : public SimObject
   public:
     Platform(const std::string &name, IntrControl *intctrl);
     virtual ~Platform();
-    virtual void init() { if (pciconfig == NULL) panic("PCI Config not set"); }
     virtual void postConsoleInt() = 0;
     virtual void clearConsoleInt() = 0;
     virtual Tick intrFrequency() = 0;
     virtual void postPciInt(int line);
     virtual void clearPciInt(int line);
     virtual Addr pciToDma(Addr pciAddr) const;
+    virtual Addr calcConfigAddr(int bus, int dev, int func) = 0;
+    virtual void registerPciDevice(uint8_t bus, uint8_t dev, uint8_t func,
+            uint8_t intr);
+
+  private:
+    std::bitset<256> intLines;
+    std::set<uint32_t> pciDevices;
+
 };
 
 #endif // __DEV_PLATFORM_HH__
index a0223733bb9ab61d5c3e2d211c4df5001ad41cd1..dddda1f1cbc7c398b4dd933bde7dce289d808868 100644 (file)
@@ -37,7 +37,6 @@
 #include "cpu/intr_control.hh"
 #include "dev/etherlink.hh"
 #include "dev/sinic.hh"
-#include "dev/pciconfigall.hh"
 #include "mem/packet.hh"
 #include "sim/builder.hh"
 #include "sim/debug.hh"
@@ -1623,7 +1622,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
 
     SimObjectParam<System *> system;
     SimObjectParam<Platform *> platform;
-    SimObjectParam<PciConfigAll *> configspace;
     SimObjectParam<PciConfigData *> configdata;
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
@@ -1666,7 +1664,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
 
     INIT_PARAM(system, "System pointer"),
     INIT_PARAM(platform, "Platform pointer"),
-    INIT_PARAM(configspace, "PCI Configspace"),
     INIT_PARAM(configdata, "PCI Config data"),
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
@@ -1711,7 +1708,6 @@ CREATE_SIM_OBJECT(Device)
     params->name = getInstanceName();
     params->platform = platform;
     params->system = system;
-    params->configSpace = configspace;
     params->configData = configdata;
     params->busNum = pci_bus;
     params->deviceNum = pci_dev;
index c9e15581d6a4bb484bd4b6cce1bd488ffe5ad004..8e740a72fcb74f51fb4cfb4e6b8a15f0b9eaf976 100644 (file)
@@ -95,6 +95,13 @@ Tsunami::pciToDma(Addr pciAddr) const
     return pchip->translatePciToDma(pciAddr);
 }
 
+
+Addr
+Tsunami::calcConfigAddr(int bus, int dev, int func)
+{
+   return pchip->calcConfigAddr(bus, dev, func);
+}
+
 void
 Tsunami::serialize(std::ostream &os)
 {
index 13fc4417c0fc52ad9a1d36773ab4b34bd47b95e5..8bb66e9143584bc45dcddb3e13e37062f394f31e 100644 (file)
@@ -113,8 +113,14 @@ class Tsunami : public Platform
      */
     virtual void clearPciInt(int line);
 
+
     virtual Addr pciToDma(Addr pciAddr) const;
 
+    /**
+     * Calculate the configuration address given a bus/dev/func.
+     */
+    virtual Addr calcConfigAddr(int bus, int dev, int func);
+
     /**
      * Serialize this object to the given output stream.
      * @param os The stream to serialize to.
index a376b908dd8bf5cb8052cbc41d1849ae1d312dc0..8a542b9b0709d6ec75e67572efb74f9aad38892a 100644 (file)
@@ -302,6 +302,17 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
     // if no match was found, then return the original address
     return busAddr;
 }
+Addr
+TsunamiPChip::calcConfigAddr(int bus, int dev, int func)
+{
+    assert(func < 8);
+    assert(dev < 32);
+    assert(bus == 0);
+
+    return TsunamiPciBus0Config | (func << 8) | (dev << 11);
+}
+
+
 
 void
 TsunamiPChip::serialize(std::ostream &os)
index 9f80f7d6888efc70ba4d5be79f3c2c3bbb9259b9..b9e900526545d59511fb114ddd4369b54a8c96c2 100644 (file)
@@ -45,6 +45,9 @@
 class TsunamiPChip : public BasicPioDevice
 {
   protected:
+
+    static const Addr TsunamiPciBus0Config = 0x801fe000000;
+
     /** Pchip control register */
     uint64_t pctl;
 
@@ -80,6 +83,8 @@ class TsunamiPChip : public BasicPioDevice
      */
     Addr translatePciToDma(Addr busAddr);
 
+    Addr calcConfigAddr(int bus, int dev, int func);
+
     virtual Tick read(Packet *pkt);
     virtual Tick write(Packet *pkt);
 
index 19a3dc9e407db6b89459b8a49ce0002bb53c9da6..31271106bb755892b36032df2753e612a34451ef 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 
+#include "base/misc.hh"
 #include "base/trace.hh"
 #include "mem/bus.hh"
 #include "sim/builder.hh"
 Port *
 Bus::getPort(const std::string &if_name, int idx)
 {
+    if (if_name == "default")
+        if (defaultPort == NULL) {
+            defaultPort = new BusPort(csprintf("%s-default",name()), this,
+                    defaultId);
+            return defaultPort;
+        } else
+            fatal("Default port already set\n");
+
     // if_name ignored?  forced to be empty?
     int id = interfaces.size();
     BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
@@ -47,11 +56,12 @@ Bus::getPort(const std::string &if_name, int idx)
     return bp;
 }
 
-/** Get the ranges of anyone that we are connected to. */
+/** Get the ranges of anyone other buses that we are connected to. */
 void
 Bus::init()
 {
     std::vector<Port*>::iterator intIter;
+
     for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
         (*intIter)->sendStatusChange(Port::RangeChange);
 }
@@ -110,6 +120,7 @@ Bus::findPort(Addr addr, int id)
     int dest_id = -1;
     int i = 0;
     bool found = false;
+    AddrRangeIter iter;
 
     while (i < portList.size() && !found)
     {
@@ -120,8 +131,18 @@ Bus::findPort(Addr addr, int id)
         }
         i++;
     }
-    if (dest_id == -1)
+
+    // Check if this matches the default range
+    if (dest_id == -1) {
+        for (iter = defaultRange.begin(); iter != defaultRange.end(); iter++) {
+            if (*iter == addr) {
+                DPRINTF(Bus, "  found addr 0x%llx on default\n", addr);
+                return defaultPort;
+            }
+        }
         panic("Unable to find destination for addr: %llx", addr);
+    }
+
 
     // we shouldn't be sending this back to where it came from
     assert(dest_id != id);
@@ -155,39 +176,52 @@ Bus::recvFunctional(Packet *pkt)
 void
 Bus::recvStatusChange(Port::Status status, int id)
 {
+    AddrRangeList ranges;
+    AddrRangeList snoops;
+    int x;
+    AddrRangeIter iter;
+
     assert(status == Port::RangeChange &&
            "The other statuses need to be implemented.");
 
     DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
 
-    assert(id < interfaces.size() && id >= 0);
-    int x;
-    Port *port = interfaces[id];
-    AddrRangeList ranges;
-    AddrRangeList snoops;
-    AddrRangeIter iter;
-    std::vector<DevMap>::iterator portIter;
+    if (id == defaultId) {
+        defaultRange.clear();
+        defaultPort->getPeerAddressRanges(ranges, snoops);
+        assert(snoops.size() == 0);
+        for(iter = ranges.begin(); iter != ranges.end(); iter++) {
+            defaultRange.push_back(*iter);
+            DPRINTF(BusAddrRanges, "Adding range %llx - %llx for default\n",
+                    iter->start, iter->end);
+        }
+    } else {
 
-    // Clean out any previously existent ids
-    for (portIter = portList.begin(); portIter != portList.end(); ) {
-        if (portIter->portId == id)
-            portIter = portList.erase(portIter);
-        else
-            portIter++;
-    }
+        assert((id < interfaces.size() && id >= 0) || id == -1);
+        Port *port = interfaces[id];
+        std::vector<DevMap>::iterator portIter;
+
+        // Clean out any previously existent ids
+        for (portIter = portList.begin(); portIter != portList.end(); ) {
+            if (portIter->portId == id)
+                portIter = portList.erase(portIter);
+            else
+                portIter++;
+        }
 
-    port->getPeerAddressRanges(ranges, snoops);
+        port->getPeerAddressRanges(ranges, snoops);
 
-    // not dealing with snooping yet either
-    assert(snoops.size() == 0);
-    for(iter = ranges.begin(); iter != ranges.end(); iter++) {
-        DevMap dm;
-        dm.portId = id;
-        dm.range = *iter;
+        // not dealing with snooping yet either
+        assert(snoops.size() == 0);
+        for(iter = ranges.begin(); iter != ranges.end(); iter++) {
+            DevMap dm;
+            dm.portId = id;
+            dm.range = *iter;
 
-        DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n",
-                dm.range.start, dm.range.end, id);
-        portList.push_back(dm);
+            DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n",
+                    dm.range.start, dm.range.end, id);
+            portList.push_back(dm);
+        }
     }
     DPRINTF(MMU, "port list has %d entries\n", portList.size());
 
@@ -196,19 +230,47 @@ Bus::recvStatusChange(Port::Status status, int id)
     for (x = 0; x < interfaces.size(); x++)
         if (x != id)
             interfaces[x]->sendStatusChange(Port::RangeChange);
+
+    if (id != defaultId && defaultPort)
+        defaultPort->sendStatusChange(Port::RangeChange);
 }
 
 void
 Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
 {
     std::vector<DevMap>::iterator portIter;
+    AddrRangeIter dflt_iter;
+    bool subset;
 
     resp.clear();
     snoop.clear();
 
     DPRINTF(BusAddrRanges, "received address range request, returning:\n");
+
+    for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end();
+            dflt_iter++) {
+        resp.push_back(*dflt_iter);
+        DPRINTF(BusAddrRanges, "  -- %#llX : %#llX\n",dflt_iter->start,
+                dflt_iter->end);
+    }
     for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
-        if (portIter->portId != id) {
+        subset = false;
+        for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end();
+                dflt_iter++) {
+            if ((portIter->range.start < dflt_iter->start &&
+                portIter->range.end >= dflt_iter->start) ||
+               (portIter->range.start < dflt_iter->end &&
+                portIter->range.end >= dflt_iter->end))
+                fatal("Devices can not set ranges that itersect the default set\
+                        but are not a subset of the default set.\n");
+            if (portIter->range.start >= dflt_iter->start &&
+                portIter->range.end <= dflt_iter->end) {
+                subset = true;
+                DPRINTF(BusAddrRanges, "  -- %#llX : %#llX is a SUBSET\n",
+                    portIter->range.start, portIter->range.end);
+            }
+        }
+        if (portIter->portId != id && !subset) {
             resp.push_back(portIter->range);
             DPRINTF(BusAddrRanges, "  -- %#llX : %#llX\n",
                     portIter->range.start, portIter->range.end);
index 9c7054b9494f341bd4013ac52705d4a1d250f9c1..3a2896886025dd28fd2e42fa9444b5f6d2c7c378 100644 (file)
@@ -51,19 +51,22 @@ class Bus : public MemObject
     /** a globally unique id for this bus. */
     int busId;
 
+    static const int defaultId = -1;
+
     struct DevMap {
         int portId;
         Range<Addr> range;
     };
     std::vector<DevMap> portList;
+    AddrRangeList defaultRange;
 
 
     /** Function called by the port when the bus is recieving a Timing
-        transaction.*/
+      transaction.*/
     bool recvTiming(Packet *pkt);
 
     /** Function called by the port when the bus is recieving a Atomic
-        transaction.*/
+      transaction.*/
     Tick recvAtomic(Packet *pkt);
 
     /** Function called by the port when the bus is recieving a Functional
@@ -159,6 +162,9 @@ class Bus : public MemObject
      * original send failed for whatever reason.*/
     std::list<Port*> retryList;
 
+    /** Port that handles requests that don't match any of the interfaces.*/
+    Port *defaultPort;
+
   public:
 
     /** A function used to return the port associated with this bus object. */
@@ -167,7 +173,7 @@ class Bus : public MemObject
     virtual void init();
 
     Bus(const std::string &n, int bus_id)
-        : MemObject(n), busId(bus_id)  {}
+        : MemObject(n), busId(bus_id), defaultPort(NULL)  {}
 
 };
 
index 019e15034627e5145370d32d4bf01e2e84648ffe..e0278e6c3315a2abd79d6a28f7638a04494eb0b5 100644 (file)
@@ -4,4 +4,5 @@ from MemObject import MemObject
 class Bus(MemObject):
     type = 'Bus'
     port = VectorPort("vector port for connecting devices")
+    default = Port("Default port for requests that aren't handeled by a device.")
     bus_id = Param.Int(0, "blah")
index 9e1e91b1306cf4e47789fcce967c69c16701d3f5..29014bb37053a2032790e8f885229636b5e29699 100644 (file)
@@ -1,5 +1,5 @@
 from m5.config import *
-from Device import BasicPioDevice, DmaDevice
+from Device import BasicPioDevice, DmaDevice, PioDevice
 
 class PciConfigData(SimObject):
     type = 'PciConfigData'
@@ -38,18 +38,22 @@ class PciConfigData(SimObject):
     MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
     MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
 
-class PciConfigAll(BasicPioDevice):
+class PciConfigAll(PioDevice):
     type = 'PciConfigAll'
+    pio_latency = Param.Tick(1, "Programmed IO latency in simticks")
+    bus = Param.UInt8(0x00, "PCI bus to act as config space for")
+    size = Param.MemorySize32('16MB', "Size of config space")
+
 
 class PciDevice(DmaDevice):
     type = 'PciDevice'
     abstract = True
+    config = Port("PCI configuration space port")
     pci_bus = Param.Int("PCI bus")
     pci_dev = Param.Int("PCI device number")
     pci_func = Param.Int("PCI function code")
     pio_latency = Param.Tick(1, "Programmed IO latency in simticks")
     configdata = Param.PciConfigData(Parent.any, "PCI Config data")
-    configspace = Param.PciConfigAll(Parent.any, "PCI Configspace")
 
 class PciFake(PciDevice):
     type = 'PciFake'