From 243223ae638e95cb6744f335010595c4de30d13c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 19 Aug 2011 15:08:08 -0500 Subject: [PATCH] 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. --- src/dev/ide_ctrl.cc | 11 +++++++++-- src/dev/ide_disk.cc | 15 +++++++++++++-- src/dev/ide_disk.hh | 9 +++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index a370c7f36..291ce1389 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -211,7 +211,10 @@ IdeController::readConfig(PacketPtr pkt) (uint32_t)pkt->get()); break; case sizeof(uint32_t): - panic("No 32bit reads implemented for this device."); + if (offset == IDEConfig) + pkt->set(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()); break; @@ -275,7 +278,10 @@ IdeController::writeConfig(PacketPtr pkt) offset, (uint32_t)pkt->get()); break; case sizeof(uint32_t): - panic("Write of unimplemented PCI config. register: %x\n", offset); + if (offset == IDEConfig) + ideConfig = pkt->get(); + else + panic("Write of unimplemented PCI config. register: %x\n", offset); break; default: panic("invalid access size(?) for PCI configspace!\n"); @@ -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; diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc index a67318b68..f0c8c8668 100644 --- a/src/dev/ide_disk.cc +++ b/src/dev/ide_disk.cc @@ -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(); diff --git a/src/dev/ide_disk.hh b/src/dev/ide_disk.hh index 0595e18cf..af42bd2c9 100644 --- a/src/dev/ide_disk.hh +++ b/src/dev/ide_disk.hh @@ -46,10 +46,11 @@ class ChunkGenerator; -#define DMA_BACKOFF_PERIOD 200 +#define DMA_BACKOFF_PERIOD 200 -#define MAX_DMA_SIZE (131072) // 128K -#define MAX_MULTSECT (128) +#define MAX_DMA_SIZE 0x20000 // 128K +#define MAX_SINGLE_DMA_SIZE 0x10000 +#define MAX_MULTSECT (128) #define PRD_BASE_MASK 0xfffffffe #define PRD_COUNT_MASK 0xfffe @@ -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)); } -- 2.30.2