Add a bunch of functions to manage the BAR addresses. This
authorNathan Binkert <binkertn@umich.edu>
Mon, 21 Nov 2005 05:38:53 +0000 (00:38 -0500)
committerNathan Binkert <binkertn@umich.edu>
Mon, 21 Nov 2005 05:38:53 +0000 (00:38 -0500)
makes it easier to implement PCI device models.

dev/pcidev.cc:
    default implementations for read/write and readBarX/writeBarX functions

--HG--
extra : convert_revision : bbe2e2a2a506e2dd94d98f8e0feaefef96380be9

dev/pcidev.cc
dev/pcidev.hh

index dd83b2e21920d63609b2c95a0c1fc3e98210ebaf..1d9ea137dc0d1d7150815ee6f3a6d69484198dee 100644 (file)
@@ -70,6 +70,62 @@ PciDev::PciDev(Params *p)
         p->configSpace->registerDevice(p->deviceNum, p->functionNum, this);
 }
 
+Fault
+PciDev::read(MemReqPtr &req, uint8_t *data)
+{ return No_Fault; }
+
+Fault
+PciDev::write(MemReqPtr &req, const uint8_t *data)
+{ return No_Fault; }
+
+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"); }
+
+Fault
+PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
+Fault
+PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data)
+{ panic("not implemented"); }
+
 void
 PciDev::readConfig(int offset, int size, uint8_t *data)
 {
index 433079b614a863eb2ee4b2cda58368c5c284ff8d..efc805b3f3c7d5956c3c5a4a3f53d02da0ae2655 100644 (file)
@@ -132,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;
@@ -160,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
@@ -202,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__