Add a bunch of functions to manage the BAR addresses. This
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
This commit is contained in:
parent
d3a4781ac5
commit
48863a1a43
2 changed files with 153 additions and 6 deletions
|
@ -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)
|
||||
{
|
||||
|
|
103
dev/pcidev.hh
103
dev/pcidev.hh
|
@ -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 §ion);
|
||||
};
|
||||
|
||||
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__
|
||||
|
|
Loading…
Reference in a new issue