make ide disk work for newmem
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 20 Apr 2006 21:14:30 +0000 (17:14 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 20 Apr 2006 21:14:30 +0000 (17:14 -0400)
SConscript:
    compile ide devices
base/chunk_generator.hh:
    add another parameter to the chuck generator called complete() which
    returns the number of bytes transfered so far. Very useful for
    adding to a pointer.
configs/test/fs.py:
    Add ide disk to fs test configuration
dev/ide_ctrl.cc:
dev/ide_ctrl.hh:
dev/ide_disk.cc:
dev/ide_disk.hh:
dev/io_device.cc:
dev/io_device.hh:
dev/pciconfigall.cc:
dev/pciconfigall.hh:
dev/pcidev.cc:
dev/pcidev.hh:
    update for new memory system
mem/bus.cc:
    support devices that return multiple ranges
    remove old ranges before using new info
mem/packet.hh:
    make senderstate void* per steve's request that we use every
    construct possible in C++
mem/physical.cc:
    have memory stamp the packet with the time.
mem/physical.hh:
    actually set the memory latency variable
python/m5/objects/Device.py:
    Add DmaDevice
python/m5/objects/Ide.py:
    Ide disk no longer has a physmem pointer
python/m5/objects/Pci.py:
    update pci device for newmem
python/m5/objects/PhysicalMemory.py:
    add latency parameter for physical memory
sim/byteswap.hh:
    use fast architecture dependent byteswap calls if they exist

--HG--
extra : convert_revision : e3cf2e8f61064ad302d94bc22010a00c59f3f793

22 files changed:
SConscript
base/chunk_generator.hh
configs/test/fs.py
dev/ide_ctrl.cc
dev/ide_ctrl.hh
dev/ide_disk.cc
dev/ide_disk.hh
dev/io_device.cc
dev/io_device.hh
dev/pciconfigall.cc
dev/pciconfigall.hh
dev/pcidev.cc
dev/pcidev.hh
mem/bus.cc
mem/packet.hh
mem/physical.cc
mem/physical.hh
python/m5/objects/Device.py
python/m5/objects/Ide.py
python/m5/objects/Pci.py
python/m5/objects/PhysicalMemory.py
sim/byteswap.hh

index 378f4db1fc6853c2b029bcf88744aa422b78719b..e41939ba3291f60b32a3e516170091de862eb088 100644 (file)
@@ -186,9 +186,12 @@ full_system_sources = Split('''
        dev/alpha_console.cc
        dev/baddev.cc
        dev/disk_image.cc
+       dev/ide_ctrl.cc
+       dev/ide_disk.cc
        dev/io_device.cc
        dev/isa_fake.cc
        dev/pciconfigall.cc
+       dev/pcidev.cc
        dev/platform.cc
         dev/simconsole.cc
        dev/simple_disk.cc
@@ -219,10 +222,7 @@ full_system_sources = Split('''
 #      dev/etherlink.cc
 #      dev/etherpkt.cc
 #      dev/ethertap.cc
-#      dev/ide_ctrl.cc
-#      dev/ide_disk.cc
 #      dev/ns_gige.cc
-#      dev/pcidev.cc
 #      dev/pcifake.cc
 #      dev/pktfifo.cc
 #      dev/sinic.cc
index 1dca50db4cc31991ad0d9d6c25b9658d5573ddcd..4f708bd4bedc584444274c18a5d647c63218a780 100644 (file)
@@ -62,6 +62,8 @@ class ChunkGenerator
     int  curSize;
     /** The number of bytes remaining in the region after the current chunk. */
     int  sizeLeft;
+    /** The start address so we can calculate offset in writing block. */
+    const Addr startAddr;
     /** The maximum chunk size, e.g., the cache block size or page size. */
     const int chunkSize;
 
@@ -73,8 +75,8 @@ class ChunkGenerator
      * @param _chunkSize The size/alignment of chunks into which
      *    the region should be decomposed.
      */
-    ChunkGenerator(Addr startAddr, int totalSize, int _chunkSize)
-        : chunkSize(_chunkSize)
+    ChunkGenerator(Addr _startAddr, int totalSize, int _chunkSize)
+        : startAddr(_startAddr), chunkSize(_chunkSize)
     {
         // chunkSize must be a power of two
         assert(chunkSize == 0 || isPowerOf2(chunkSize));
@@ -107,6 +109,8 @@ class ChunkGenerator
     /** Return size in bytes of current chunk. */
     int  size() { return curSize; }
 
+    /** Number of bytes we have already chunked up. */
+    int complete() { return curAddr - startAddr; }
     /**
      * Are we done?  That is, did the last call to next() advance
      * past the end of the region?
index d2e5381f0b587b8778e393fb199ceee7b45553f6..6608aafa7934c0db8277ab1b9f9547530cd54f6e 100644 (file)
@@ -1,9 +1,50 @@
+from m5 import *
 import os
 from SysPaths import *
 
 # Base for tests is directory containing this file.
 test_base = os.path.dirname(__file__)
 
+linux_image = env.get('LINUX_IMAGE', disk('linux-latest.img'))
+
+class IdeControllerPciData(PciConfigData):
+    VendorID = 0x8086
+    DeviceID = 0x7111
+    Command = 0x0
+    Status = 0x280
+    Revision = 0x0
+    ClassCode = 0x01
+    SubClassCode = 0x01
+    ProgIF = 0x85
+    BAR0 = 0x00000001
+    BAR1 = 0x00000001
+    BAR2 = 0x00000001
+    BAR3 = 0x00000001
+    BAR4 = 0x00000001
+    BAR5 = 0x00000001
+    InterruptLine = 0x1f
+    InterruptPin = 0x01
+    BAR0Size = '8B'
+    BAR1Size = '4B'
+    BAR2Size = '8B'
+    BAR3Size = '4B'
+    BAR4Size = '16B'
+
+
+class LinuxRootDisk(IdeDisk):
+    raw_image = RawDiskImage(image_file=linux_image, read_only=True)
+    image = CowDiskImage(child=Parent.raw_image, read_only=False)
+
+class LinuxSwapDisk(IdeDisk):
+    raw_image = RawDiskImage(image_file = disk('linux-bigswap2.img'),
+                                  read_only=True)
+    image = CowDiskImage(child = Parent.raw_image, read_only=False)
+
+class SpecwebFilesetDisk(IdeDisk):
+    raw_image = RawDiskImage(image_file = disk('specweb-fileset.img'),
+                                  read_only=True)
+    image = CowDiskImage(child = Parent.raw_image, read_only=False)
+
 class BaseTsunami(Tsunami):
     cchip = TsunamiCChip(pio_addr=0x801a0000000)
     pchip = TsunamiPChip(pio_addr=0x80180000000)
@@ -48,17 +89,19 @@ class BaseTsunami(Tsunami):
 #                        configdata=IdeControllerPciData(),
 #                        pci_func=0, pci_dev=0, pci_bus=0)
 
-#class LinuxTsunami(BaseTsunami):
-#    disk0 = LinuxRootDisk(delay='0us', driveID='master')
-#    ide = IdeController(disks=[Parent.disk0],
-#                        configdata=IdeControllerPciData(),
-#                        pci_func=0, pci_dev=0, pci_bus=0)
+class LinuxTsunami(BaseTsunami):
+    disk0 = LinuxRootDisk(driveID='master')
+    disk1 = SpecwebFilesetDisk(driveID='slave')
+    disk2 = LinuxSwapDisk(driveID='master')
+    ide = IdeController(disks=[Parent.disk0, Parent.disk1, Parent.disk2],
+                        configdata=IdeControllerPciData(),
+                        pci_func=0, pci_dev=0, pci_bus=0)
 
 class LinuxAlphaSystem(LinuxAlphaSystem):
     magicbus = Bus()
     physmem = PhysicalMemory(range = AddrRange('128MB'))
     c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus)
-    tsunami = BaseTsunami()
+    tsunami = LinuxTsunami()
     c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus)
     c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus)
     c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus)
@@ -67,6 +110,8 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
     c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus)
     c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus)
     c10 = Connector(side_a=Parent.tsunami.fake_uart4, side_a_name='pio', side_b=Parent.magicbus)
+    c11 = Connector(side_a=Parent.tsunami.ide, side_a_name='pio', side_b=Parent.magicbus)
+    c13 = Connector(side_a=Parent.tsunami.ide, side_a_name='dma', side_b=Parent.magicbus)
     c12 = Connector(side_a=Parent.tsunami.fake_ppc, side_a_name='pio', side_b=Parent.magicbus)
     c14 = Connector(side_a=Parent.tsunami.fake_OROM, side_a_name='pio', side_b=Parent.magicbus)
     c16 = Connector(side_a=Parent.tsunami.fake_pnp_addr, side_a_name='pio', side_b=Parent.magicbus)
@@ -85,7 +130,7 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
     c31 = Connector(side_a=Parent.tsunami.io, side_a_name='pio', side_b=Parent.magicbus)
     c32 = Connector(side_a=Parent.tsunami.uart, side_a_name='pio', side_b=Parent.magicbus)
     c33 = Connector(side_a=Parent.tsunami.console, side_a_name='pio', side_b=Parent.magicbus)
-    raw_image = RawDiskImage(image_file=disk('linux.img'),
+    raw_image = RawDiskImage(image_file=disk('linux-latest.img'),
                              read_only=True)
     simple_disk = SimpleDisk(disk=Parent.raw_image)
     intrctrl = IntrControl()
index fed6048675c5def74a457db41de5adce437706e4..f0fc7596e3267bc36c064245c0deebead92af6ce 100644 (file)
@@ -31,7 +31,6 @@
 #include <string>
 #include <vector>
 
-#include "arch/alpha/ev5.hh"
 #include "base/trace.hh"
 #include "cpu/intr_control.hh"
 #include "dev/ide_ctrl.hh"
 #include "dev/pciconfigall.hh"
 #include "dev/pcireg.h"
 #include "dev/platform.hh"
-#include "mem/bus/bus.hh"
-#include "mem/bus/dma_interface.hh"
-#include "mem/bus/pio_interface.hh"
-#include "mem/bus/pio_interface_impl.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
+#include "mem/packet.hh"
 #include "sim/builder.hh"
 #include "sim/sim_object.hh"
+#include "sim/byteswap.hh"
 
 using namespace std;
-using namespace TheISA;
 
 ////
 // Initialization and destruction
@@ -92,22 +86,6 @@ IdeController::IdeController(Params *p)
     bm_enabled = false;
     memset(cmd_in_progress, 0, sizeof(cmd_in_progress));
 
-    pioInterface = NULL;
-    dmaInterface = NULL;
-    // create the PIO and DMA interfaces
-    if (params()->pio_bus) {
-        pioInterface = newPioInterface(name() + ".pio", params()->hier,
-                                       params()->pio_bus, this,
-                                       &IdeController::cacheAccess);
-        pioLatency = params()->pio_latency * params()->pio_bus->clockRate;
-    }
-
-    if (params()->dma_bus) {
-        dmaInterface = new DMAInterface<Bus>(name() + ".dma",
-                                             params()->dma_bus,
-                                             params()->dma_bus, 1, true);
-    }
-
     // setup the disks attached to controller
     memset(disks, 0, sizeof(disks));
     dev[0] = 0;
@@ -118,7 +96,7 @@ IdeController::IdeController(Params *p)
 
     for (int i = 0; i < params()->disks.size(); i++) {
         disks[i] = params()->disks[i];
-        disks[i]->setController(this, dmaInterface);
+        disks[i]->setController(this);
     }
 }
 
@@ -240,91 +218,158 @@ IdeController::setDmaComplete(IdeDisk *disk)
     }
 }
 
-////
-// Bus timing and bus access functions
-////
-
-Tick
-IdeController::cacheAccess(MemReqPtr &req)
-{
-    // @todo Add more accurate timing to cache access
-    return curTick + pioLatency;
-}
 
 ////
 // Read and write handling
 ////
 
 void
-IdeController::readConfig(int offset, int size, uint8_t *data)
+IdeController::readConfig(int offset, uint8_t *data)
 {
-    int config_offset;
-
     if (offset < PCI_DEVICE_SPECIFIC) {
-        PciDev::readConfig(offset, size, data);
+        PciDev::readConfig(offset, data);
     } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + size) <= IDE_CTRL_CONF_END) {
-
-        config_offset = offset - IDE_CTRL_CONF_START;
+               (offset + 1) <= IDE_CTRL_CONF_END) {
 
-        switch (size) {
-          case sizeof(uint8_t):
-            *data = config_regs.data[config_offset];
+        switch (offset) {
+          case IDE_CTRL_CONF_DEV_TIMING:
+            *data = config_regs.sidetim;
             break;
-          case sizeof(uint16_t):
-            *(uint16_t*)data = *(uint16_t*)&config_regs.data[config_offset];
+          case IDE_CTRL_CONF_UDMA_CNTRL:
+            *data = config_regs.udmactl;
             break;
-          case sizeof(uint32_t):
-            *(uint32_t*)data = *(uint32_t*)&config_regs.data[config_offset];
+          case IDE_CTRL_CONF_PRIM_TIMING+1:
+            *data = htole(config_regs.idetim0) >> 8;
+            break;
+          case IDE_CTRL_CONF_SEC_TIMING+1:
+            *data = htole(config_regs.idetim1) >> 8;
+            break;
+          case IDE_CTRL_CONF_IDE_CONFIG:
+            *data = htole(config_regs.ideconfig) & 0xFF;
+            break;
+          case IDE_CTRL_CONF_IDE_CONFIG+1:
+            *data = htole(config_regs.ideconfig) >> 8;
             break;
           default:
-            panic("Invalid PCI configuration read size!\n");
+            panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
+                    offset);
         }
 
-        DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n",
-                offset, size, *(uint32_t*)data);
-
     } 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::writeConfig(int offset, int size, const uint8_t *data)
+IdeController::readConfig(int offset, uint16_t *data)
 {
-    int config_offset;
+    if (offset < PCI_DEVICE_SPECIFIC) {
+        PciDev::readConfig(offset, data);
+    } else if (offset >= IDE_CTRL_CONF_START &&
+               (offset + 2) <= IDE_CTRL_CONF_END) {
 
+        switch (offset) {
+          case IDE_CTRL_CONF_PRIM_TIMING:
+            *data = config_regs.idetim0;
+            break;
+          case IDE_CTRL_CONF_SEC_TIMING:
+            *data = config_regs.idetim1;
+            break;
+          case IDE_CTRL_CONF_UDMA_TIMING:
+            *data = config_regs.udmatim;
+            break;
+          case IDE_CTRL_CONF_IDE_CONFIG:
+            *data = 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, *data);
+}
+
+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, size, data);
+        PciDev::writeConfig(offset, data);
     } else if (offset >= IDE_CTRL_CONF_START &&
-               (offset + size) <= IDE_CTRL_CONF_END) {
+               (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);
+        }
 
-        config_offset = offset - IDE_CTRL_CONF_START;
+    } 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);
+}
 
-        switch(size) {
-          case sizeof(uint8_t):
-            config_regs.data[config_offset] = *data;
+void
+IdeController::writeConfig(int offset, const uint16_t data)
+{
+    if (offset < PCI_DEVICE_SPECIFIC) {
+        PciDev::writeConfig(offset, data);
+    } else if (offset >= IDE_CTRL_CONF_START &&
+               (offset + 2) <= IDE_CTRL_CONF_END) {
+
+        switch (offset) {
+          case IDE_CTRL_CONF_PRIM_TIMING:
+            config_regs.idetim0 = data;
             break;
-          case sizeof(uint16_t):
-            *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data;
+          case IDE_CTRL_CONF_SEC_TIMING:
+            config_regs.idetim1 = data;
             break;
-          case sizeof(uint32_t):
-            *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data;
+          case IDE_CTRL_CONF_UDMA_TIMING:
+            config_regs.udmatim = data;
+            break;
+          case IDE_CTRL_CONF_IDE_CONFIG:
+            config_regs.ideconfig = data;
             break;
           default:
-            panic("Invalid PCI configuration write size!\n");
+            panic("Invalid PCI configuration write for size 2 offset: %#x!\n",
+                    offset);
         }
+
     } else {
         panic("Write of unimplemented PCI config. register: %x\n", offset);
     }
+    DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n", offset, data);
 
-    DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
-            offset, size, data);
-
-    // Catch the writes to specific PCI registers that have side affects
-    // (like updating the PIO ranges)
-    switch (offset) {
-      case PCI_COMMAND:
+    /* 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
@@ -334,91 +379,111 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data)
             bm_enabled = true;
         else
             bm_enabled = false;
-        break;
+    }
+
+}
+
+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);
 
+    switch(offset) {
       case PCI0_BASE_ADDR0:
-        if (BARAddrs[0] != 0) {
+        if (BARAddrs[0] != 0)
             pri_cmd_addr = BARAddrs[0];
-            if (pioInterface)
-                pioInterface->addAddrRange(RangeSize(pri_cmd_addr,
-                                                     pri_cmd_size));
-
-            pri_cmd_addr &= EV5::PAddrUncachedMask;
-        }
         break;
 
       case PCI0_BASE_ADDR1:
-        if (BARAddrs[1] != 0) {
+        if (BARAddrs[1] != 0)
             pri_ctrl_addr = BARAddrs[1];
-            if (pioInterface)
-                pioInterface->addAddrRange(RangeSize(pri_ctrl_addr,
-                                                     pri_ctrl_size));
-
-            pri_ctrl_addr &= EV5::PAddrUncachedMask;
-        }
         break;
 
       case PCI0_BASE_ADDR2:
-        if (BARAddrs[2] != 0) {
+        if (BARAddrs[2] != 0)
             sec_cmd_addr = BARAddrs[2];
-            if (pioInterface)
-                pioInterface->addAddrRange(RangeSize(sec_cmd_addr,
-                                                     sec_cmd_size));
-
-            sec_cmd_addr &= EV5::PAddrUncachedMask;
-        }
         break;
 
       case PCI0_BASE_ADDR3:
-        if (BARAddrs[3] != 0) {
+        if (BARAddrs[3] != 0)
             sec_ctrl_addr = BARAddrs[3];
-            if (pioInterface)
-                pioInterface->addAddrRange(RangeSize(sec_ctrl_addr,
-                                                     sec_ctrl_size));
-
-            sec_ctrl_addr &= EV5::PAddrUncachedMask;
-        }
         break;
 
       case PCI0_BASE_ADDR4:
-        if (BARAddrs[4] != 0) {
+        if (BARAddrs[4] != 0)
             bmi_addr = BARAddrs[4];
-            if (pioInterface)
-                pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
-
-            bmi_addr &= EV5::PAddrUncachedMask;
-        }
         break;
     }
 }
 
-Fault
-IdeController::read(MemReqPtr &req, uint8_t *data)
+Tick
+IdeController::read(Packet &pkt)
 {
     Addr offset;
     IdeChannel channel;
     IdeRegType reg_type;
     int disk;
 
-    parseAddr(req->paddr, offset, channel, reg_type);
+    uint8_t *data8 = 0 ;
+    uint16_t *data16 = 0;
+    uint32_t *data32 = 0;
+
+    switch(pkt.size) {
+      case sizeof(uint8_t):
+        if (!pkt.data) {
+            data8 = new uint8_t;
+            pkt.data = data8;
+        } else
+            data8 = pkt.data;
+        *data8 = 0;
+      break;
+      case sizeof(uint16_t):
+        if (!pkt.data) {
+            data16 = new uint16_t;
+            pkt.data = (uint8_t*)data16;
+        } else
+            data16 = (uint16_t*)pkt.data;
+        *data16 = 0;
+      break;
+      case sizeof(uint32_t):
+        if (!pkt.data) {
+            data32 = new uint32_t;
+            pkt.data = (uint8_t*)data32;
+        } else
+            data32 = (uint32_t*)pkt.data;
+        *data32 = 0;
+      break;
+      default:
+         panic("Bad IDE read size: %d\n", pkt.size);
+    }
+
+    parseAddr(pkt.addr, offset, channel, reg_type);
 
-    if (!io_enabled)
-        return NoFault;
+    if (!io_enabled) {
+        pkt.result = Success;
+        return pioDelay;
+    }
 
     switch (reg_type) {
       case BMI_BLOCK:
-        switch (req->size) {
+        switch (pkt.size) {
           case sizeof(uint8_t):
-            *data = bmi_regs.data[offset];
+            *data8 = bmi_regs.data[offset];
             break;
           case sizeof(uint16_t):
-            *(uint16_t*)data = *(uint16_t*)&bmi_regs.data[offset];
+            *data16 = *(uint16_t*)&bmi_regs.data[offset];
             break;
           case sizeof(uint32_t):
-            *(uint32_t*)data = *(uint32_t*)&bmi_regs.data[offset];
+            *data32 = *(uint32_t*)&bmi_regs.data[offset];
             break;
           default:
-            panic("IDE read of BMI reg invalid size: %#x\n", req->size);
+            panic("IDE read of BMI reg invalid size: %#x\n", pkt.size);
         }
         break;
 
@@ -431,68 +496,82 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
 
         switch (offset) {
           case DATA_OFFSET:
-            switch (req->size) {
+            switch (pkt.size) {
               case sizeof(uint16_t):
-                disks[disk]->read(offset, reg_type, data);
+                disks[disk]->read(offset, reg_type, (uint8_t*)data16);
                 break;
 
               case sizeof(uint32_t):
-                disks[disk]->read(offset, reg_type, data);
-                disks[disk]->read(offset, reg_type, &data[2]);
+                disks[disk]->read(offset, reg_type, (uint8_t*)data16);
+                disks[disk]->read(offset, reg_type, (uint8_t*)(data16 + sizeof(uint16_t)));
                 break;
 
               default:
-                panic("IDE read of data reg invalid size: %#x\n", req->size);
+                panic("IDE read of data reg invalid size: %#x\n", pkt.size);
             }
             break;
           default:
-            if (req->size == sizeof(uint8_t)) {
-                disks[disk]->read(offset, reg_type, data);
+            if (pkt.size == sizeof(uint8_t)) {
+                disks[disk]->read(offset, reg_type, data8);
             } else
-                panic("IDE read of command reg of invalid size: %#x\n", req->size);
+                panic("IDE read of command reg of invalid size: %#x\n", pkt.size);
         }
         break;
       default:
         panic("IDE controller read of unknown register block type!\n");
     }
-
+    if (pkt.size == 1)
     DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
-            offset, req->size, *(uint32_t*)data);
+            offset, pkt.size, (uint32_t)*data8);
+    else if (pkt.size == 2)
+    DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
+            offset, pkt.size, *data16);
+    else
+    DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
+            offset, pkt.size, *data32);
 
-    return NoFault;
+    pkt.result = Success;
+    return pioDelay;
 }
 
-Fault
-IdeController::write(MemReqPtr &req, const uint8_t *data)
+Tick
+IdeController::write(Packet &pkt)
 {
     Addr offset;
     IdeChannel channel;
     IdeRegType reg_type;
     int disk;
     uint8_t oldVal, newVal;
+    uint8_t data8 = *(uint8_t*)pkt.data;
+    uint32_t data32 = *(uint32_t*)pkt.data;
 
-    parseAddr(req->paddr, offset, channel, reg_type);
 
-    if (!io_enabled)
-        return NoFault;
+    parseAddr(pkt.addr, offset, channel, reg_type);
+
+    if (!io_enabled) {
+        pkt.result = Success;
+        return pioDelay;
+    }
 
     switch (reg_type) {
       case BMI_BLOCK:
-        if (!bm_enabled)
-            return NoFault;
+        if (!bm_enabled) {
+            pkt.result = Success;
+            return pioDelay;
+        }
 
         switch (offset) {
             // Bus master IDE command register
           case BMIC1:
           case BMIC0:
-            if (req->size != sizeof(uint8_t))
-                panic("Invalid BMIC write size: %x\n", req->size);
+            if (pkt.size != sizeof(uint8_t))
+                panic("Invalid BMIC write size: %x\n", pkt.size);
 
             // select the current disk based on DEV bit
             disk = getDisk(channel);
 
             oldVal = bmi_regs.chan[channel].bmic;
-            newVal = *data;
+            newVal = data8;
 
             // if a DMA transfer is in progress, R/W control cannot change
             if (oldVal & SSBM) {
@@ -541,11 +620,11 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
             // Bus master IDE status register
           case BMIS0:
           case BMIS1:
-            if (req->size != sizeof(uint8_t))
-                panic("Invalid BMIS write size: %x\n", req->size);
+            if (pkt.size != sizeof(uint8_t))
+                panic("Invalid BMIS write size: %x\n", pkt.size);
 
             oldVal = bmi_regs.chan[channel].bmis;
-            newVal = *data;
+            newVal = data8;
 
             // the BMIDEA bit is RO
             newVal |= (oldVal & BMIDEA);
@@ -568,30 +647,28 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
           case BMIDTP0:
           case BMIDTP1:
             {
-                if (req->size != sizeof(uint32_t))
-                    panic("Invalid BMIDTP write size: %x\n", req->size);
+                if (pkt.size != sizeof(uint32_t))
+                    panic("Invalid BMIDTP write size: %x\n", pkt.size);
 
-                uint32_t host_data =  letoh(*(uint32_t*)data);
-                host_data &= ~0x3;
-                bmi_regs.chan[channel].bmidtp = htole(host_data);
+                bmi_regs.chan[channel].bmidtp = htole(data32 & ~0x3);
             }
             break;
 
           default:
-            if (req->size != sizeof(uint8_t) &&
-                req->size != sizeof(uint16_t) &&
-                req->size != sizeof(uint32_t))
+            if (pkt.size != sizeof(uint8_t) &&
+                pkt.size != sizeof(uint16_t) &&
+                pkt.size != sizeof(uint32_t))
                 panic("IDE controller write of invalid write size: %x\n",
-                      req->size);
+                      pkt.size);
 
             // do a default copy of data into the registers
-            memcpy(&bmi_regs.data[offset], data, req->size);
+            memcpy(&bmi_regs.data[offset], pkt.data, pkt.size);
         }
         break;
       case COMMAND_BLOCK:
         if (offset == IDE_SELECT_OFFSET) {
             uint8_t *devBit = &dev[channel];
-            *devBit = (letoh(*data) & IDE_SELECT_DEV_BIT) ? 1 : 0;
+            *devBit = (letoh(data8) & IDE_SELECT_DEV_BIT) ? 1 : 0;
         }
         // fall-through ok!
       case CONTROL_BLOCK:
@@ -602,34 +679,44 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
 
         switch (offset) {
           case DATA_OFFSET:
-            switch (req->size) {
+            switch (pkt.size) {
               case sizeof(uint16_t):
-                disks[disk]->write(offset, reg_type, data);
+                disks[disk]->write(offset, reg_type, pkt.data);
                 break;
 
               case sizeof(uint32_t):
-                disks[disk]->write(offset, reg_type, data);
-                disks[disk]->write(offset, reg_type, &data[2]);
+                disks[disk]->write(offset, reg_type, pkt.data);
+                disks[disk]->write(offset, reg_type, pkt.data +
+                        sizeof(uint16_t));
                 break;
               default:
-                panic("IDE write of data reg invalid size: %#x\n", req->size);
+                panic("IDE write of data reg invalid size: %#x\n", pkt.size);
             }
             break;
           default:
-            if (req->size == sizeof(uint8_t)) {
-                disks[disk]->write(offset, reg_type, data);
+            if (pkt.size == sizeof(uint8_t)) {
+                disks[disk]->write(offset, reg_type, pkt.data);
             } else
-                panic("IDE write of command reg of invalid size: %#x\n", req->size);
+                panic("IDE write of command reg of invalid size: %#x\n", pkt.size);
         }
         break;
       default:
         panic("IDE controller write of unknown register block type!\n");
     }
 
+    if (pkt.size == 1)
+    DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
+            offset, pkt.size, (uint32_t)data8);
+    else if (pkt.size == 2)
     DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
-            offset, req->size, *(uint32_t*)data);
+            offset, pkt.size, *(uint16_t*)pkt.data);
+    else
+    DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
+            offset, pkt.size, data32);
+
 
-    return NoFault;
+    pkt.result = Success;
+    return pioDelay;
 }
 
 ////
@@ -698,51 +785,35 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(bm_enabled);
     UNSERIALIZE_ARRAY(cmd_in_progress,
                       sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
-
-    if (pioInterface) {
-        pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size));
-        pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size));
-        pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size));
-        pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size));
-        pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
-   }
 }
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
 
-    Param<Addr> addr;
-    SimObjectVectorParam<IdeDisk *> disks;
-    SimObjectParam<MemoryController *> mmu;
+    SimObjectParam<System *> system;
+    SimObjectParam<Platform *> platform;
     SimObjectParam<PciConfigAll *> configspace;
     SimObjectParam<PciConfigData *> configdata;
-    SimObjectParam<Platform *> platform;
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
     Param<uint32_t> pci_func;
-    SimObjectParam<Bus *> pio_bus;
-    SimObjectParam<Bus *> dma_bus;
     Param<Tick> pio_latency;
-    SimObjectParam<HierParams *> hier;
+    SimObjectVectorParam<IdeDisk *> disks;
 
 END_DECLARE_SIM_OBJECT_PARAMS(IdeController)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
 
-    INIT_PARAM(addr, "Device Address"),
-    INIT_PARAM(disks, "IDE disks attached to this controller"),
-    INIT_PARAM(mmu, "Memory controller"),
+    INIT_PARAM(system, "System pointer"),
+    INIT_PARAM(platform, "Platform pointer"),
     INIT_PARAM(configspace, "PCI Configspace"),
     INIT_PARAM(configdata, "PCI Config data"),
-    INIT_PARAM(platform, "Platform pointer"),
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
     INIT_PARAM(pci_func, "PCI function code"),
-    INIT_PARAM(pio_bus, ""),
-    INIT_PARAM(dma_bus, ""),
     INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
-    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
+    INIT_PARAM(disks, "IDE disks attached to this controller")
 
 END_INIT_SIM_OBJECT_PARAMS(IdeController)
 
@@ -750,19 +821,15 @@ CREATE_SIM_OBJECT(IdeController)
 {
     IdeController::Params *params = new IdeController::Params;
     params->name = getInstanceName();
-    params->mmu = mmu;
+    params->platform = platform;
+    params->system = system;
     params->configSpace = configspace;
     params->configData = configdata;
-    params->plat = platform;
     params->busNum = pci_bus;
     params->deviceNum = pci_dev;
     params->functionNum = pci_func;
-
+    params->pio_delay = pio_latency;
     params->disks = disks;
-    params->pio_bus = pio_bus;
-    params->dma_bus = dma_bus;
-    params->pio_latency = pio_latency;
-    params->hier = hier;
     return new IdeController(params);
 }
 
index 0fbaf9207b982e83baf5df453eee38c64827bed0..a074f4f97c95e4090d94bfe9cfda6cca5958aee3 100644 (file)
 #define IDE_CTRL_CONF_START 0x40
 #define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs))
 
+#define IDE_CTRL_CONF_PRIM_TIMING   0x40
+#define IDE_CTRL_CONF_SEC_TIMING    0x42
+#define IDE_CTRL_CONF_DEV_TIMING    0x44
+#define IDE_CTRL_CONF_UDMA_CNTRL    0x48
+#define IDE_CTRL_CONF_UDMA_TIMING   0x4A
+#define IDE_CTRL_CONF_IDE_CONFIG    0x54
+
 
 enum IdeRegType {
     COMMAND_BLOCK,
@@ -77,13 +84,9 @@ enum IdeRegType {
     BMI_BLOCK
 };
 
-class BaseInterface;
-class Bus;
-class HierParams;
 class IdeDisk;
 class IntrControl;
 class PciConfigAll;
-class PhysicalMemory;
 class Platform;
 
 /**
@@ -191,10 +194,6 @@ class IdeController : public PciDev
     {
         /** Array of disk objects */
         std::vector<IdeDisk *> disks;
-        Bus *pio_bus;
-        Bus *dma_bus;
-        Tick pio_latency;
-        HierParams *hier;
     };
     const Params *params() const { return (const Params *)_params; }
 
@@ -202,26 +201,28 @@ class IdeController : public PciDev
     IdeController(Params *p);
     ~IdeController();
 
-    virtual void writeConfig(int offset, int size, const uint8_t *data);
-    virtual void readConfig(int offset, int size, uint8_t *data);
+    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);
 
     void setDmaComplete(IdeDisk *disk);
 
     /**
      * Read a done field for a given target.
-     * @param req Contains the address of the field to read.
-     * @param data Return the field read.
-     * @return The fault condition of the access.
+     * @param pkt Packet describing what is to be read
+     * @return The amount of time to complete this request
      */
-    virtual Fault read(MemReqPtr &req, uint8_t *data);
+    virtual Tick read(Packet &pkt);
 
     /**
-     * Write to the mmapped I/O control registers.
-     * @param req Contains the address to write to.
-     * @param data The data to write.
-     * @return The fault condition of the access.
+     * Write a done field for a given target.
+     * @param pkt Packet describing what is to be written
+     * @return The amount of time to complete this request
      */
-    virtual Fault write(MemReqPtr &req, const uint8_t *data);
+    virtual Tick write(Packet &pkt);
 
     /**
      * Serialize this object to the given output stream.
@@ -236,11 +237,5 @@ class IdeController : public PciDev
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
-    /**
-     * Return how long this access will take.
-     * @param req the memory request to calcuate
-     * @return Tick when the request is done
-     */
-    Tick cacheAccess(MemReqPtr &req);
 };
 #endif // __IDE_CTRL_HH_
index 41400c59042c2dc562c948d265ac9cd3fdb6eeb6..f1aafbc6d9f285e0235649ae38f871aa114d6821 100644 (file)
@@ -35,6 +35,7 @@
 #include <deque>
 #include <string>
 
+#include "base/chunk_generator.hh"
 #include "base/cprintf.hh" // csprintf
 #include "base/trace.hh"
 #include "dev/disk_image.hh"
 #include "dev/ide_ctrl.hh"
 #include "dev/tsunami.hh"
 #include "dev/tsunami_pchip.hh"
-#include "mem/functional/physical.hh"
-#include "mem/bus/bus.hh"
-#include "mem/bus/dma_interface.hh"
-#include "mem/bus/pio_interface.hh"
-#include "mem/bus/pio_interface_impl.hh"
+#include "mem/packet.hh"
 #include "sim/builder.hh"
 #include "sim/sim_object.hh"
 #include "sim/root.hh"
 using namespace std;
 using namespace TheISA;
 
-IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
+IdeDisk::IdeDisk(const string &name, DiskImage *img,
                  int id, Tick delay)
-    : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay),
-      dmaTransferEvent(this), dmaReadWaitEvent(this),
-      dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
+    : SimObject(name), ctrl(NULL), image(img), diskDelay(delay),
+      dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this),
+      dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
       dmaReadEvent(this), dmaWriteEvent(this)
 {
     // Reset the device state
@@ -139,7 +136,6 @@ IdeDisk::reset(int id)
     memset(&cmdReg, 0, sizeof(CommandReg_t));
     memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
 
-    dmaInterfaceBytes = 0;
     curPrdAddr = 0;
     curSector = 0;
     cmdBytes = 0;
@@ -188,29 +184,6 @@ IdeDisk::pciToDma(Addr pciAddr)
         panic("Access to unset controller!\n");
 }
 
-uint32_t
-IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
-{
-    uint32_t bytesInPage = 0;
-
-    // First calculate how many bytes could be in the page
-    if (bytesLeft > TheISA::PageBytes)
-        bytesInPage = TheISA::PageBytes;
-    else
-        bytesInPage = bytesLeft;
-
-    // Next, see if we have crossed a page boundary, and adjust
-    Addr upperBound = curAddr + bytesInPage;
-    Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes;
-
-    assert(upperBound >= curAddr && "DMA read wraps around address space!\n");
-
-    if (upperBound >= pageBound)
-        bytesInPage = pageBound - curAddr;
-
-    return bytesInPage;
-}
-
 ////
 // Device registers read/write
 ////
@@ -339,29 +312,17 @@ IdeDisk::doDmaTransfer()
         panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
               dmaState, devState);
 
-    // first read the current PRD
-    if (dmaInterface) {
-        if (dmaInterface->busy()) {
-            // reschedule after waiting period
-            dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
-            return;
-        }
-
-        dmaInterface->doDMA(Read, curPrdAddr, sizeof(PrdEntry_t), curTick,
-                            &dmaPrdReadEvent);
-    } else {
-        dmaPrdReadDone();
-    }
+    if (ctrl->dmaPending()) {
+        dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+        return;
+    } else
+        ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent,
+                (uint8_t*)&curPrd.entry);
 }
 
 void
 IdeDisk::dmaPrdReadDone()
 {
-    // actually copy the PRD from physical memory
-    memcpy((void *)&curPrd.entry,
-           physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
-           sizeof(PrdEntry_t));
-
     DPRINTF(IdeDisk,
             "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
             curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
@@ -372,38 +333,49 @@ IdeDisk::dmaPrdReadDone()
     curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
 
     if (dmaRead)
-        doDmaRead();
+        doDmaDataRead();
     else
-        doDmaWrite();
+        doDmaDataWrite();
 }
 
 void
-IdeDisk::doDmaRead()
+IdeDisk::doDmaDataRead()
 {
     /** @todo we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
 
     DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
             diskDelay, totalDiskDelay);
-    if (dmaInterface) {
-        if (dmaInterface->busy()) {
-            // reschedule after waiting period
-            dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
-            return;
-        }
 
-        Addr dmaAddr = pciToDma(curPrd.getBaseAddr());
+    dmaReadWaitEvent.schedule(curTick + totalDiskDelay);
+}
 
-        uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(),
-                                              (uint32_t)curPrd.getByteCount());
 
-        dmaInterfaceBytes = bytesInPage;
+void
+IdeDisk::doDmaRead()
+{
+
+    if (!dmaReadCG) {
+        // clear out the data buffer
+        memset(dataBuffer, 0, MAX_DMA_SIZE);
+        dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(),
+                curPrd.getByteCount(), TheISA::PageBytes);
 
-        dmaInterface->doDMA(Read, dmaAddr, bytesInPage,
-                            curTick + totalDiskDelay, &dmaReadEvent);
+    }
+    if (ctrl->dmaPending()) {
+        panic("shouldn't be reentant??");
+        dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+        return;
+    } else if (!dmaReadCG->done()) {
+        assert(dmaReadCG->complete() < MAX_DMA_SIZE);
+        ctrl->dmaRead(pciToDma(dmaReadCG->addr()), dmaReadCG->size(),
+                &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete());
+        dmaReadCG->next();
     } else {
-        // schedule dmaReadEvent with sectorDelay (dmaReadDone)
-        dmaReadEvent.schedule(curTick + totalDiskDelay);
+        assert(dmaReadCG->done());
+        delete dmaReadCG;
+        dmaReadCG = NULL;
+        dmaReadDone();
     }
 }
 
@@ -411,63 +383,14 @@ void
 IdeDisk::dmaReadDone()
 {
 
-    Addr curAddr = 0, dmaAddr = 0;
-    uint32_t bytesWritten = 0, bytesInPage = 0, bytesLeft = 0;
-
-    // continue to use the DMA interface until all pages are read
-    if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) {
-        // see if the interface is busy
-        if (dmaInterface->busy()) {
-            // reschedule after waiting period
-            dmaReadEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
-            return;
-        }
-
-        uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes;
-        curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes;
-        dmaAddr = pciToDma(curAddr);
-
-        bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
-        dmaInterfaceBytes += bytesInPage;
-
-        dmaInterface->doDMA(Read, dmaAddr, bytesInPage,
-                            curTick, &dmaReadEvent);
-
-        return;
-    }
-
-    // set initial address
-    curAddr = curPrd.getBaseAddr();
-
-    // clear out the data buffer
-    memset(dataBuffer, 0, MAX_DMA_SIZE);
+    uint32_t bytesWritten = 0;
 
-    // read the data from memory via DMA into a data buffer
-    while (bytesWritten < curPrd.getByteCount()) {
-        if (cmdBytesLeft <= 0)
-            panic("DMA data is larger than # of sectors specified\n");
-
-        dmaAddr = pciToDma(curAddr);
-
-        // calculate how many bytes are in the current page
-        bytesLeft = curPrd.getByteCount() - bytesWritten;
-        bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
-
-        // copy the data from memory into the data buffer
-        memcpy((void *)(dataBuffer + bytesWritten),
-               physmem->dma_addr(dmaAddr, bytesInPage),
-               bytesInPage);
-
-        curAddr += bytesInPage;
-        bytesWritten += bytesInPage;
-        cmdBytesLeft -= bytesInPage;
-    }
 
     // write the data to the disk image
-    for (bytesWritten = 0;
-         bytesWritten < curPrd.getByteCount();
+    for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
          bytesWritten += SectorSize) {
 
+        cmdBytesLeft -= SectorSize;
         writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
     }
 
@@ -482,107 +405,55 @@ IdeDisk::dmaReadDone()
 }
 
 void
-IdeDisk::doDmaWrite()
+IdeDisk::doDmaDataWrite()
 {
     /** @todo we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
+    uint32_t bytesRead = 0;
 
     DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
             diskDelay, totalDiskDelay);
 
-    if (dmaInterface) {
-        if (dmaInterface->busy()) {
-            // reschedule after waiting period
-            dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
-            return;
-        }
-
-        Addr dmaAddr = pciToDma(curPrd.getBaseAddr());
+    memset(dataBuffer, 0, MAX_DMA_SIZE);
+    assert(cmdBytesLeft <= MAX_DMA_SIZE);
+    while (bytesRead < curPrd.getByteCount()) {
+        readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
+        bytesRead += SectorSize;
+        cmdBytesLeft -= SectorSize;
+    }
 
-        uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(),
-                                              (uint32_t)curPrd.getByteCount());
+    dmaWriteWaitEvent.schedule(curTick + totalDiskDelay);
+}
 
-        dmaInterfaceBytes = bytesInPage;
+void
+IdeDisk::doDmaWrite()
+{
 
-        dmaInterface->doDMA(WriteInvalidate, dmaAddr,
-                            bytesInPage, curTick + totalDiskDelay,
-                            &dmaWriteEvent);
+    if (!dmaWriteCG) {
+        // clear out the data buffer
+        dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(),
+                curPrd.getByteCount(), TheISA::PageBytes);
+    }
+    if (ctrl->dmaPending()) {
+        panic("shouldn't be reentant??");
+        dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+        return;
+    } else if (!dmaWriteCG->done()) {
+        assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
+        ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(),
+                &dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete());
+        dmaWriteCG->next();
     } else {
-        // schedule event with disk delay (dmaWriteDone)
-        dmaWriteEvent.schedule(curTick + totalDiskDelay);
+        assert(dmaWriteCG->done());
+        delete dmaWriteCG;
+        dmaWriteCG = NULL;
+        dmaWriteDone();
     }
 }
 
 void
 IdeDisk::dmaWriteDone()
 {
-    Addr curAddr = 0, pageAddr = 0, dmaAddr = 0;
-    uint32_t bytesRead = 0, bytesInPage = 0;
-
-    // continue to use the DMA interface until all pages are read
-    if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) {
-        // see if the interface is busy
-        if (dmaInterface->busy()) {
-            // reschedule after waiting period
-            dmaWriteEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
-            return;
-        }
-
-        uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes;
-        curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes;
-        dmaAddr = pciToDma(curAddr);
-
-        bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
-        dmaInterfaceBytes += bytesInPage;
-
-        dmaInterface->doDMA(WriteInvalidate, dmaAddr,
-                            bytesInPage, curTick,
-                            &dmaWriteEvent);
-
-        return;
-    }
-
-    // setup the initial page and DMA address
-    curAddr = curPrd.getBaseAddr();
-    pageAddr = TheISA::TruncPage(curAddr);
-    dmaAddr = pciToDma(curAddr);
-
-    // clear out the data buffer
-    memset(dataBuffer, 0, MAX_DMA_SIZE);
-
-    while (bytesRead < curPrd.getByteCount()) {
-        // see if we have crossed into a new page
-        if (pageAddr != TheISA::TruncPage(curAddr)) {
-            // write the data to memory
-            memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
-                   (void *)(dataBuffer + (bytesRead - bytesInPage)),
-                   bytesInPage);
-
-            // update the DMA address and page address
-            pageAddr = TheISA::TruncPage(curAddr);
-            dmaAddr = pciToDma(curAddr);
-
-            bytesInPage = 0;
-        }
-
-        if (cmdBytesLeft <= 0)
-            panic("DMA requested data is larger than # sectors specified\n");
-
-        readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
-
-        curAddr += SectorSize;
-        bytesRead += SectorSize;
-        bytesInPage += SectorSize;
-        cmdBytesLeft -= SectorSize;
-    }
-
-    // write the last page worth read to memory
-    if (bytesInPage != 0) {
-        memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
-               (void *)(dataBuffer + (bytesRead - bytesInPage)),
-               bytesInPage);
-    }
-
     // check for the EOT
     if (curPrd.getEOT()) {
         assert(cmdBytesLeft == 0);
@@ -1138,13 +1009,13 @@ IdeDisk::serialize(ostream &os)
     SERIALIZE_SCALAR(curPrd.entry.endOfTable);
     SERIALIZE_SCALAR(curPrdAddr);
 
+    /** @todo need to serialized chunk generator stuff!! */
     // Serialize current transfer related information
     SERIALIZE_SCALAR(cmdBytesLeft);
     SERIALIZE_SCALAR(cmdBytes);
     SERIALIZE_SCALAR(drqBytesLeft);
     SERIALIZE_SCALAR(curSector);
     SERIALIZE_SCALAR(dmaRead);
-    SERIALIZE_SCALAR(dmaInterfaceBytes);
     SERIALIZE_SCALAR(intrPending);
     SERIALIZE_ENUM(devState);
     SERIALIZE_ENUM(dmaState);
@@ -1190,13 +1061,13 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
     UNSERIALIZE_SCALAR(curPrd.entry.endOfTable);
     UNSERIALIZE_SCALAR(curPrdAddr);
 
+    /** @todo need to serialized chunk generator stuff!! */
     // Unserialize current transfer related information
     UNSERIALIZE_SCALAR(cmdBytes);
     UNSERIALIZE_SCALAR(cmdBytesLeft);
     UNSERIALIZE_SCALAR(drqBytesLeft);
     UNSERIALIZE_SCALAR(curSector);
     UNSERIALIZE_SCALAR(dmaRead);
-    UNSERIALIZE_SCALAR(dmaInterfaceBytes);
     UNSERIALIZE_SCALAR(intrPending);
     UNSERIALIZE_ENUM(devState);
     UNSERIALIZE_ENUM(dmaState);
@@ -1210,7 +1081,6 @@ static const char *DriveID_strings[] = { "master", "slave" };
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
 
     SimObjectParam<DiskImage *> image;
-    SimObjectParam<PhysicalMemory *> physmem;
     SimpleEnumParam<DriveID> driveID;
     Param<int> delay;
 
@@ -1219,7 +1089,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
 BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk)
 
     INIT_PARAM(image, "Disk image"),
-    INIT_PARAM(physmem, "Physical memory"),
     INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings),
     INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1)
 
@@ -1228,7 +1097,7 @@ END_INIT_SIM_OBJECT_PARAMS(IdeDisk)
 
 CREATE_SIM_OBJECT(IdeDisk)
 {
-    return new IdeDisk(getInstanceName(), image, physmem, driveID, delay);
+    return new IdeDisk(getInstanceName(), image, driveID, delay);
 }
 
 REGISTER_SIM_OBJECT("IdeDisk", IdeDisk)
index a656ca464ef8c14ae52a5480fa0ecc9800ffbf60..3d67abece2e8b4cb6bee405f8ac3a8ecf84e2f58 100644 (file)
@@ -42,7 +42,7 @@
 
 #define DMA_BACKOFF_PERIOD 200
 
-#define MAX_DMA_SIZE    (65536)  // 64K
+#define MAX_DMA_SIZE    (131072)  // 128K
 #define MAX_MULTSECT    (128)
 
 #define PRD_BASE_MASK  0xfffffffe
@@ -190,12 +190,8 @@ class IdeDisk : public SimObject
   protected:
     /** The IDE controller for this disk. */
     IdeController *ctrl;
-    /** The DMA interface to use for transfers */
-    DMAInterface<Bus> *dmaInterface;
     /** The image that contains the data of this disk. */
     DiskImage *image;
-    /** Pointer to physical memory for DMA transfers */
-    PhysicalMemory *physmem;
 
   protected:
     /** The disk delay in microseconds. */
@@ -230,8 +226,6 @@ class IdeDisk : public SimObject
     uint32_t curPrdAddr;
     /** PRD entry */
     PrdTableEntry curPrd;
-    /** Number of bytes transfered by DMA interface for current transfer */
-    uint32_t dmaInterfaceBytes;
     /** Device ID (master=0/slave=1) */
     int devID;
     /** Interrupt pending */
@@ -242,12 +236,10 @@ class IdeDisk : public SimObject
      * Create and initialize this Disk.
      * @param name The name of this disk.
      * @param img The disk image of this disk.
-     * @param phys Pointer to physical memory
      * @param id The disk ID (master=0/slave=1)
      * @param disk_delay The disk delay in milliseconds
      */
-    IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys,
-            int id, Tick disk_delay);
+    IdeDisk(const std::string &name, DiskImage *img, int id, Tick disk_delay);
 
     /**
      * Delete the data buffer.
@@ -263,10 +255,9 @@ class IdeDisk : public SimObject
      * Set the controller for this device
      * @param c The IDE controller
      */
-    void setController(IdeController *c, DMAInterface<Bus> *dmaIntr) {
+    void setController(IdeController *c) {
         if (ctrl) panic("Cannot change the controller once set!\n");
         ctrl = c;
-        dmaInterface = dmaIntr;
     }
 
     // Device register read/write
@@ -289,11 +280,17 @@ class IdeDisk : public SimObject
     friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>;
     EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent;
 
+    void doDmaDataRead();
+
     void doDmaRead();
+    ChunkGenerator *dmaReadCG;
     friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>;
     EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent;
 
+    void doDmaDataWrite();
+
     void doDmaWrite();
+    ChunkGenerator *dmaWriteCG;
     friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>;
     EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent;
 
@@ -339,8 +336,6 @@ class IdeDisk : public SimObject
 
     inline Addr pciToDma(Addr pciAddr);
 
-    uint32_t bytesInDmaPage(Addr curAddr, uint32_t bytesLeft);
-
     /**
      * Serialize this object to the given output stream.
      * @param os The stream to serialize to.
index a2e5a8a0d0be6b1f35f4f53081a135f31953fadf..4a84b6817648e5b2441aa121c4dc239b072a5ad6 100644 (file)
@@ -105,23 +105,24 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
 }
 
 
-DmaPort::DmaPort(DmaDevice *dev)
-        : device(dev)
+DmaPort::DmaPort(DmaDevice *dev, Platform *p)
+        : device(dev), platform(p), pendingCount(0)
 { }
 
 bool
 DmaPort::recvTiming(Packet &pkt)
 {
-    completionEvent->schedule(curTick+1);
-    completionEvent = NULL;
+    if (pkt.senderState) {
+        DmaReqState *state;
+        state = (DmaReqState*)pkt.senderState;
+        state->completionEvent->schedule(pkt.time - pkt.req->getTime());
+    }
     return Success;
 }
 
 DmaDevice::DmaDevice(Params *p)
-    : PioDevice(p)
-{
-    dmaPort = new DmaPort(this);
-}
+    : PioDevice(p), dmaPort(NULL)
+{ }
 
 void
 DmaPort::SendEvent::process()
@@ -140,8 +141,8 @@ DmaPort::recvRetry()
     return pkt;
 }
 void
-DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
-                     Event *event, uint8_t *data)
+DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
+        uint8_t *data)
 {
 
     assert(event);
@@ -161,8 +162,6 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
 //    baseReq.nicReq = true;
     baseReq.setTime(curTick);
 
-    completionEvent = event;
-
     for (ChunkGenerator gen(addr, size, peerBlockSize());
          !gen.done(); gen.next()) {
             Packet *pkt = new Packet(basePkt);
@@ -175,7 +174,15 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
             // Increment the data pointer on a write
             pkt->data = data ? data + prevSize : NULL ;
             prevSize += pkt->size;
-
+            // Set the last bit of the dma as the final packet for this dma
+            // and set it's completion event.
+            if (prevSize == size) {
+                DmaReqState *state = new DmaReqState(event, true);
+
+                pkt->senderState = (void*)state;
+            }
+            assert(pendingCount >= 0);
+            pendingCount++;
             sendDma(*pkt);
     }
 }
@@ -194,8 +201,12 @@ DmaPort::sendDma(Packet &pkt)
            transmitList.push_back(&packet);
    } else if (state == Atomic) {*/
        sendAtomic(pkt);
-       completionEvent->schedule(pkt.time - pkt.req->getTime());
-       completionEvent = NULL;
+       if (pkt.senderState) {
+           DmaReqState *state = (DmaReqState*)pkt.senderState;
+           state->completionEvent->schedule(curTick + (pkt.time - pkt.req->getTime()) +1);
+       }
+        pendingCount--;
+        assert(pendingCount >= 0);
 /*   } else if (state == Functional) {
        sendFunctional(pkt);
        // Is this correct???
index 5379a664c00f56e6c534fa4a9b5f5fa7cfde446d..bc0160c46ab69cc7abb401d9aac9a81f27be170a 100644 (file)
@@ -113,13 +113,28 @@ class PioPort : public Port
   friend class PioPort::SendEvent;
 };
 
+
+struct DmaReqState
+{
+    Event *completionEvent;
+    bool final;
+    DmaReqState(Event *ce, bool f)
+        : completionEvent(ce), final(f)
+    {}
+};
+
 class DmaPort : public Port
 {
   protected:
-    PioDevice *device;
+    DmaDevice *device;
     std::list<Packet*> transmitList;
-    Event *completionEvent;
 
+    /** The platform that device/port are in. This is used to select which mode
+     * we are currently operating in. */
+    Platform *platform;
+
+    /** Number of outstanding packets the dma port has. */
+    int pendingCount;
 
     virtual bool recvTiming(Packet &pkt);
     virtual Tick recvAtomic(Packet &pkt)
@@ -152,13 +167,15 @@ class DmaPort : public Port
         friend class DmaPort;
     };
 
-    void dmaAction(Command cmd, DmaPort port, Addr addr, int size,
-              Event *event, uint8_t *data = NULL);
-
     void sendDma(Packet &pkt);
 
   public:
-    DmaPort(DmaDevice *dev);
+    DmaPort(DmaDevice *dev, Platform *p);
+
+    void dmaAction(Command cmd, Addr addr, int size, Event *event,
+            uint8_t *data = NULL);
+
+    bool dmaPending() { return pendingCount > 0; }
 
   friend class DmaPort::SendEvent;
 
@@ -286,13 +303,27 @@ class DmaDevice : public PioDevice
     DmaDevice(Params *p);
     virtual ~DmaDevice();
 
+    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
+    { dmaPort->dmaAction(Write, addr, size, event, data) ; }
+
+    void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
+    { dmaPort->dmaAction(Read, addr, size, event, data); }
+
+    bool dmaPending() { return dmaPort->dmaPending(); }
+
     virtual Port *getPort(const std::string &if_name)
     {
-        if (if_name == "pio")
+        if (if_name == "pio") {
+            if (pioPort != NULL)
+                panic("pio port already connected to.");
+            pioPort = new PioPort(this, params()->platform);
             return pioPort;
-        else if (if_name == "dma")
+        } else if (if_name == "dma") {
+            if (dmaPort != NULL)
+                panic("dma port already connected to.");
+            dmaPort = new DmaPort(this, params()->platform);
             return dmaPort;
-        else
+        else
             return NULL;
     }
 
index 86a505b9a551c30aaf7c57924604876b3f7ec2e6..fa6b35f7763f74bfe1fd8dec5b5e08ba82b5cc0f 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "base/trace.hh"
 #include "dev/pciconfigall.hh"
-//#include "dev/pcidev.hh"
+#include "dev/pcidev.hh"
 #include "dev/pcireg.h"
 #include "dev/platform.hh"
 #include "mem/packet.hh"
@@ -68,7 +68,7 @@ PciConfigAll::PciConfigAll(Params *p)
 void
 PciConfigAll::startup()
 {
-/*    bitset<256> intLines;
+    bitset<256> intLines;
     PciDev *tempDev;
     uint8_t intline;
 
@@ -85,7 +85,7 @@ PciConfigAll::startup()
            } // devices != NULL
         } // PCI_FUNC
     } // PCI_DEV
-  */
+
 }
 
 Tick
@@ -97,7 +97,7 @@ PciConfigAll::read(Packet &pkt)
     Addr daddr = pkt.addr - pioAddr;
     int device = (daddr >> 11) & 0x1F;
     int func = (daddr >> 8) & 0x7;
-    //int reg = daddr & 0xFF;
+    int reg = daddr & 0xFF;
 
     pkt.time = curTick + pioDelay;
 
@@ -131,7 +131,7 @@ PciConfigAll::read(Packet &pkt)
          if (devices[device][func] == NULL)
              *data32 = 0xFFFFFFFF;
          else
-             ;//devices[device][func]->readConfig(reg, req.size, data32);
+             devices[device][func]->readConfig(reg, data32);
          break;
       case sizeof(uint16_t):
          if (!pkt.data) {
@@ -143,7 +143,7 @@ PciConfigAll::read(Packet &pkt)
          if (devices[device][func] == NULL)
              *data16 = 0xFFFF;
          else
-             ;//devices[device][func]->readConfig(reg, req.size, data16);
+             devices[device][func]->readConfig(reg, data16);
          break;
       case sizeof(uint8_t):
          if (!pkt.data) {
@@ -155,7 +155,7 @@ PciConfigAll::read(Packet &pkt)
          if (devices[device][func] == NULL)
              *data8 = 0xFF;
          else
-             ;//devices[device][func]->readConfig(reg, req.size, data8);
+             devices[device][func]->readConfig(reg, data8);
          break;
       default:
         panic("invalid access size(?) for PCI configspace!\n");
@@ -177,7 +177,7 @@ PciConfigAll::write(Packet &pkt)
 
     int device = (daddr >> 11) & 0x1F;
     int func = (daddr >> 8) & 0x7;
-//    int reg = daddr & 0xFF;
+    int reg = daddr & 0xFF;
 
     if (devices[device][func] == NULL)
         panic("Attempting to write to config space on non-existant device\n");
@@ -185,8 +185,19 @@ PciConfigAll::write(Packet &pkt)
     DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n",
             pkt.addr, pkt.size, *(uint32_t*)pkt.data);
 
-//    devices[device][func]->writeConfig(reg, req->size, data);
-
+    switch (pkt.size) {
+      case sizeof(uint8_t):
+        devices[device][func]->writeConfig(reg, *pkt.data);
+        break;
+      case sizeof(uint16_t):
+        devices[device][func]->writeConfig(reg, *(uint16_t*)pkt.data);
+        break;
+      case sizeof(uint32_t):
+        devices[device][func]->writeConfig(reg, *(uint32_t*)pkt.data);
+        break;
+      default:
+        panic("invalid pci config write size\n");
+    }
     return pioDelay;
 }
 
index b2034594c5338acdb2fff6a888519484123617dd..2393b445e381c2e5b496c7db2f833b83ad8000b0 100644 (file)
@@ -54,8 +54,6 @@ class PciDev;
 class PciConfigAll : public BasicPioDevice
 {
   private:
-    static const Addr size = 0xffffff;
-
     /**
       * Pointers to all the devices that are registered with this
       * particular config space.
index a05ee380323c6dd2fc5b72c6974cbf9bf6b7260c..c40ef62e49c4dfcab44f1d349407897ea783592a 100644 (file)
 #include "base/misc.hh"
 #include "base/str.hh" // for to_number
 #include "base/trace.hh"
-#include "dev/pcidev.hh"
 #include "dev/pciconfigall.hh"
-#include "mem/bus/bus.hh"
-#include "mem/functional/memory_control.hh"
+#include "dev/pcidev.hh"
+#include "dev/tsunamireg.h"
+#include "mem/packet.hh"
 #include "sim/builder.hh"
+#include "sim/byteswap.hh"
 #include "sim/param.hh"
 #include "sim/root.hh"
-#include "dev/tsunamireg.h"
 
 using namespace std;
 
 PciDev::PciDev(Params *p)
-    : DmaDevice(p->name, p->plat), _params(p), plat(p->plat),
-      configData(p->configData)
+    : DmaDevice(p), plat(p->platform), configData(p->configData),
+      pioDelay(p->pio_delay)
 {
     // copy the config data from the PciConfigData object
     if (configData) {
@@ -70,214 +70,180 @@ PciDev::PciDev(Params *p)
         p->configSpace->registerDevice(p->deviceNum, p->functionNum, this);
 }
 
-Fault
-PciDev::read(MemReqPtr &req, uint8_t *data)
-{ return NoFault; }
-
-Fault
-PciDev::write(MemReqPtr &req, const uint8_t *data)
-{ return NoFault; }
-
-Fault
-PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
-
-Fault
-PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint8_t *data)
+{
+    if (offset >= PCI_DEVICE_SPECIFIC)
+        panic("Device specific PCI config space not implemented!\n");
 
-Fault
-PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+    *data = config.data[offset];
 
-Fault
-PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+    DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset, *data);
+}
 
-Fault
-PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::addressRanges(AddrRangeList &range_list)
+{
+    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]));
+}
 
-Fault
-PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint16_t *data)
+{
+    if (offset >= PCI_DEVICE_SPECIFIC)
+        panic("Device specific PCI config space not implemented!\n");
 
-Fault
-PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+    *data = *(uint16_t*)&config.data[offset];
 
-Fault
-PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+    DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset, *data);
+}
 
-Fault
-PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint32_t *data)
+{
+    if (offset >= PCI_DEVICE_SPECIFIC)
+        panic("Device specific PCI config space not implemented!\n");
 
-Fault
-PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+    *data = *(uint32_t*)&config.data[offset];
 
-Fault
-PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+    DPRINTF(PCIDEV,
+            "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n",
+            params()->deviceNum, params()->functionNum, offset, *data);
+}
 
-Fault
-PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
 
 void
-PciDev::readConfig(int offset, int size, uint8_t *data)
+PciDev::writeConfig(int offset,  const uint8_t data)
 {
     if (offset >= PCI_DEVICE_SPECIFIC)
         panic("Device specific PCI config space not implemented!\n");
 
-    switch(size) {
-      case sizeof(uint8_t):
-        *data = config.data[offset];
-        break;
-      case sizeof(uint16_t):
-        *(uint16_t*)data = *(uint16_t*)&config.data[offset];
+    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;
         break;
-      case sizeof(uint32_t):
-        *(uint32_t*)data = *(uint32_t*)&config.data[offset];
+      /* 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("Invalid PCI configuration read size!\n");
+        panic("writing to a read only register");
     }
-
-    DPRINTF(PCIDEV,
-            "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, size,
-            *(uint32_t*)data);
 }
 
 void
-PciDev::writeConfig(int offset, int size, const uint8_t *data)
+PciDev::writeConfig(int offset, const uint16_t data)
 {
     if (offset >= PCI_DEVICE_SPECIFIC)
         panic("Device specific PCI config space not implemented!\n");
 
-    uint8_t &data8 = *(uint8_t*)data;
-    uint16_t &data16 = *(uint16_t*)data;
-    uint32_t &data32 = *(uint32_t*)data;
-
     DPRINTF(PCIDEV,
-            "write device: %#x function: %#x reg: %#x size: %d data: %#x\n",
-            params()->deviceNum, params()->functionNum, offset, size, data32);
-
-    switch (size) {
-      case sizeof(uint8_t): // 1-byte access
-        switch (offset) {
-          case PCI0_INTERRUPT_LINE:
-            config.interruptLine = data8;
-          case PCI_CACHE_LINE_SIZE:
-            config.cacheLineSize = data8;
-          case PCI_LATENCY_TIMER:
-            config.latencyTimer = data8;
-            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");
-        }
+            "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");
+    }
+}
 
-      case sizeof(uint16_t): // 2-byte access
-        switch (offset) {
-          case PCI_COMMAND:
-            config.command = data16;
-          case PCI_STATUS:
-            config.status = data16;
-          case PCI_CACHE_LINE_SIZE:
-            config.cacheLineSize = data16;
-            break;
-          default:
-            panic("writing to a read only register");
-        }
-        break;
 
-      case sizeof(uint32_t): // 4-byte access
-        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;
-            }
+void
+PciDev::writeConfig(int offset, const uint32_t data)
+{
+    if (offset >= PCI_DEVICE_SPECIFIC)
+        panic("Device specific PCI config space not implemented!\n");
 
-            // Writing 0xffffffff to a BAR tells the card to set the
-            // value of the bar to size of memory it needs
-            if (letoh(data32) == 0xffffffff) {
-                // This is I/O Space, bottom two bits are read only
+    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;
+        }
 
-                config.baseAddr[barnum] = letoh(
-                        (~(BARSize[barnum] - 1) & ~bar_mask) |
-                        (letoh(config.baseAddr[barnum]) & bar_mask));
-            } else {
-                MemoryController *mmu = params()->mmu;
+        // 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(
-                    (letoh(data32) & ~bar_mask) |
+            config.baseAddr[barnum] = letoh(
+                    (~(BARSize[barnum] - 1) & ~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(data32) & ~bar_mask) + space_base;
-                    base_size = BARSize[barnum];
-
-                    // It's never been set
-                    if (BARAddrs[barnum] == 0)
-                        mmu->add_child((FunctionalMemory *)this,
-                                       RangeSize(base_addr, base_size));
-                    else
-                        mmu->update_child((FunctionalMemory *)this,
-                                          RangeSize(BARAddrs[barnum], base_size),
-                                          RangeSize(base_addr, base_size));
-
-                    BARAddrs[barnum] = base_addr;
-                }
+            pioPort->sendStatusChange(Port::RangeChange);
             }
-            break;
-
-          case PCI0_ROM_BASE_ADDR:
-            if (letoh(data32) == 0xfffffffe)
-                config.expansionROM = htole((uint32_t)0xffffffff);
-            else
-                config.expansionROM = data32;
-            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 = data16;
-            break;
-
-          default:
-            DPRINTF(PCIDEV, "Writing to a read only register");
         }
         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:
-        panic("invalid access size");
+        DPRINTF(PCIDEV, "Writing to a read only register");
     }
 }
 
@@ -296,12 +262,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
     UNSERIALIZE_ARRAY(config.data,
                       sizeof(config.data) / sizeof(config.data[0]));
-
-    // Add the MMU mappings for the BARs
-    for (int i=0; i < 6; i++) {
-        if (BARAddrs[i] != 0)
-            params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i]));
-    }
 }
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
index bdfc6b93230f5d6ecb12018975aaef9348f0f5ad..fc477390834f7788743ecdd7f86f23c3e2f48a09 100644 (file)
@@ -44,7 +44,6 @@
 #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
 
 class PciConfigAll;
-class MemoryController;
 
 
 /**
@@ -85,12 +84,8 @@ class PciConfigData : public SimObject
 class PciDev : public DmaDevice
 {
   public:
-    struct Params
+    struct Params : public ::PioDevice::Params
     {
-        std::string name;
-        Platform *plat;
-        MemoryController *mmu;
-
         /**
          * A pointer to the configspace all object that calls us when
          * a read comes to this particular device/function.
@@ -111,13 +106,13 @@ class PciDev : public DmaDevice
 
         /** The function number */
         uint32_t functionNum;
-    };
 
-  protected:
-    Params *_params;
+        /** The latency for pio accesses. */
+        Tick pio_delay;
+    };
 
   public:
-    const Params *params() const { return _params; }
+    const Params *params() const { return (const Params *)_params; }
 
   protected:
     /** The current config space. Unlike the PciConfigData this is
@@ -164,6 +159,7 @@ class PciDev : public DmaDevice
   protected:
     Platform *plat;
     PciConfigData *configData;
+    Tick pioDelay;
 
   public:
     Addr pciToDma(Addr pciAddr) const
@@ -181,7 +177,11 @@ class PciDev : public DmaDevice
     interruptLine()
     { return configData->config.interruptLine; }
 
-  public:
+    /** return the address ranges that this device responds to.
+     * @params range_list range list to populate with ranges
+     */
+    void addressRanges(AddrRangeList &range_list);
+
     /**
      * Constructor for PCI Dev. This function copies data from the
      * config file object PCIConfigData and registers the device with
@@ -189,39 +189,6 @@ class PciDev : public DmaDevice
      */
     PciDev(Params *params);
 
-    virtual Fault read(MemReqPtr &req, uint8_t *data);
-    virtual Fault write(MemReqPtr &req, const uint8_t *data);
-
-  public:
-    /**
-     * Implement the read/write as BAR accesses
-     */
-    Fault readBar(MemReqPtr &req, uint8_t *data);
-    Fault writeBar(MemReqPtr &req, const uint8_t *data);
-
-  public:
-    /**
-     * Read from a specific BAR
-     */
-    virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
-    virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data);
-    virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data);
-    virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data);
-    virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data);
-    virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data);
-
-  public:
-    /**
-     * Write to a specific BAR
-     */
-    virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
-    virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data);
-    virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data);
-    virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data);
-    virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data);
-    virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data);
-
-  public:
     /**
      * 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
@@ -230,7 +197,9 @@ class PciDev : public DmaDevice
      * @param size the size of the write
      * @param data the data to write
      */
-    virtual void writeConfig(int offset, int size, const uint8_t* data);
+    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);
 
 
     /**
@@ -241,7 +210,9 @@ class PciDev : public DmaDevice
      * @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, int size, uint8_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);
 
     /**
      * Serialize this object to the given output stream.
@@ -256,43 +227,4 @@ class PciDev : public DmaDevice
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 };
-
-inline Fault
-PciDev::readBar(MemReqPtr &req, uint8_t *data)
-{
-    using namespace TheISA;
-    if (isBAR(req->paddr, 0))
-        return readBar0(req, req->paddr - BARAddrs[0], data);
-    if (isBAR(req->paddr, 1))
-        return readBar1(req, req->paddr - BARAddrs[1], data);
-    if (isBAR(req->paddr, 2))
-        return readBar2(req, req->paddr - BARAddrs[2], data);
-    if (isBAR(req->paddr, 3))
-        return readBar3(req, req->paddr - BARAddrs[3], data);
-    if (isBAR(req->paddr, 4))
-        return readBar4(req, req->paddr - BARAddrs[4], data);
-    if (isBAR(req->paddr, 5))
-        return readBar5(req, req->paddr - BARAddrs[5], data);
-    return genMachineCheckFault();
-}
-
-inline Fault
-PciDev::writeBar(MemReqPtr &req, const uint8_t *data)
-{
-    using namespace TheISA;
-    if (isBAR(req->paddr, 0))
-        return writeBar0(req, req->paddr - BARAddrs[0], data);
-    if (isBAR(req->paddr, 1))
-        return writeBar1(req, req->paddr - BARAddrs[1], data);
-    if (isBAR(req->paddr, 2))
-        return writeBar2(req, req->paddr - BARAddrs[2], data);
-    if (isBAR(req->paddr, 3))
-        return writeBar3(req, req->paddr - BARAddrs[3], data);
-    if (isBAR(req->paddr, 4))
-        return writeBar4(req, req->paddr - BARAddrs[4], data);
-    if (isBAR(req->paddr, 5))
-        return writeBar5(req, req->paddr - BARAddrs[5], data);
-    return genMachineCheckFault();
-}
-
 #endif // __DEV_PCIDEV_HH__
index 5e84beb838608f54bd6deba7cb6bd381cad9ecae..86e834894f214279dbd1a637d1e9c2891386f6b3 100644 (file)
@@ -97,21 +97,30 @@ Bus::recvStatusChange(Port::Status status, int id)
     Port *port = interfaces[id];
     AddrRangeList ranges;
     AddrRangeList snoops;
+    AddrRangeIter iter;
+    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);
 
     // not dealing with snooping yet either
     assert(snoops.size() == 0);
-    // or multiple ranges
-    assert(ranges.size() == 1);
-
-    DevMap dm;
-    dm.portId = id;
-    dm.range = ranges.front();
-
-    DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start,
-            dm.range.end, id);
-    portList.push_back(dm);
+    for(iter = ranges.begin(); iter != ranges.end(); iter++) {
+        DevMap dm;
+        dm.portId = id;
+        dm.range = *iter;
+
+        DPRINTF(MMU, "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());
 }
 
index 843d34ac0d2c4e0f83764d0a58632fdaabda2f98..79fe0ea06d3031c32a0144d552284110c52c5574 100644 (file)
@@ -92,7 +92,7 @@ struct Packet
                            // assert(dynamic_cast<Foo>) etc.
 
     /** A virtual base opaque structure used to hold the senders state. */
-    SenderState *senderState; // virtual base opaque,
+    void *senderState; // virtual base opaque,
                            // assert(dynamic_cast<Foo>) etc.
 
     /** A pointer to the data being transfered.  It can be differnt sizes
index b00935990d28486c26581805aadd02e9fd452605..a15a59106d402a2685aea948c4a510010aa9cdca 100644 (file)
@@ -69,8 +69,8 @@ PhysicalMemory::MemResponseEvent::description()
     return "Physical Memory Timing Access respnse event";
 }
 
-PhysicalMemory::PhysicalMemory(const string &n)
-    : MemObject(n), base_addr(0), pmem_addr(NULL), port(NULL)
+PhysicalMemory::PhysicalMemory(const string &n, Tick latency)
+    : MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency)
 {
     // Hardcoded to 128 MB for now.
     pmem_size = 1 << 27;
@@ -137,6 +137,7 @@ Tick
 PhysicalMemory::doAtomicAccess(Packet &pkt)
 {
     doFunctionalAccess(pkt);
+    pkt.time = curTick + lat;
     return curTick + lat;
 }
 
@@ -344,20 +345,22 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
 
     Param<string> file;
     Param<Range<Addr> > range;
+    Param<Tick> latency;
 
 END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
 
     INIT_PARAM_DFLT(file, "memory mapped file", ""),
-    INIT_PARAM(range, "Device Address Range")
+    INIT_PARAM(range, "Device Address Range"),
+    INIT_PARAM(latency, "Memory access latency")
 
 END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
 
 CREATE_SIM_OBJECT(PhysicalMemory)
 {
 
-    return new PhysicalMemory(getInstanceName());
+    return new PhysicalMemory(getInstanceName(), latency);
 }
 
 REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory)
index ce0a2099c4f68e42ef14a85beac51d8d94ae8858..f87683c45ec2a0f7926d69981266af273fcfb4c3 100644 (file)
@@ -71,7 +71,6 @@ class PhysicalMemory : public MemObject
 
     int numPorts;
 
-    int lat;
 
     struct MemResponseEvent : public Event
     {
@@ -94,13 +93,14 @@ class PhysicalMemory : public MemObject
     uint8_t *pmem_addr;
     MemoryPort *port;
     int page_ptr;
+    Tick lat;
 
   public:
     Addr new_page();
     uint64_t size() { return pmem_size; }
 
   public:
-    PhysicalMemory(const std::string &n);
+    PhysicalMemory(const std::string &n, Tick latency);
     virtual ~PhysicalMemory();
 
   public:
index cda3b182480a4f238a7ebb5f2747d3a07e1061f1..2a71bbc6509ca0e61c6555d55bdef6555fa84b93 100644 (file)
@@ -12,3 +12,7 @@ class BasicPioDevice(PioDevice):
     abstract = True
     pio_addr = Param.Addr("Device Address")
     pio_latency = Param.Tick(1, "Programmed IO latency in simticks")
+
+class DmaDevice(PioDevice):
+    type = 'DmaDevice'
+    abstract = True
index 6855ec65343b1800307bc5b88daeed2a5970c85d..2403e6d36909945f939dd24516d2d7660dece639 100644 (file)
@@ -8,7 +8,6 @@ class IdeDisk(SimObject):
     delay = Param.Latency('1us', "Fixed disk delay in microseconds")
     driveID = Param.IdeID('master', "Drive ID")
     image = Param.DiskImage("Disk image")
-    physmem = Param.PhysicalMemory(Parent.any, "Physical memory")
 
 class IdeController(PciDevice):
     type = 'IdeController'
index f2ccce09f21c7ef8665855684ffdf451da3812fe..85cefcd4429b7dc92ab34ccfc846e41eb3e43daf 100644 (file)
@@ -1,6 +1,5 @@
 from m5 import *
-from Device import BasicPioDevice
-#, DmaDevice
+from Device import BasicPioDevice, DmaDevice
 
 class PciConfigData(SimObject):
     type = 'PciConfigData'
@@ -42,15 +41,15 @@ class PciConfigData(SimObject):
 class PciConfigAll(BasicPioDevice):
     type = 'PciConfigAll'
 
-#class PciDevice(DmaDevice):
-#    type = 'PciDevice'
-#    abstract = True
-#    addr = 0xffffffffL
-#    pci_bus = Param.Int("PCI bus")
-#    pci_dev = Param.Int("PCI device number")
-#    pci_func = Param.Int("PCI function code")
-#    configdata = Param.PciConfigData(Parent.any, "PCI Config data")
-#    configspace = Param.PciConfigAll(Parent.any, "PCI Configspace")
-#
-#class PciFake(PciDevice):
-#    type = 'PciFake'
+class PciDevice(DmaDevice):
+    type = 'PciDevice'
+    abstract = True
+    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'
index b69c969cb94c666243217359866a89a3da50dbf3..e59e94e9be6930cb40afca0907c22643e9b287de 100644 (file)
@@ -1,7 +1,8 @@
 from m5 import *
-from Memory import Memory
+from MemObject import *
 
-class PhysicalMemory(Memory):
+class PhysicalMemory(MemObject):
     type = 'PhysicalMemory'
     range = Param.AddrRange("Device Address")
     file = Param.String('', "memory mapped file")
+    latency = Param.Latency('10ns', "latency of an access")
index 0dd0ba827cf1950d2fc958c994ca9725005e6b99..a8c5da9d7661f679a8a7a2455abb82a138d636a1 100644 (file)
 // This lets us figure out what the byte order of the host system is
 #if defined(linux)
 #include <endian.h>
+// If this is a linux system, lets used the optimized definitions if they exist.
+// If one doesn't exist, we pretty much get what is listed below, so it all
+// works out
+#include <byteswap.h>
 #else
 #include <machine/endian.h>
 #endif
@@ -47,6 +51,9 @@
 static inline uint64_t
 swap_byte64(uint64_t x)
 {
+#if defined(linux)
+    return bswap_64(x);
+#else
     return  (uint64_t)((((uint64_t)(x) & 0xff) << 56) |
             ((uint64_t)(x) & 0xff00ULL) << 40 |
             ((uint64_t)(x) & 0xff0000ULL) << 24 |
@@ -55,22 +62,30 @@ swap_byte64(uint64_t x)
             ((uint64_t)(x) & 0xff0000000000ULL) >> 24 |
             ((uint64_t)(x) & 0xff000000000000ULL) >> 40 |
             ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ;
+#endif
 }
 
 static inline uint32_t
 swap_byte32(uint32_t x)
 {
+#if defined(linux)
+    return bswap_32(x);
+#else
     return  (uint32_t)(((uint32_t)(x) & 0xff) << 24 |
             ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 |
             ((uint32_t)(x) & 0xff000000) >> 24);
-
+#endif
 }
 
 static inline uint16_t
 swap_byte16(uint16_t x)
 {
+#if defined(linux)
+    return bswap_16(x);
+#else
     return (uint16_t)(((uint16_t)(x) & 0xff) << 8 |
                       ((uint16_t)(x) & 0xff00) >> 8);
+#endif
 }
 
 //This lets the compiler figure out how to call the swap_byte functions above