summaryrefslogtreecommitdiff
path: root/dev/ide_disk.cc
diff options
context:
space:
mode:
authorMiguel Serrano <mserrano@umich.edu>2005-08-15 16:59:58 -0400
committerMiguel Serrano <mserrano@umich.edu>2005-08-15 16:59:58 -0400
commitb64eae5e52d9eb60ad498464d076b48cd5ceafe3 (patch)
treeba02beaf1c9ac36a344173cf48dab15545d20028 /dev/ide_disk.cc
parent1e2c16c9124ed3f51229daa715a6c00c2b97f73d (diff)
downloadgem5-b64eae5e52d9eb60ad498464d076b48cd5ceafe3.tar.xz
Changes for getting FreeBSD to run.
SConscript: Added more files to compile: dev/pcifake.cc, dev/isa_fake.cc, kern/freebsd/freebsd_system.cc, kern/freebsd/freebsd_events.cc. arch/alpha/isa_traits.hh: Added constant for argument register 2 as it is needed by FreebsdSystem::doCalibrateClocks(). cpu/exec_context.hh: cpu/o3/alpha_cpu.hh: Replaced htoa()s with gtoh() and htog(). cpu/o3/fetch_impl.hh: cpu/simple/cpu.cc: Replaced htoa() with gtoh(). dev/disk_image.cc: Replaced htoa()s with letoh()s. dev/ide_ctrl.cc: Got rid of magic numbers. Added IdeChannel and IdeRegType type names where necessary. dev/ide_ctrl.hh: Got rid of unnecessary macros. Changed RegType_t to IdeRegType. Changed bmi_regs to allow accessing registers by name instead of just by array index. Added IdeChannel enum type to use in place of bool variables which were used to specify IDE channel. dev/ide_disk.cc: Rewrote IdeDisk::read and IdeDisk::write functions to specify registers by name instead of indexing through an array. dev/ide_disk.hh: Updated command register struct. dev/ns_gige.cc: dev/ns_gige.hh: Made ReadConfig and WriteConfig begin with a lower-case letter. writeConfig() now takes a pointer to data as a parameter instead of a copy of data. dev/pciconfigall.cc: writeConfig() now takes a pointer to data as a parameter instead of a copy of data. dev/pcidev.cc: Cleaned up readConfig() and writeConfig() functions. dev/pcidev.hh: Added macros to make code that works with the BARs (base adress registers) more readable. writeConfig() now takes a pointer to data. dev/pcireg.h: Changed PCIConfig struct to make accessing elements more straight forward. Removed type 1 (for PCI-to-PCI bridges) PCI configuration space struct since it is not used. dev/rtcreg.h: Added macros for bit fields in RTC status registers A & B. dev/sinic.cc: Function name change: WriteConfig --> writeConfig. writeConfig() now takes a pointer to data instead of a copy of data. The accessing of elements of PCIConfig structure is updated. dev/sinic.hh: Function name change: WriteConfig --> writeConfig. writeConfig() now takes a pointer to data instead of a copy of data. dev/tsunami_io.cc: Added implementation of new RTC and PIT classes. dev/tsunami_io.hh: Added classes for RTC and PIT modules. dev/tsunamireg.h: Added macros for DMA ports used by Tsunami-Tru64. dev/uart8250.cc: Got rid of a magic number. Transmit (Tx) interrupts should clear upon a read of the Interrupt ID register. dev/uart8250.hh: Added comments and macros dealing with the UART Interrupt ID register. kern/linux/linux_system.cc: Replaced htoa() with htog(). python/m5/objects/Pci.py: PciFake is a python class for Pci Devices that do nothing. python/m5/objects/Tsunami.py: TsunamiFake was renamed as IsaFake. sim/system.cc: Replaced htoa()s with htog()s. dev/isa_fake.cc: New BitKeeper file ``dev/isa_fake.cc'' TsunamiFake was renamed as IsaFake. dev/isa_fake.hh: New BitKeeper file ``dev/isa_fake.hh'' TsunmaiFake was renamed as IsaFake. dev/pitreg.h: New BitKeeper file ``dev/pitreg.h'' Useful macros for working with PIT (Periodic Interval Timer) registers. --HG-- extra : convert_revision : 33f3a8a1034af4f6c71b32dd743e371c8613e780
Diffstat (limited to 'dev/ide_disk.cc')
-rw-r--r--dev/ide_disk.cc179
1 files changed, 103 insertions, 76 deletions
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 23d04bb5e..bd9aac8ea 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()
@@ -158,6 +161,10 @@ IdeDisk::reset(int id)
// set the device ready bit
status = STATUS_DRDY_BIT;
+
+ /* The error register must be set to 0x1 on start-up to
+ indicate that no diagnostic error was detected */
+ cmdReg.error = 0x1;
}
////
@@ -207,41 +214,52 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
////
void
-IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data)
+IdeDisk::read(const Addr &offset, IdeRegType reg_type, 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 read, only allowed on data reg\n");
-
- if (!byte)
- *(uint16_t *)data = *(uint16_t *)&cmdReg.data0;
- else
- *data = ((uint8_t *)&cmdReg)[offset];
-
- // determine if an action needs to be taken on the state machine
- if (offset == STATUS_OFFSET) {
+ 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;
- *data = status; // status is in a shadow, explicity copy
- } else if (offset == DATA_OFFSET) {
- if (byte)
- action = ACT_DATA_READ_BYTE;
- else
- action = ACT_DATA_READ_SHORT;
+ break;
+ default:
+ panic("Invalid IDE command register offset: %#x\n", offset);
}
-
- } else {
- if (offset != ALTSTAT_OFFSET)
- panic("Invalid disk control register offset: %#x\n", offset);
-
- if (!byte)
- panic("Invalid 16-bit read from control block\n");
-
- *data = status;
+ break;
+ case CONTROL_BLOCK:
+ if (offset == ALTSTAT_OFFSET)
+ *data = status;
+ else
+ panic("Invalid IDE control register offset: %#x\n", offset);
+ break;
+ default:
+ panic("Unknown register block!\n");
}
if (action != ACT_NONE)
@@ -249,50 +267,59 @@ IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data)
}
void
-IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
+IdeDisk::write(const Addr &offset, IdeRegType reg_type, 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");
-
- if (!byte)
- *((uint16_t *)&cmdReg.data0) = *(uint16_t *)data;
- else
- ((uint8_t *)&cmdReg)[offset] = *data;
-
- // determine if an action needs to be taken on the state machine
- if (offset == COMMAND_OFFSET) {
- action = ACT_CMD_WRITE;
- } else if (offset == DATA_OFFSET) {
- if (byte)
- action = ACT_DATA_WRITE_BYTE;
- else
- action = ACT_DATA_WRITE_SHORT;
- } else if (offset == SELECT_OFFSET) {
+ 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);
}
-
- } else {
- if (offset != CONTROL_OFFSET)
- panic("Invalid disk control register offset: %#x\n", offset);
-
- if (!byte)
- panic("Invalid 16-bit write to control block\n");
-
- 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;
+ 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;
}
-
- nIENBit = (*data & CONTROL_IEN_BIT) ? true : false;
+ else
+ panic("Invalid IDE control register offset: %#x\n", offset);
+ break;
+ default:
+ panic("Unknown register block!\n");
}
if (action != ACT_NONE)
@@ -744,8 +771,10 @@ IdeDisk::intrPost()
intrPending = true;
// talk to controller to set interrupt
- if (ctrl)
+ if (ctrl) {
+ ctrl->bmi_regs.bmis0 |= IDEINTS;
ctrl->intrPost();
+ }
}
void
@@ -864,7 +893,7 @@ IdeDisk::updateState(DevAction_t action)
}
// put the first two bytes into the data register
- memcpy((void *)&cmdReg.data0, (void *)dataBuffer,
+ memcpy((void *)&cmdReg.data, (void *)dataBuffer,
sizeof(uint16_t));
if (!isIENSet()) {
@@ -893,7 +922,7 @@ IdeDisk::updateState(DevAction_t action)
// copy next short into data registers
if (drqBytesLeft)
- memcpy((void *)&cmdReg.data0,
+ memcpy((void *)&cmdReg.data,
(void *)&dataBuffer[SectorSize - drqBytesLeft],
sizeof(uint16_t));
}
@@ -966,7 +995,7 @@ IdeDisk::updateState(DevAction_t action)
} else {
// copy the latest short into the data buffer
memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
- (void *)&cmdReg.data0,
+ (void *)&cmdReg.data,
sizeof(uint16_t));
drqBytesLeft -= 2;
@@ -1090,8 +1119,7 @@ IdeDisk::serialize(ostream &os)
SERIALIZE_ENUM(event);
// Serialize device registers
- SERIALIZE_SCALAR(cmdReg.data0);
- SERIALIZE_SCALAR(cmdReg.data1);
+ SERIALIZE_SCALAR(cmdReg.data);
SERIALIZE_SCALAR(cmdReg.sec_count);
SERIALIZE_SCALAR(cmdReg.sec_num);
SERIALIZE_SCALAR(cmdReg.cyl_low);
@@ -1143,8 +1171,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
}
// Unserialize device registers
- UNSERIALIZE_SCALAR(cmdReg.data0);
- UNSERIALIZE_SCALAR(cmdReg.data1);
+ UNSERIALIZE_SCALAR(cmdReg.data);
UNSERIALIZE_SCALAR(cmdReg.sec_count);
UNSERIALIZE_SCALAR(cmdReg.sec_num);
UNSERIALIZE_SCALAR(cmdReg.cyl_low);