X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fide_disk.cc;h=83faf508eeec477f53dd04764d737a77cc0fdc7f;hb=7daed385bf9de7761128eedd5a2995692bdfeb19;hp=8f9999bebae3b6617539e74ec3d43f54e94c540b;hpb=54cc0053f0a6822e47a49771976af6daaabc24bb;p=gem5.git diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc index 8f9999beb..83faf508e 100644 --- a/src/dev/ide_disk.cc +++ b/src/dev/ide_disk.cc @@ -177,7 +177,7 @@ Addr IdeDisk::pciToDma(Addr pciAddr) { if (ctrl) - return ctrl->plat->pciToDma(pciAddr); + return ctrl->pciToDma(pciAddr); else panic("Access to unset controller!\n"); } @@ -187,120 +187,127 @@ IdeDisk::pciToDma(Addr pciAddr) //// void -IdeDisk::read(const Addr &offset, IdeRegType reg_type, uint8_t *data) +IdeDisk::readCommand(const Addr offset, int size, uint8_t *data) { - DevAction_t action = ACT_NONE; - - switch (reg_type) { - case COMMAND_BLOCK: - switch (offset) { - // Data transfers occur two bytes at a time - case DATA_OFFSET: - *(uint16_t*)data = cmdReg.data; - action = ACT_DATA_READ_SHORT; - break; - case ERROR_OFFSET: - *data = cmdReg.error; - break; - case NSECTOR_OFFSET: - *data = cmdReg.sec_count; - break; - case SECTOR_OFFSET: - *data = cmdReg.sec_num; - break; - case LCYL_OFFSET: - *data = cmdReg.cyl_low; - break; - case HCYL_OFFSET: - *data = cmdReg.cyl_high; - break; - case DRIVE_OFFSET: - *data = cmdReg.drive; - break; - case STATUS_OFFSET: - *data = status; - action = ACT_STAT_READ; - break; - default: - panic("Invalid IDE command register offset: %#x\n", offset); + if (offset == DATA_OFFSET) { + if (size == sizeof(uint16_t)) { + *(uint16_t *)data = cmdReg.data; + } else if (size == sizeof(uint32_t)) { + *(uint16_t *)data = cmdReg.data; + updateState(ACT_DATA_READ_SHORT); + *((uint16_t *)data + 1) = cmdReg.data; + } else { + panic("Data read of unsupported size %d.\n", size); } + updateState(ACT_DATA_READ_SHORT); + return; + } + assert(size == sizeof(uint8_t)); + switch (offset) { + case ERROR_OFFSET: + *data = cmdReg.error; break; - case CONTROL_BLOCK: - if (offset == ALTSTAT_OFFSET) - *data = status; - else - panic("Invalid IDE control register offset: %#x\n", offset); + case NSECTOR_OFFSET: + *data = cmdReg.sec_count; + break; + case SECTOR_OFFSET: + *data = cmdReg.sec_num; + break; + case LCYL_OFFSET: + *data = cmdReg.cyl_low; + break; + case HCYL_OFFSET: + *data = cmdReg.cyl_high; + break; + case DRIVE_OFFSET: + *data = cmdReg.drive; + break; + case STATUS_OFFSET: + *data = status; + updateState(ACT_STAT_READ); break; default: - panic("Unknown register block!\n"); + panic("Invalid IDE command register offset: %#x\n", offset); } - DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, - (uint32_t)*data); - - if (action != ACT_NONE) - updateState(action); + DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data); } void -IdeDisk::write(const Addr &offset, IdeRegType reg_type, const uint8_t *data) +IdeDisk::readControl(const Addr offset, int size, uint8_t *data) { - DevAction_t action = ACT_NONE; + assert(size == sizeof(uint8_t)); + *data = status; + if (offset != ALTSTAT_OFFSET) + panic("Invalid IDE control register offset: %#x\n", offset); + DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data); +} - switch (reg_type) { - case COMMAND_BLOCK: - switch (offset) { - case DATA_OFFSET: - cmdReg.data = *(uint16_t*)data; - action = ACT_DATA_WRITE_SHORT; - break; - case FEATURES_OFFSET: - break; - case NSECTOR_OFFSET: - cmdReg.sec_count = *data; - break; - case SECTOR_OFFSET: - cmdReg.sec_num = *data; - break; - case LCYL_OFFSET: - cmdReg.cyl_low = *data; - break; - case HCYL_OFFSET: - cmdReg.cyl_high = *data; - break; - case DRIVE_OFFSET: - cmdReg.drive = *data; - action = ACT_SELECT_WRITE; - break; - case COMMAND_OFFSET: - cmdReg.command = *data; - action = ACT_CMD_WRITE; - break; - default: - panic("Invalid IDE command register offset: %#x\n", offset); +void +IdeDisk::writeCommand(const Addr offset, int size, const uint8_t *data) +{ + if (offset == DATA_OFFSET) { + if (size == sizeof(uint16_t)) { + cmdReg.data = *(const uint16_t *)data; + } else if (size == sizeof(uint32_t)) { + cmdReg.data = *(const uint16_t *)data; + updateState(ACT_DATA_WRITE_SHORT); + cmdReg.data = *((const uint16_t *)data + 1); + } else { + panic("Data write of unsupported size %d.\n", size); } + updateState(ACT_DATA_WRITE_SHORT); + return; + } + + assert(size == sizeof(uint8_t)); + switch (offset) { + case FEATURES_OFFSET: break; - case CONTROL_BLOCK: - if (offset == CONTROL_OFFSET) { - if (*data & CONTROL_RST_BIT) { - // force the device into the reset state - devState = Device_Srst; - action = ACT_SRST_SET; - } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) - action = ACT_SRST_CLEAR; - - nIENBit = (*data & CONTROL_IEN_BIT) ? true : false; - } - else - panic("Invalid IDE control register offset: %#x\n", offset); + case NSECTOR_OFFSET: + cmdReg.sec_count = *data; + break; + case SECTOR_OFFSET: + cmdReg.sec_num = *data; + break; + case LCYL_OFFSET: + cmdReg.cyl_low = *data; + break; + case HCYL_OFFSET: + cmdReg.cyl_high = *data; + break; + case DRIVE_OFFSET: + cmdReg.drive = *data; + updateState(ACT_SELECT_WRITE); + break; + case COMMAND_OFFSET: + cmdReg.command = *data; + updateState(ACT_CMD_WRITE); break; default: - panic("Unknown register block!\n"); + panic("Invalid IDE command register offset: %#x\n", offset); } + DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset, + (uint32_t)*data); +} + +void +IdeDisk::writeControl(const Addr offset, int size, const uint8_t *data) +{ + if (offset != CONTROL_OFFSET) + panic("Invalid IDE control register offset: %#x\n", offset); + + if (*data & CONTROL_RST_BIT) { + // force the device into the reset state + devState = Device_Srst; + updateState(ACT_SRST_SET); + } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) { + updateState(ACT_SRST_CLEAR); + } + + nIENBit = *data & CONTROL_IEN_BIT; DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset, (uint32_t)*data); - if (action != ACT_NONE) - updateState(action); } //// @@ -315,7 +322,7 @@ IdeDisk::doDmaTransfer() dmaState, devState); if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) { - dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + schedule(dmaTransferEvent, curTick + DMA_BACKOFF_PERIOD); return; } else ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent, @@ -349,7 +356,7 @@ IdeDisk::doDmaDataRead() DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n", diskDelay, totalDiskDelay); - dmaReadWaitEvent.schedule(curTick + totalDiskDelay); + schedule(dmaReadWaitEvent, curTick + totalDiskDelay); } void @@ -395,7 +402,7 @@ IdeDisk::doDmaRead() } if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) { - dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + schedule(dmaReadWaitEvent, curTick + DMA_BACKOFF_PERIOD); return; } else if (!dmaReadCG->done()) { assert(dmaReadCG->complete() < MAX_DMA_SIZE); @@ -457,7 +464,7 @@ IdeDisk::doDmaDataWrite() cmdBytesLeft -= SectorSize; } - dmaWriteWaitEvent.schedule(curTick + totalDiskDelay); + schedule(dmaWriteWaitEvent, curTick + totalDiskDelay); } void @@ -470,7 +477,7 @@ IdeDisk::doDmaWrite() curPrd.getByteCount(), TheISA::PageBytes); } if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) { - dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + schedule(dmaWriteWaitEvent, curTick + DMA_BACKOFF_PERIOD); return; } else if (!dmaWriteCG->done()) { assert(dmaWriteCG->complete() < MAX_DMA_SIZE); @@ -545,7 +552,7 @@ IdeDisk::startDma(const uint32_t &prdTableBase) dmaState = Dma_Transfer; // schedule dma transfer (doDmaTransfer) - dmaTransferEvent.schedule(curTick + 1); + schedule(dmaTransferEvent, curTick + 1); } void @@ -683,7 +690,6 @@ IdeDisk::intrPost() // talk to controller to set interrupt if (ctrl) { - ctrl->bmi_regs.bmis0 |= IDEINTS; ctrl->intrPost(); } } @@ -1073,12 +1079,12 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) switch (event) { case None : break; - case Transfer : dmaTransferEvent.schedule(reschedule); break; - case ReadWait : dmaReadWaitEvent.schedule(reschedule); break; - case WriteWait : dmaWriteWaitEvent.schedule(reschedule); break; - case PrdRead : dmaPrdReadEvent.schedule(reschedule); break; - case DmaRead : dmaReadEvent.schedule(reschedule); break; - case DmaWrite : dmaWriteEvent.schedule(reschedule); break; + case Transfer : schedule(dmaTransferEvent, reschedule); break; + case ReadWait : schedule(dmaReadWaitEvent, reschedule); break; + case WriteWait : schedule(dmaWriteWaitEvent, reschedule); break; + case PrdRead : schedule(dmaPrdReadEvent, reschedule); break; + case DmaRead : schedule(dmaReadEvent, reschedule); break; + case DmaWrite : schedule(dmaWriteEvent, reschedule); break; } // Unserialize device registers