Added initial (hackish) support for translating between a PCI bus address
and a physical memory address for DMA dev/tsunami_pchip.cc: dev/tsunami_pchip.hh: Changed registers to array and added mapping function to translate between PCI bus space and physical address space --HG-- extra : convert_revision : e9dc4de4e7effe8e8e2365298843d6f767b5a289
This commit is contained in:
parent
7f069e7bdb
commit
43787ad863
2 changed files with 71 additions and 75 deletions
|
@ -29,18 +29,11 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
|||
{
|
||||
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
||||
|
||||
wsba0 = 0;
|
||||
wsba1 = 0;
|
||||
wsba2 = 0;
|
||||
wsba3 = 0;
|
||||
wsm0 = 0;
|
||||
wsm1 = 0;
|
||||
wsm2 = 0;
|
||||
wsm3 = 0;
|
||||
tba0 = 0;
|
||||
tba1 = 0;
|
||||
tba2 = 0;
|
||||
tba3 = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wsba[i] = 0;
|
||||
wsm[i] = 0;
|
||||
tba[i] = 0;
|
||||
}
|
||||
|
||||
//Set back pointer in tsunami
|
||||
tsunami->pchip = this;
|
||||
|
@ -61,40 +54,40 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
|
|||
case sizeof(uint64_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_PC_WSBA0:
|
||||
*(uint64_t*)data = wsba0;
|
||||
*(uint64_t*)data = wsba[0];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA1:
|
||||
*(uint64_t*)data = wsba1;
|
||||
*(uint64_t*)data = wsba[1];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA2:
|
||||
*(uint64_t*)data = wsba2;
|
||||
*(uint64_t*)data = wsba[2];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA3:
|
||||
*(uint64_t*)data = wsba3;
|
||||
*(uint64_t*)data = wsba[3];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM0:
|
||||
*(uint64_t*)data = wsm0;
|
||||
*(uint64_t*)data = wsm[0];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM1:
|
||||
*(uint64_t*)data = wsm1;
|
||||
*(uint64_t*)data = wsm[1];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM2:
|
||||
*(uint64_t*)data = wsm2;
|
||||
*(uint64_t*)data = wsm[2];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM3:
|
||||
*(uint64_t*)data = wsm3;
|
||||
*(uint64_t*)data = wsm[3];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA0:
|
||||
*(uint64_t*)data = tba0;
|
||||
*(uint64_t*)data = tba[0];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA1:
|
||||
*(uint64_t*)data = tba1;
|
||||
*(uint64_t*)data = tba[1];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA2:
|
||||
*(uint64_t*)data = tba2;
|
||||
*(uint64_t*)data = tba[2];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA3:
|
||||
*(uint64_t*)data = tba3;
|
||||
*(uint64_t*)data = tba[3];
|
||||
return No_Fault;
|
||||
case TSDEV_PC_PCTL:
|
||||
// might want to change the clock??
|
||||
|
@ -149,40 +142,40 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
case sizeof(uint64_t):
|
||||
switch(daddr) {
|
||||
case TSDEV_PC_WSBA0:
|
||||
wsba0 = *(uint64_t*)data;
|
||||
wsba[0] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA1:
|
||||
wsba1 = *(uint64_t*)data;
|
||||
wsba[1] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA2:
|
||||
wsba2 = *(uint64_t*)data;
|
||||
wsba[2] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSBA3:
|
||||
wsba3 = *(uint64_t*)data;
|
||||
wsba[3] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM0:
|
||||
wsm0 = *(uint64_t*)data;
|
||||
wsm[0] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM1:
|
||||
wsm1 = *(uint64_t*)data;
|
||||
wsm[1] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM2:
|
||||
wsm2 = *(uint64_t*)data;
|
||||
wsm[2] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_WSM3:
|
||||
wsm3 = *(uint64_t*)data;
|
||||
wsm[3] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA0:
|
||||
tba0 = *(uint64_t*)data;
|
||||
tba[0] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA1:
|
||||
tba1 = *(uint64_t*)data;
|
||||
tba[1] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA2:
|
||||
tba2 = *(uint64_t*)data;
|
||||
tba[2] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_TBA3:
|
||||
tba3 = *(uint64_t*)data;
|
||||
tba[3] = *(uint64_t*)data;
|
||||
return No_Fault;
|
||||
case TSDEV_PC_PCTL:
|
||||
// might want to change the clock??
|
||||
|
@ -224,40 +217,49 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
|||
return No_Fault;
|
||||
}
|
||||
|
||||
Addr
|
||||
TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||
{
|
||||
// compare the address to the window base registers
|
||||
uint64_t windowMask = 0;
|
||||
uint64_t windowBase = 0;
|
||||
Addr dmaAddr;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
windowBase = wsba[i];
|
||||
windowMask = ~wsm[i] & (0x7ff << 20);
|
||||
|
||||
if ((busAddr & windowMask) == (windowBase & windowMask)) {
|
||||
windowMask = (wsm[i] & (0x7ff << 20)) | 0xfffff;
|
||||
|
||||
if (wsba[i] & 0x1) { // see if enabled
|
||||
if (wsba[i] & 0x2) // see if SG bit is set
|
||||
panic("PCI to system SG mapping not currently implemented!\n");
|
||||
else
|
||||
dmaAddr = (tba[i] & ~windowMask) | (busAddr & windowMask);
|
||||
|
||||
return dmaAddr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TsunamiPChip::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(wsba0);
|
||||
SERIALIZE_SCALAR(wsba1);
|
||||
SERIALIZE_SCALAR(wsba2);
|
||||
SERIALIZE_SCALAR(wsba3);
|
||||
SERIALIZE_SCALAR(wsm0);
|
||||
SERIALIZE_SCALAR(wsm1);
|
||||
SERIALIZE_SCALAR(wsm2);
|
||||
SERIALIZE_SCALAR(wsm3);
|
||||
SERIALIZE_SCALAR(tba0);
|
||||
SERIALIZE_SCALAR(tba1);
|
||||
SERIALIZE_SCALAR(tba2);
|
||||
SERIALIZE_SCALAR(tba3);
|
||||
|
||||
SERIALIZE_ARRAY(wsba, 4);
|
||||
SERIALIZE_ARRAY(wsm, 4);
|
||||
SERIALIZE_ARRAY(tba, 4);
|
||||
}
|
||||
|
||||
void
|
||||
TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(wsba0);
|
||||
UNSERIALIZE_SCALAR(wsba1);
|
||||
UNSERIALIZE_SCALAR(wsba2);
|
||||
UNSERIALIZE_SCALAR(wsba3);
|
||||
UNSERIALIZE_SCALAR(wsm0);
|
||||
UNSERIALIZE_SCALAR(wsm1);
|
||||
UNSERIALIZE_SCALAR(wsm2);
|
||||
UNSERIALIZE_SCALAR(wsm3);
|
||||
UNSERIALIZE_SCALAR(tba0);
|
||||
UNSERIALIZE_SCALAR(tba1);
|
||||
UNSERIALIZE_SCALAR(tba2);
|
||||
UNSERIALIZE_SCALAR(tba3);
|
||||
|
||||
UNSERIALIZE_ARRAY(wsba, 4);
|
||||
UNSERIALIZE_ARRAY(wsm, 4);
|
||||
UNSERIALIZE_ARRAY(tba, 4);
|
||||
}
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||
|
|
|
@ -48,24 +48,18 @@ class TsunamiPChip : public FunctionalMemory
|
|||
protected:
|
||||
Tsunami *tsunami;
|
||||
|
||||
uint64_t wsba0;
|
||||
uint64_t wsba1;
|
||||
uint64_t wsba2;
|
||||
uint64_t wsba3;
|
||||
uint64_t wsm0;
|
||||
uint64_t wsm1;
|
||||
uint64_t wsm2;
|
||||
uint64_t wsm3;
|
||||
uint64_t tba0;
|
||||
uint64_t tba1;
|
||||
uint64_t tba2;
|
||||
uint64_t tba3;
|
||||
|
||||
uint64_t wsba[4];
|
||||
uint64_t wsm[4];
|
||||
uint64_t tba[4];
|
||||
|
||||
public:
|
||||
TsunamiPChip(const std::string &name, Tsunami *t, Addr a,
|
||||
MemoryController *mmu);
|
||||
|
||||
// @todo This hack does a quick and dirty translation of the PCI bus address to
|
||||
// a valid DMA address. This is described in 10-10 of the Tsunami book, should be fixed
|
||||
Addr translatePciToDma(Addr busAddr);
|
||||
|
||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
||||
|
||||
|
|
Loading…
Reference in a new issue