IDE: Fix issues with new PIIX kernel driver and our model.
The driver can read the IDE config register as a 32 bit register since some adapters use bit 18 as a disable channel bit. If the size isn't set in a PRD it should be 64K according to the SPEC (and driver) not 128K.
This commit is contained in:
parent
999cd8aef5
commit
243223ae63
3 changed files with 27 additions and 8 deletions
|
@ -211,6 +211,9 @@ IdeController::readConfig(PacketPtr pkt)
|
|||
(uint32_t)pkt->get<uint16_t>());
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
if (offset == IDEConfig)
|
||||
pkt->set<uint32_t>(ideConfig);
|
||||
else
|
||||
panic("No 32bit reads implemented for this device.");
|
||||
DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset,
|
||||
(uint32_t)pkt->get<uint32_t>());
|
||||
|
@ -275,6 +278,9 @@ IdeController::writeConfig(PacketPtr pkt)
|
|||
offset, (uint32_t)pkt->get<uint16_t>());
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
if (offset == IDEConfig)
|
||||
ideConfig = pkt->get<uint32_t>();
|
||||
else
|
||||
panic("Write of unimplemented PCI config. register: %x\n", offset);
|
||||
break;
|
||||
default:
|
||||
|
@ -312,6 +318,7 @@ IdeController::writeConfig(PacketPtr pkt)
|
|||
break;
|
||||
|
||||
case PCI_COMMAND:
|
||||
DPRINTF(IdeCtrl, "Writing to PCI Command val: %#x\n", config.command);
|
||||
ioEnabled = (config.command & htole(PCI_CMD_IOSE));
|
||||
bmEnabled = (config.command & htole(PCI_CMD_BME));
|
||||
break;
|
||||
|
|
|
@ -334,6 +334,7 @@ IdeDisk::doDmaTransfer()
|
|||
void
|
||||
IdeDisk::dmaPrdReadDone()
|
||||
{
|
||||
|
||||
DPRINTF(IdeDisk,
|
||||
"PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
|
||||
curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
|
||||
|
@ -465,6 +466,8 @@ IdeDisk::doDmaDataWrite()
|
|||
bytesRead += SectorSize;
|
||||
cmdBytesLeft -= SectorSize;
|
||||
}
|
||||
DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
|
||||
bytesRead, cmdBytesLeft);
|
||||
|
||||
schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
|
||||
}
|
||||
|
@ -472,7 +475,7 @@ IdeDisk::doDmaDataWrite()
|
|||
void
|
||||
IdeDisk::doDmaWrite()
|
||||
{
|
||||
|
||||
DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
|
||||
if (!dmaWriteCG) {
|
||||
// clear out the data buffer
|
||||
dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(),
|
||||
|
@ -480,17 +483,22 @@ IdeDisk::doDmaWrite()
|
|||
}
|
||||
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
|
||||
schedule(dmaWriteWaitEvent, curTick() + DMA_BACKOFF_PERIOD);
|
||||
DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
|
||||
return;
|
||||
} else if (!dmaWriteCG->done()) {
|
||||
assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
|
||||
ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(),
|
||||
&dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete());
|
||||
DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
|
||||
curPrd.getByteCount(), curPrd.getEOT());
|
||||
dmaWriteBytes += dmaWriteCG->size();
|
||||
dmaWriteTxs++;
|
||||
if (dmaWriteCG->size() == TheISA::PageBytes)
|
||||
dmaWriteFullPages++;
|
||||
dmaWriteCG->next();
|
||||
} else {
|
||||
DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
|
||||
curPrd.getByteCount(), curPrd.getEOT());
|
||||
assert(dmaWriteCG->done());
|
||||
delete dmaWriteCG;
|
||||
dmaWriteCG = NULL;
|
||||
|
@ -501,6 +509,8 @@ IdeDisk::doDmaWrite()
|
|||
void
|
||||
IdeDisk::dmaWriteDone()
|
||||
{
|
||||
DPRINTF(IdeDisk, "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
|
||||
curPrd.getByteCount(), curPrd.getEOT(), cmdBytesLeft);
|
||||
// check for the EOT
|
||||
if (curPrd.getEOT()) {
|
||||
assert(cmdBytesLeft == 0);
|
||||
|
@ -636,7 +646,7 @@ IdeDisk::startCommand()
|
|||
cmdBytes = cmdBytesLeft = (256 * SectorSize);
|
||||
else
|
||||
cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize);
|
||||
|
||||
DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d\n", cmdBytesLeft);
|
||||
curSector = getLBABase();
|
||||
|
||||
devState = Prepare_Data_Out;
|
||||
|
@ -654,6 +664,7 @@ IdeDisk::startCommand()
|
|||
cmdBytes = cmdBytesLeft = (256 * SectorSize);
|
||||
else
|
||||
cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize);
|
||||
DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n", cmdBytesLeft);
|
||||
|
||||
curSector = getLBABase();
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ class ChunkGenerator;
|
|||
|
||||
#define DMA_BACKOFF_PERIOD 200
|
||||
|
||||
#define MAX_DMA_SIZE (131072) // 128K
|
||||
#define MAX_DMA_SIZE 0x20000 // 128K
|
||||
#define MAX_SINGLE_DMA_SIZE 0x10000
|
||||
#define MAX_MULTSECT (128)
|
||||
|
||||
#define PRD_BASE_MASK 0xfffffffe
|
||||
|
@ -72,7 +73,7 @@ class PrdTableEntry {
|
|||
|
||||
uint32_t getByteCount()
|
||||
{
|
||||
return ((entry.byteCount == 0) ? MAX_DMA_SIZE :
|
||||
return ((entry.byteCount == 0) ? MAX_SINGLE_DMA_SIZE :
|
||||
(entry.byteCount & PRD_COUNT_MASK));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue