Add the capability to iterate through the packets in a pktfifo,
[gem5.git] / dev / pcidev.hh
index 14f183e2891fe3bd2e3b4158450fcf04bfd9adb7..efc805b3f3c7d5956c3c5a4a3f53d02da0ae2655 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 The Regents of The University of Michigan
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "dev/pcireg.h"
 #include "dev/platform.hh"
 
+#define BAR_IO_MASK 0x3
+#define BAR_MEM_MASK 0xF
+#define BAR_IO_SPACE_BIT 0x1
+#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
+#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
+
 class PciConfigAll;
 class MemoryController;
 
@@ -115,7 +121,7 @@ class PciDev : public DmaDevice
 
   protected:
     /** The current config space. Unlike the PciConfigData this is
-     * updated during simulation while continues to refelect what was
+     * updated during simulation while continues to reflect what was
      * in the config file.
      */
     PCIConfig config;
@@ -126,6 +132,35 @@ class PciDev : public DmaDevice
     /** The current address mapping of the BARs */
     Addr BARAddrs[6];
 
+    bool
+    isBAR(Addr addr, int bar) const
+    {
+        assert(bar >= 0 && bar < 6);
+        return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar];
+    }
+
+    int
+    getBAR(Addr addr)
+    {
+        for (int i = 0; i <= 5; ++i)
+            if (isBAR(addr, i))
+                return i;
+
+        return -1;
+    }
+
+    bool
+    getBAR(Addr paddr, Addr &daddr, int &bar)
+    {
+        int b = getBAR(paddr);
+        if (b < 0)
+            return false;
+
+        daddr = paddr - BARAddrs[b];
+        bar = b;
+        return true;
+    }
+
   protected:
     Platform *plat;
     PciConfigData *configData;
@@ -136,15 +171,15 @@ class PciDev : public DmaDevice
 
     void
     intrPost()
-    { plat->postPciInt(configData->config.hdr.pci0.interruptLine); }
+    { plat->postPciInt(configData->config.interruptLine); }
 
     void
     intrClear()
-    { plat->clearPciInt(configData->config.hdr.pci0.interruptLine); }
+    { plat->clearPciInt(configData->config.interruptLine); }
 
     uint8_t
     interruptLine()
-    { return configData->config.hdr.pci0.interruptLine; }
+    { return configData->config.interruptLine; }
 
   public:
     /**
@@ -154,13 +189,39 @@ class PciDev : public DmaDevice
      */
     PciDev(Params *params);
 
-    virtual Fault read(MemReqPtr &req, uint8_t *data) {
-        return No_Fault;
-    }
-    virtual Fault write(MemReqPtr &req, const uint8_t *data) {
-        return No_Fault;
-    }
+    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
@@ -169,7 +230,7 @@ class PciDev : public DmaDevice
      * @param size the size of the write
      * @param data the data to write
      */
-    virtual void WriteConfig(int offset, int size, uint32_t data);
+    virtual void writeConfig(int offset, int size, const uint8_t* data);
 
 
     /**
@@ -180,7 +241,7 @@ 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, int size, uint8_t *data);
 
     /**
      * Serialize this object to the given output stream.
@@ -196,4 +257,40 @@ class PciDev : public DmaDevice
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 };
 
+inline Fault
+PciDev::readBar(MemReqPtr &req, uint8_t *data)
+{
+    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 Machine_Check_Fault;
+}
+
+inline Fault
+PciDev::writeBar(MemReqPtr &req, const uint8_t *data)
+{
+    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 Machine_Check_Fault;
+}
+
 #endif // __DEV_PCIDEV_HH__