Fixes in translation in PCI to DMA address to fix boot problems with
Linux 2.6 with DMA support dev/ide_disk.cc: Add debug infomation for DMA transfers and fix handling of PRD pointer values dev/ide_disk.hh: Reduce buffer (MAX_DMA) size to 64K dev/tsunami_pchip.cc: dev/tsunami_pchip.hh: Add handling of PCTL register and also fix the translate from PCI to DMA addresses which was incorrect --HG-- extra : convert_revision : 562f55fa1c7099ad0f5a23f59dec2c8ec7601d43
This commit is contained in:
parent
44a2a2336e
commit
0408051f20
4 changed files with 46 additions and 15 deletions
|
@ -330,7 +330,13 @@ IdeDisk::dmaPrdReadDone()
|
||||||
physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
|
physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
|
||||||
sizeof(PrdEntry_t));
|
sizeof(PrdEntry_t));
|
||||||
|
|
||||||
curPrdAddr += sizeof(PrdEntry_t);
|
DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
|
||||||
|
curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
|
||||||
|
curPrd.getByteCount(), (cmdBytesLeft/SectorSize),
|
||||||
|
curPrd.getEOT(), curSector);
|
||||||
|
|
||||||
|
// make sure the new curPrdAddr is properly translated from PCI to system
|
||||||
|
curPrdAddr = pciToDma(curPrdAddr + sizeof(PrdEntry_t));
|
||||||
|
|
||||||
if (dmaRead)
|
if (dmaRead)
|
||||||
doDmaRead();
|
doDmaRead();
|
||||||
|
@ -613,7 +619,8 @@ IdeDisk::startDma(const uint32_t &prdTableBase)
|
||||||
if (devState != Transfer_Data_Dma)
|
if (devState != Transfer_Data_Dma)
|
||||||
panic("Inconsistent device state for DMA start!\n");
|
panic("Inconsistent device state for DMA start!\n");
|
||||||
|
|
||||||
curPrdAddr = pciToDma((Addr)prdTableBase);
|
// PRD base address is given by bits 31:2
|
||||||
|
curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3)));
|
||||||
|
|
||||||
dmaState = Dma_Transfer;
|
dmaState = Dma_Transfer;
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
|
|
||||||
#define DMA_BACKOFF_PERIOD 200
|
#define DMA_BACKOFF_PERIOD 200
|
||||||
|
|
||||||
#define MAX_DMA_SIZE (131072) // 256 * SectorSize (512)
|
#define MAX_DMA_SIZE (65536) // 64K
|
||||||
#define MAX_MULTSECT (128)
|
#define MAX_MULTSECT (128)
|
||||||
|
|
||||||
#define PRD_BASE_MASK 0xfffffffe
|
#define PRD_BASE_MASK 0xfffffffe
|
||||||
#define PRD_COUNT_MASK 0xfffe
|
#define PRD_COUNT_MASK 0xfffe
|
||||||
|
@ -62,7 +62,7 @@ class PrdTableEntry {
|
||||||
return (entry.baseAddr & PRD_BASE_MASK);
|
return (entry.baseAddr & PRD_BASE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getByteCount()
|
uint32_t getByteCount()
|
||||||
{
|
{
|
||||||
return ((entry.byteCount == 0) ? MAX_DMA_SIZE :
|
return ((entry.byteCount == 0) ? MAX_DMA_SIZE :
|
||||||
(entry.byteCount & PRD_COUNT_MASK));
|
(entry.byteCount & PRD_COUNT_MASK));
|
||||||
|
|
|
@ -36,6 +36,9 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
||||||
tba[i] = 0;
|
tba[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize pchip control register
|
||||||
|
pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);
|
||||||
|
|
||||||
//Set back pointer in tsunami
|
//Set back pointer in tsunami
|
||||||
tsunami->pchip = this;
|
tsunami->pchip = this;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +92,7 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
|
||||||
*(uint64_t*)data = tba[3];
|
*(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??
|
*(uint64_t*)data = pctl;
|
||||||
*(uint64_t*)data = 0x00; // try this
|
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
|
@ -177,8 +179,7 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
|
||||||
tba[3] = *(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??
|
pctl = *(uint64_t*)data;
|
||||||
//*(uint64_t*)data; // try this
|
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
|
@ -233,12 +234,29 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||||
Addr pteAddr;
|
Addr pteAddr;
|
||||||
Addr dmaAddr;
|
Addr dmaAddr;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n",
|
||||||
|
i, wsba[i], wsm[i]);
|
||||||
|
|
||||||
windowBase = wsba[i];
|
windowBase = wsba[i];
|
||||||
windowMask = ~wsm[i] & (0x7ff << 20);
|
windowMask = ~wsm[i] & (ULL(0xfff) << 20);
|
||||||
|
|
||||||
if ((busAddr & windowMask) == (windowBase & windowMask)) {
|
if ((busAddr & windowMask) == (windowBase & windowMask)) {
|
||||||
|
DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n",
|
||||||
|
i, windowBase, windowMask, (busAddr & windowMask),
|
||||||
|
(windowBase & windowMask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
||||||
|
windowBase = wsba[i];
|
||||||
|
windowMask = ~wsm[i] & (ULL(0xfff) << 20);
|
||||||
|
|
||||||
|
if ((busAddr & windowMask) == (windowBase & windowMask)) {
|
||||||
|
|
||||||
if (wsba[i] & 0x1) { // see if enabled
|
if (wsba[i] & 0x1) { // see if enabled
|
||||||
if (wsba[i] & 0x2) { // see if SG bit is set
|
if (wsba[i] & 0x2) { // see if SG bit is set
|
||||||
|
@ -252,8 +270,8 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||||
to create an address for the SG page
|
to create an address for the SG page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tbaMask = ~(((wsm[i] & (0x7ff << 20)) >> 10) | 0x3ff);
|
tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff));
|
||||||
baMask = (wsm[i] & (0x7ff << 20)) | (0x7f << 13);
|
baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
|
||||||
pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
|
pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
|
||||||
|
|
||||||
memcpy((void *)&pteEntry,
|
memcpy((void *)&pteEntry,
|
||||||
|
@ -261,10 +279,10 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||||
physmem->dma_addr(pteAddr, sizeof(uint64_t)),
|
physmem->dma_addr(pteAddr, sizeof(uint64_t)),
|
||||||
sizeof(uint64_t));
|
sizeof(uint64_t));
|
||||||
|
|
||||||
dmaAddr = ((pteEntry & ~0x1) << 12) | (busAddr & 0x1fff);
|
dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
baMask = (wsm[i] & (0x7ff << 20)) | 0xfffff;
|
baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff);
|
||||||
tbaMask = ~baMask;
|
tbaMask = ~baMask;
|
||||||
dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
|
dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
|
||||||
}
|
}
|
||||||
|
@ -274,12 +292,14 @@ TsunamiPChip::translatePciToDma(Addr busAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// if no match was found, then return the original address
|
||||||
|
return busAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TsunamiPChip::serialize(std::ostream &os)
|
TsunamiPChip::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
|
SERIALIZE_SCALAR(pctl);
|
||||||
SERIALIZE_ARRAY(wsba, 4);
|
SERIALIZE_ARRAY(wsba, 4);
|
||||||
SERIALIZE_ARRAY(wsm, 4);
|
SERIALIZE_ARRAY(wsm, 4);
|
||||||
SERIALIZE_ARRAY(tba, 4);
|
SERIALIZE_ARRAY(tba, 4);
|
||||||
|
@ -288,6 +308,7 @@ TsunamiPChip::serialize(std::ostream &os)
|
||||||
void
|
void
|
||||||
TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion)
|
TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
|
UNSERIALIZE_SCALAR(pctl);
|
||||||
UNSERIALIZE_ARRAY(wsba, 4);
|
UNSERIALIZE_ARRAY(wsba, 4);
|
||||||
UNSERIALIZE_ARRAY(wsm, 4);
|
UNSERIALIZE_ARRAY(wsm, 4);
|
||||||
UNSERIALIZE_ARRAY(tba, 4);
|
UNSERIALIZE_ARRAY(tba, 4);
|
||||||
|
|
|
@ -56,6 +56,9 @@ class TsunamiPChip : public FunctionalMemory
|
||||||
*/
|
*/
|
||||||
Tsunami *tsunami;
|
Tsunami *tsunami;
|
||||||
|
|
||||||
|
/** Pchip control register */
|
||||||
|
uint64_t pctl;
|
||||||
|
|
||||||
/** Window Base addresses */
|
/** Window Base addresses */
|
||||||
uint64_t wsba[4];
|
uint64_t wsba[4];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue