summaryrefslogtreecommitdiff
path: root/dev/ide_disk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/ide_disk.cc')
-rw-r--r--dev/ide_disk.cc63
1 files changed, 33 insertions, 30 deletions
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 3d7bd19c0..98f2ee7d5 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -116,6 +116,9 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
driveID.atap_udmamode_supp = 0x10;
// Statically set hardware config word
driveID.atap_hwreset_res = 0x4001;
+
+ //arbitrary for now...
+ driveID.atap_ata_major = WDC_VER_ATA7;
}
IdeDisk::~IdeDisk()
@@ -134,7 +137,6 @@ IdeDisk::reset(int id)
memset(&cmdReg, 0, sizeof(CommandReg_t));
memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
- cmdReg.error = 1;
dmaInterfaceBytes = 0;
curPrdAddr = 0;
curSector = 0;
@@ -159,6 +161,8 @@ IdeDisk::reset(int id)
// set the device ready bit
status = STATUS_DRDY_BIT;
+
+ cmdReg.error = 0x1;
}
////
@@ -207,62 +211,63 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
// Device registers read/write
////
-uint16_t
-IdeDisk::read(const Addr &offset, RegType_t type)
+void
+IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
{
- uint16_t data;
DevAction_t action = ACT_NONE;
- if (type == COMMAND_BLOCK) {
-
+ switch (type) {
+ case COMMAND_BLOCK:
if (offset == STATUS_OFFSET)
action = ACT_STAT_READ;
else if (offset == DATA_OFFSET)
action = ACT_DATA_READ_SHORT;
switch (offset) {
+ // Data transfers occur 16 bits at a time
case DATA_OFFSET:
- data = cmdReg.data;
+ // use memcpy to preserve little-endianess
+ memcpy(data, &cmdReg.data, sizeof(uint16_t));
break;
+ // All other transfers are 8 bit
case ERROR_OFFSET:
- data = cmdReg.error;
+ *data = cmdReg.error;
break;
case NSECTOR_OFFSET:
- data = cmdReg.sec_count;
+ *data = cmdReg.sec_count;
break;
case SECTOR_OFFSET:
- data = cmdReg.sec_num;
+ *data = cmdReg.sec_num;
break;
case LCYL_OFFSET:
- data = cmdReg.cyl_low;
+ *data = cmdReg.cyl_low;
break;
case HCYL_OFFSET:
- data = cmdReg.cyl_high;
+ *data = cmdReg.cyl_high;
break;
- case SELECT_OFFSET:
- data = cmdReg.drive;
+ case DRIVE_OFFSET:
+ *data = cmdReg.drive;
break;
case STATUS_OFFSET:
- data = status;
+ *data = status;
break;
default:
panic("Invalid IDE command register offset: %#x\n", offset);
}
- }
- else if (type == CONTROL_BLOCK) {
- if (offset != ALTSTAT_OFFSET)
+ break;
+ case CONTROL_BLOCK:
+ if (offset == ALTSTAT_OFFSET)
+ *data = status;
+ else
panic("Invalid IDE control register offset: %#x\n", offset);
+ break;
- data = status;
- }
- else {
- panic("Invalid IDE register type: %#x\n", type);
+ default:
+ panic("Unknown register block!\n");
}
if (action != ACT_NONE)
updateState(action);
-
- return data;
}
void
@@ -271,8 +276,6 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
DevAction_t action = ACT_NONE;
if (cmdBlk) {
- if (offset < 0 || offset > sizeof(CommandReg_t))
- panic("Invalid disk command register offset: %#x\n", offset);
if (!byte && offset != DATA_OFFSET)
panic("Invalid 16-bit write, only allowed on data reg\n");
@@ -282,10 +285,10 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
else {
switch (offset) {
case DATA_OFFSET:
- cmdReg.data = *data;
+ memcpy(&cmdReg.data, data, sizeof(uint16_t));
break;
case FEATURES_OFFSET:
- cmdReg.features = *data;
+ //cmdReg.features = *data;
break;
case NSECTOR_OFFSET:
cmdReg.sec_count = *data;
@@ -299,7 +302,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
case HCYL_OFFSET:
cmdReg.cyl_high = *data;
break;
- case SELECT_OFFSET:
+ case DRIVE_OFFSET:
cmdReg.drive = *data;
break;
case COMMAND_OFFSET:
@@ -318,7 +321,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
action = ACT_DATA_WRITE_BYTE;
else
action = ACT_DATA_WRITE_SHORT;
- } else if (offset == SELECT_OFFSET) {
+ } else if (offset == DRIVE_OFFSET) {
action = ACT_SELECT_WRITE;
}