summaryrefslogtreecommitdiff
path: root/dev/ide_disk.cc
diff options
context:
space:
mode:
authorAndrew Schultz <alschult@umich.edu>2004-05-24 18:58:27 -0400
committerAndrew Schultz <alschult@umich.edu>2004-05-24 18:58:27 -0400
commit7c70a16c04202cc57e42b1b8baabcda40b6245b2 (patch)
tree52a787ead6a88b8848e6b669414b7d805d483338 /dev/ide_disk.cc
parent74c494a4eb868af99ebd77738685e4abb65743e7 (diff)
downloadgem5-7c70a16c04202cc57e42b1b8baabcda40b6245b2.tar.xz
Fix to the PIO read state machine (write still needs fixes)
--HG-- extra : convert_revision : 2e8afcfe3448d921b26ebb76e65c0b237339e9b1
Diffstat (limited to 'dev/ide_disk.cc')
-rw-r--r--dev/ide_disk.cc39
1 files changed, 26 insertions, 13 deletions
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 0d12e797d..2205db9e3 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -655,7 +655,7 @@ IdeDisk::startCommand()
// Supported PIO data-in commands
case WIN_IDENTIFY:
- cmdBytesLeft = drqBytesLeft = sizeof(struct hd_driveid);
+ cmdBytesLeft = sizeof(struct hd_driveid);
devState = Prepare_Data_In;
action = ACT_DATA_READY;
break;
@@ -670,9 +670,9 @@ IdeDisk::startCommand()
else
cmdBytesLeft = (cmdReg.sec_count * SectorSize);
- drqBytesLeft = SectorSize;
curSector = getLBABase();
+ /** @todo make this a scheduled event to simulate disk delay */
devState = Prepare_Data_In;
action = ACT_DATA_READY;
break;
@@ -688,7 +688,6 @@ IdeDisk::startCommand()
else
cmdBytesLeft = (cmdReg.sec_count * SectorSize);
- drqBytesLeft = SectorSize;
curSector = getLBABase();
devState = Prepare_Data_Out;
@@ -707,7 +706,6 @@ IdeDisk::startCommand()
else
cmdBytesLeft = (cmdReg.sec_count * SectorSize);
- drqBytesLeft = SectorSize;
curSector = getLBABase();
devState = Prepare_Data_Dma;
@@ -831,16 +829,23 @@ IdeDisk::updateState(DevAction_t action)
// set the DRQ bit
cmdReg.status |= STATUS_DRQ_BIT;
- // put the first two bytes into the data register
- memcpy((void *)&cmdReg.data0, (void *)dataBuffer,
- sizeof(uint16_t));
-
// copy the data into the data buffer
- if (curCommand == WIN_IDENTIFY)
+ if (curCommand == WIN_IDENTIFY) {
+ // Reset the drqBytes for this block
+ drqBytesLeft = sizeof(struct hd_driveid);
+
memcpy((void *)dataBuffer, (void *)&driveID,
sizeof(struct hd_driveid));
- else
+ } else {
+ // Reset the drqBytes for this block
+ drqBytesLeft = SectorSize;
+
readDisk(curSector++, dataBuffer);
+ }
+
+ // put the first two bytes into the data register
+ memcpy((void *)&cmdReg.data0, (void *)dataBuffer,
+ sizeof(uint16_t));
if (!isIENSet()) {
devState = Data_Ready_INTRQ_In;
@@ -867,9 +872,10 @@ IdeDisk::updateState(DevAction_t action)
cmdBytesLeft -= 2;
// copy next short into data registers
- memcpy((void *)&cmdReg.data0,
- (void *)&dataBuffer[SectorSize - drqBytesLeft],
- sizeof(uint16_t));
+ if (drqBytesLeft)
+ memcpy((void *)&cmdReg.data0,
+ (void *)&dataBuffer[SectorSize - drqBytesLeft],
+ sizeof(uint16_t));
}
if (drqBytesLeft == 0) {
@@ -879,7 +885,14 @@ IdeDisk::updateState(DevAction_t action)
devState = Device_Idle_S;
} else {
devState = Prepare_Data_In;
+ // set the BSY_BIT
cmdReg.status |= STATUS_BSY_BIT;
+ // clear the DRQ_BIT
+ cmdReg.status &= ~STATUS_DRQ_BIT;
+
+ /** @todo change this to a scheduled event to simulate
+ disk delay */
+ updateState(ACT_DATA_READY);
}
}
}