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));
|
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
||||||
|
|
||||||
wsba0 = 0;
|
for (int i = 0; i < 4; i++) {
|
||||||
wsba1 = 0;
|
wsba[i] = 0;
|
||||||
wsba2 = 0;
|
wsm[i] = 0;
|
||||||
wsba3 = 0;
|
tba[i] = 0;
|
||||||
wsm0 = 0;
|
}
|
||||||
wsm1 = 0;
|
|
||||||
wsm2 = 0;
|
|
||||||
wsm3 = 0;
|
|
||||||
tba0 = 0;
|
|
||||||
tba1 = 0;
|
|
||||||
tba2 = 0;
|
|
||||||
tba3 = 0;
|
|
||||||
|
|
||||||
//Set back pointer in tsunami
|
//Set back pointer in tsunami
|
||||||
tsunami->pchip = this;
|
tsunami->pchip = this;
|
||||||
|
@ -61,40 +54,40 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
|
||||||
case sizeof(uint64_t):
|
case sizeof(uint64_t):
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
*(uint64_t*)data = wsba0;
|
*(uint64_t*)data = wsba[0];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
*(uint64_t*)data = wsba1;
|
*(uint64_t*)data = wsba[1];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
*(uint64_t*)data = wsba2;
|
*(uint64_t*)data = wsba[2];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
*(uint64_t*)data = wsba3;
|
*(uint64_t*)data = wsba[3];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
*(uint64_t*)data = wsm0;
|
*(uint64_t*)data = wsm[0];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
*(uint64_t*)data = wsm1;
|
*(uint64_t*)data = wsm[1];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
*(uint64_t*)data = wsm2;
|
*(uint64_t*)data = wsm[2];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
*(uint64_t*)data = wsm3;
|
*(uint64_t*)data = wsm[3];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
*(uint64_t*)data = tba0;
|
*(uint64_t*)data = tba[0];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
*(uint64_t*)data = tba1;
|
*(uint64_t*)data = tba[1];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
*(uint64_t*)data = tba2;
|
*(uint64_t*)data = tba[2];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA3:
|
case TSDEV_PC_TBA3:
|
||||||
*(uint64_t*)data = tba3;
|
*(uint64_t*)data = tba[3];
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
// might want to change the clock??
|
// might want to change the clock??
|
||||||
|
@ -149,40 +142,40 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
||||||
case sizeof(uint64_t):
|
case sizeof(uint64_t):
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
wsba0 = *(uint64_t*)data;
|
wsba[0] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
wsba1 = *(uint64_t*)data;
|
wsba[1] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
wsba2 = *(uint64_t*)data;
|
wsba[2] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
wsba3 = *(uint64_t*)data;
|
wsba[3] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
wsm0 = *(uint64_t*)data;
|
wsm[0] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
wsm1 = *(uint64_t*)data;
|
wsm[1] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
wsm2 = *(uint64_t*)data;
|
wsm[2] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
wsm3 = *(uint64_t*)data;
|
wsm[3] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
tba0 = *(uint64_t*)data;
|
tba[0] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
tba1 = *(uint64_t*)data;
|
tba[1] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
tba2 = *(uint64_t*)data;
|
tba[2] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_TBA3:
|
case TSDEV_PC_TBA3:
|
||||||
tba3 = *(uint64_t*)data;
|
tba[3] = *(uint64_t*)data;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
// might want to change the clock??
|
// might want to change the clock??
|
||||||
|
@ -224,40 +217,49 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
||||||
return No_Fault;
|
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
|
void
|
||||||
TsunamiPChip::serialize(std::ostream &os)
|
TsunamiPChip::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
SERIALIZE_SCALAR(wsba0);
|
SERIALIZE_ARRAY(wsba, 4);
|
||||||
SERIALIZE_SCALAR(wsba1);
|
SERIALIZE_ARRAY(wsm, 4);
|
||||||
SERIALIZE_SCALAR(wsba2);
|
SERIALIZE_ARRAY(tba, 4);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion)
|
TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
UNSERIALIZE_SCALAR(wsba0);
|
UNSERIALIZE_ARRAY(wsba, 4);
|
||||||
UNSERIALIZE_SCALAR(wsba1);
|
UNSERIALIZE_ARRAY(wsm, 4);
|
||||||
UNSERIALIZE_SCALAR(wsba2);
|
UNSERIALIZE_ARRAY(tba, 4);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
|
||||||
|
|
|
@ -48,24 +48,18 @@ class TsunamiPChip : public FunctionalMemory
|
||||||
protected:
|
protected:
|
||||||
Tsunami *tsunami;
|
Tsunami *tsunami;
|
||||||
|
|
||||||
uint64_t wsba0;
|
uint64_t wsba[4];
|
||||||
uint64_t wsba1;
|
uint64_t wsm[4];
|
||||||
uint64_t wsba2;
|
uint64_t tba[4];
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TsunamiPChip(const std::string &name, Tsunami *t, Addr a,
|
TsunamiPChip(const std::string &name, Tsunami *t, Addr a,
|
||||||
MemoryController *mmu);
|
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 read(MemReqPtr &req, uint8_t *data);
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue