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:
Ali Saidi 2011-08-19 15:08:08 -05:00
parent 999cd8aef5
commit 243223ae63
3 changed files with 27 additions and 8 deletions

View file

@ -211,7 +211,10 @@ IdeController::readConfig(PacketPtr pkt)
(uint32_t)pkt->get<uint16_t>());
break;
case sizeof(uint32_t):
panic("No 32bit reads implemented for this device.");
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>());
break;
@ -275,7 +278,10 @@ IdeController::writeConfig(PacketPtr pkt)
offset, (uint32_t)pkt->get<uint16_t>());
break;
case sizeof(uint32_t):
panic("Write of unimplemented PCI config. register: %x\n", offset);
if (offset == IDEConfig)
ideConfig = pkt->get<uint32_t>();
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;

View file

@ -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();

View file

@ -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));
}