From 74fd4f68c5a7df2efba11497ba1ab5ab62b0b1bf Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Thu, 28 Jul 2005 11:49:01 -0400 Subject: [PATCH] . SConscript: add pcifake dev/ide_ctrl.cc: dev/ide_ctrl.hh: dev/ide_disk.cc: dev/ide_disk.hh: endianess dev/tsunami_io.cc: rtc, date/time --HG-- extra : convert_revision : 21ad27c780749cb6f6eef2b57798c0c292c3f14d --- SConscript | 1 + dev/ide_ctrl.cc | 290 ++++++++++++++++++++++++++++++---------------- dev/ide_ctrl.hh | 17 ++- dev/ide_disk.cc | 174 +++++++++++++--------------- dev/ide_disk.hh | 10 +- dev/tsunami_io.cc | 12 +- 6 files changed, 288 insertions(+), 216 deletions(-) diff --git a/SConscript b/SConscript index 7b309fbfe..736135386 100644 --- a/SConscript +++ b/SConscript @@ -265,6 +265,7 @@ full_system_sources = Split(''' dev/ns_gige.cc dev/pciconfigall.cc dev/pcidev.cc + dev/pcifake.cc dev/pktfifo.cc dev/platform.cc dev/sinic.cc diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 6636a5ff6..2c86d27c7 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -75,13 +75,13 @@ IdeController::IdeController(Params *p) bmi_size = BARSize[4]; // zero out all of the registers - memset(bmi_regs, 0, sizeof(bmi_regs)); + memset(bmi_regs.data, 0, sizeof(bmi_regs)); memset(pci_config_regs.data, 0, sizeof(pci_config_regs.data)); // setup initial values pci_config_regs.idetim = htoa((uint32_t)0x80008000); // enable both channels - *(uint8_t *)&bmi_regs[BMIS0] = 0x60; - *(uint8_t *)&bmi_regs[BMIS1] = 0x60; + bmi_regs.bmis0 = DMA1CAP | DMA0CAP; + bmi_regs.bmis1 = DMA1CAP | DMA0CAP; // reset all internal variables io_enabled = false; @@ -218,18 +218,18 @@ IdeController::setDmaComplete(IdeDisk *disk) if (diskNum < 2) { // clear the start/stop bit in the command register - bmi_regs[BMIC0] &= ~SSBM; + bmi_regs.bmic0 &= ~SSBM; // clear the bus master active bit in the status register - bmi_regs[BMIS0] &= ~BMIDEA; + bmi_regs.bmis0 &= ~BMIDEA; // set the interrupt bit - bmi_regs[BMIS0] |= IDEINTS; + bmi_regs.bmis0 |= IDEINTS; } else { // clear the start/stop bit in the command register - bmi_regs[BMIC1] &= ~SSBM; + bmi_regs.bmic1 &= ~SSBM; // clear the bus master active bit in the status register - bmi_regs[BMIS1] &= ~BMIDEA; + bmi_regs.bmis1 &= ~BMIDEA; // set the interrupt bit - bmi_regs[BMIS1] |= IDEINTS; + bmi_regs.bmis1 |= IDEINTS; } } @@ -251,74 +251,78 @@ IdeController::cacheAccess(MemReqPtr &req) void IdeController::ReadConfig(int offset, int size, uint8_t *data) { - int config_offset; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + }; -#if TRACING_ON - Addr origOffset = offset; -#endif + int config_offset; if (offset < PCI_DEVICE_SPECIFIC) { PciDev::ReadConfig(offset, size, data); - } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) { + } else if (offset >= IDE_CTRL_CONFIG_START && + (offset + size) <= IDE_CTRL_CONFIG_END) { config_offset = offset - IDE_CTRL_CONFIG_START; + dword = 0; - switch(size) { - case sizeof(uint32_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint32_t)); - *(uint32_t*)data = htoa(*(uint32_t*)data); + switch (size) { + case sizeof(uint8_t): + memcpy(&byte, &pci_config_regs.data[config_offset], size); + *data = byte; break; - case sizeof(uint16_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint16_t)); - *(uint16_t*)data = htoa(*(uint16_t*)data); + memcpy(&byte, &pci_config_regs.data[config_offset], size); + *(uint16_t*)data = htoa(word); break; - - case sizeof(uint8_t): - memcpy(data, &pci_config_regs.data[config_offset], sizeof(uint8_t)); + case sizeof(uint32_t): + memcpy(&byte, &pci_config_regs.data[config_offset], size); + *(uint32_t*)data = htoa(dword); break; - default: panic("Invalid PCI configuration read size!\n"); } + + DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n", + offset, size, htoa(dword)); + } else { panic("Read of unimplemented PCI config. register: %x\n", offset); } - - DPRINTF(IdeCtrl, "PCI read offset: %#x (%#x) size: %#x data: %#x\n", - origOffset, offset, size, - *(uint32_t *)data & (0xffffffff >> 8 * (4 - size))); } void IdeController::WriteConfig(int offset, int size, uint32_t data) { int config_offset; + uint32_t write_data; if (offset < PCI_DEVICE_SPECIFIC) { PciDev::WriteConfig(offset, size, data); - } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) { + } else if (offset >= IDE_CTRL_CONFIG_START && + (offset + size) <= IDE_CTRL_CONFIG_END) { config_offset = offset - IDE_CTRL_CONFIG_START; + write_data = htoa(data); + switch(size) { - case sizeof(uint32_t): - case sizeof(uint16_t): case sizeof(uint8_t): - memcpy(&pci_config_regs.data[config_offset], &data, size); + case sizeof(uint16_t): + case sizeof(uint32_t): + memcpy(&pci_config_regs.data[config_offset], &write_data, size); break; default: panic("Invalid PCI configuration write size!\n"); } - } else { panic("Write of unimplemented PCI config. register: %x\n", offset); } DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n", - offset, size, data & (0xffffffff >> 8 * (4 - size))); - + offset, size, data); // Catch the writes to specific PCI registers that have side affects // (like updating the PIO ranges) @@ -399,42 +403,89 @@ IdeController::read(MemReqPtr &req, uint8_t *data) RegType_t type; int disk; + /* union + * +-- --+-- --+-- --+-- --+ + * | 0 | 1 | 2 | 3 | + * +-- --+-- --+-- --+-- --+ + * | byte | .. | .. | .. | + * +-- --+-- --+-- --+-- --+ + * | word0 | word1 | + * +-- --+-- --+ + * | dword | + * +-- --+ + */ + union { + uint8_t byte; + uint16_t word[2]; + uint32_t dword; + }; + + dword = 0; + parseAddr(req->paddr, offset, primary, type); if (!io_enabled) return No_Fault; - // sanity check the size (allows byte, word, or dword access) - switch (req->size) { - case sizeof(uint8_t): - case sizeof(uint16_t): - case sizeof(uint32_t): + switch (type) { + case BMI_BLOCK: + switch (req->size) { + case sizeof(uint8_t): + memcpy(&byte, &bmi_regs.data[offset], sizeof(uint8_t)); + *data = byte; + break; + case sizeof(uint16_t): + memcpy(&byte, &bmi_regs.data[offset], sizeof(uint16_t)); + *(uint16_t*)data = htoa(word[0]); + break; + case sizeof(uint32_t): + memcpy(&byte, &bmi_regs.data[offset], sizeof(uint32_t)); + *(uint32_t*)data = htoa(dword); + break; + default: + panic("IDE read of BMI reg invalid size: %#x\n", req->size); + } break; - default: - panic("IDE controller read of invalid size: %#x\n", req->size); - } - - if (type != BMI_BLOCK) { + case COMMAND_BLOCK: + case CONTROL_BLOCK: disk = getDisk(primary); - if (disks[disk]) - if (req->size == sizeof(uint32_t) && offset == DATA_OFFSET) { - ((uint16_t*)data)[0] = disks[disk]->read(offset, type); - ((uint16_t*)data)[1] = disks[disk]->read(offset, type); - } - else if (req->size == sizeof(uint8_t) && offset == DATA_OFFSET) { + + if (disks[disk] == NULL) + break; + + switch (offset) { + case DATA_OFFSET: + switch (req->size) { + case sizeof(uint16_t): + disks[disk]->read(offset, type, (uint8_t*)&word[0]); + *(uint16_t*)data = htoa(word[0]); + break; + + case sizeof(uint32_t): + disks[disk]->read(offset, type, (uint8_t*)&word[0]); + disks[disk]->read(offset, type, (uint8_t*)&word[1]); + *(uint32_t*)data = htoa(dword); + break; + + default: panic("IDE read of data reg invalid size: %#x\n", req->size); } - else { - *data = disks[disk]->read(offset, type); - } - } else { - memcpy((void *)data, &bmi_regs[offset], req->size); + break; + default: + if (req->size == sizeof(uint8_t)) { + disks[disk]->read(offset, type, &byte); + *data = byte; + } else + panic("IDE read of command reg of invalid size: %#x\n", req->size); + } + break; + default: + panic("IDE controller read of unknown register block type!\n"); } DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, - (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size))); + offset, req->size, htoa(dword)); return No_Fault; } @@ -444,40 +495,29 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) { Addr offset; bool primary; - bool byte; - bool cmdBlk; RegType_t type; int disk; - parseAddr(req->paddr, offset, primary, type); - byte = (req->size == sizeof(uint8_t)) ? true : false; - cmdBlk = (type == COMMAND_BLOCK) ? true : false; + union { + uint8_t byte; + uint16_t word[2]; + uint32_t dword; + }; - DPRINTF(IdeCtrl, "write from offset: %#x size: %#x data: %#x\n", - offset, req->size, - (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size))); + dword = 0; + + parseAddr(req->paddr, offset, primary, type); uint8_t oldVal, newVal; if (!io_enabled) return No_Fault; - if (type == BMI_BLOCK && !bm_enabled) - return No_Fault; + switch (type) { + case BMI_BLOCK: + if (!bm_enabled) + return No_Fault; - if (type != BMI_BLOCK) { - // shadow the dev bit - if (type == COMMAND_BLOCK && offset == IDE_SELECT_OFFSET) { - uint8_t *devBit = (primary ? &dev[0] : &dev[1]); - *devBit = ((*data & IDE_SELECT_DEV_BIT) ? 1 : 0); - } - - assert(req->size != sizeof(uint32_t)); - - disk = getDisk(primary); - if (disks[disk]) - disks[disk]->write(offset, byte, cmdBlk, data); - } else { switch (offset) { // Bus master IDE command register case BMIC1: @@ -488,8 +528,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) // select the current disk based on DEV bit disk = getDisk(primary); - oldVal = bmi_regs[offset]; - newVal = *data; + oldVal = bmi_regs.data[offset]; + byte = *data; + newVal = byte; // if a DMA transfer is in progress, R/W control cannot change if (oldVal & SSBM) { @@ -505,7 +546,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) DPRINTF(IdeCtrl, "Stopping DMA transfer\n"); // clear the BMIDEA bit - bmi_regs[offset + 0x2] &= ~BMIDEA; + bmi_regs.data[offset + 0x2] &= ~BMIDEA; if (disks[disk] == NULL) panic("DMA stop for disk %d which does not exist\n", @@ -518,7 +559,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) DPRINTF(IdeCtrl, "Starting DMA transfer\n"); // set the BMIDEA bit - bmi_regs[offset + 0x2] |= BMIDEA; + bmi_regs.data[offset + 0x2] |= BMIDEA; if (disks[disk] == NULL) panic("DMA start for disk %d which does not exist\n", @@ -526,14 +567,14 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) // inform the disk of the DMA transfer start if (primary) - disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP0]); + disks[disk]->startDma(bmi_regs.bmidtp0); else - disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP1]); + disks[disk]->startDma(bmi_regs.bmidtp1); } } // update the register value - bmi_regs[offset] = newVal; + bmi_regs.data[offset] = newVal; break; // Bus master IDE status register @@ -542,8 +583,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) if (req->size != sizeof(uint8_t)) panic("Invalid BMIS write size: %x\n", req->size); - oldVal = bmi_regs[offset]; - newVal = *data; + oldVal = bmi_regs.data[offset]; + byte = *data; + newVal = byte; // the BMIDEA bit is RO newVal |= (oldVal & BMIDEA); @@ -559,7 +601,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) else (oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE; - bmi_regs[offset] = newVal; + bmi_regs.data[offset] = newVal; break; // Bus master IDE descriptor table pointer register @@ -568,7 +610,8 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) if (req->size != sizeof(uint32_t)) panic("Invalid BMIDTP write size: %x\n", req->size); - *(uint32_t *)&bmi_regs[offset] = *(uint32_t *)data & ~0x3; + dword = htoa(*(uint32_t *)data & ~0x3); + *(uint32_t *)&bmi_regs.data[offset] = dword; break; default: @@ -579,10 +622,53 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) req->size); // do a default copy of data into the registers - memcpy((void *)&bmi_regs[offset], data, req->size); + memcpy((void *)&bmi_regs.data[offset], data, req->size); + } + break; + case COMMAND_BLOCK: + if (offset == IDE_SELECT_OFFSET) { + uint8_t *devBit = (primary ? &dev[0] : &dev[1]); + *devBit = ((*data & IDE_SELECT_DEV_BIT) ? 1 : 0); } + // fall-through ok! + case CONTROL_BLOCK: + disk = getDisk(primary); + + if (disks[disk] == NULL) + break; + + switch (offset) { + case DATA_OFFSET: + switch (req->size) { + case sizeof(uint16_t): + word[0] = htoa(*(uint16_t*)data); + disks[disk]->write(offset, type, (uint8_t*)&word[0]); + break; + + case sizeof(uint32_t): + dword = htoa(*(uint32_t*)data); + disks[disk]->write(offset, type, (uint8_t*)&word[0]); + disks[disk]->write(offset, type, (uint8_t*)&word[1]); + break; + default: + panic("IDE write of data reg invalid size: %#x\n", req->size); + } + break; + default: + if (req->size == sizeof(uint8_t)) { + byte = *data; + disks[disk]->write(offset, type, &byte); + } else + panic("IDE write of command reg of invalid size: %#x\n", req->size); + } + break; + default: + panic("IDE controller write of unknown register block type!\n"); } + DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", + offset, req->size, dword); + return No_Fault; } @@ -609,14 +695,14 @@ IdeController::serialize(std::ostream &os) SERIALIZE_SCALAR(bmi_size); // Serialize registers - SERIALIZE_ARRAY(bmi_regs, 16); - SERIALIZE_ARRAY(dev, 2); - SERIALIZE_ARRAY(pci_config_regs.data, 22); + SERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs)); + SERIALIZE_ARRAY(dev, sizeof(dev)); + SERIALIZE_ARRAY(pci_config_regs.data, sizeof(pci_config_regs)); // Serialize internal state SERIALIZE_SCALAR(io_enabled); SERIALIZE_SCALAR(bm_enabled); - SERIALIZE_ARRAY(cmd_in_progress, 4); + SERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress)); } void @@ -638,14 +724,14 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(bmi_size); // Unserialize registers - UNSERIALIZE_ARRAY(bmi_regs, 16); - UNSERIALIZE_ARRAY(dev, 2); - UNSERIALIZE_ARRAY(pci_config_regs.data, 22); + UNSERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs)); + UNSERIALIZE_ARRAY(dev, sizeof(dev)); + UNSERIALIZE_ARRAY(pci_config_regs.data, sizeof(pci_config_regs)); // Unserialize internal state UNSERIALIZE_SCALAR(io_enabled); UNSERIALIZE_SCALAR(bm_enabled); - UNSERIALIZE_ARRAY(cmd_in_progress, 4); + UNSERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress)); if (pioInterface) { pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 2164f2f4a..51bdd93b1 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -110,7 +110,22 @@ class IdeController : public PciDev private: /** Registers used for bus master interface */ - uint8_t bmi_regs[16]; + union { + uint8_t data[16]; + + struct { + uint8_t bmic0; + uint8_t padding_0; + uint8_t bmis0; + uint8_t padding_1; + uint32_t bmidtp0; + uint8_t bmic1; + uint8_t padding_2; + uint8_t bmis1; + uint8_t padding_3; + uint32_t bmidtp1; + }; + } bmi_regs; /** Shadows of the device select bit */ uint8_t dev[2]; /** Registers used in device specific PCI configuration */ diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 0d553fb83..39eb2e698 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,8 +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; @@ -160,6 +161,8 @@ IdeDisk::reset(int id) // set the device ready bit status = STATUS_DRDY_BIT; + + cmdReg.error = 0x1; } //// @@ -208,134 +211,113 @@ 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 = 0; DevAction_t action = ACT_NONE; - if (type == COMMAND_BLOCK) { - - if (offset == STATUS_OFFSET) - action = ACT_STAT_READ; - else if (offset == DATA_OFFSET) - action = ACT_DATA_READ_SHORT; - + switch (type) { + case COMMAND_BLOCK: switch (offset) { + // Data transfers occur two bytes at a time case DATA_OFFSET: - data = cmdReg.data; + memcpy(data, &cmdReg.data, sizeof(uint16_t)); + action = ACT_DATA_READ_SHORT; break; 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; + action = ACT_STAT_READ; 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); - - data = status; + break; + default: + panic("Unknown register block!\n"); } if (action != ACT_NONE) updateState(action); - - return data; } void -IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) +IdeDisk::write(const Addr &offset, RegType_t 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.data) = *(uint16_t *)data; - else { - switch (offset) { - case DATA_OFFSET: - cmdReg.data = *data; - break; - case FEATURES_OFFSET: - cmdReg.features = *data; - 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 SELECT_OFFSET: - cmdReg.drive = *data; - break; - case COMMAND_OFFSET: - cmdReg.command = *data; - break; - default: - panic("Invalid IDE command register offset: %#x\n", offset); - } - } - - // 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 (type) { + case COMMAND_BLOCK: + switch (offset) { + case DATA_OFFSET: + memcpy(&cmdReg.data, data, sizeof(uint16_t)); + 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) @@ -787,8 +769,8 @@ IdeDisk::intrPost() intrPending = true; // talk to controller to set interrupt - if (ctrl){ - ctrl->bmi_regs[BMIS0] |= IDEINTS; + if (ctrl) { + ctrl->bmi_regs.bmis0 |= IDEINTS; ctrl->intrPost(); } } diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 0fcd863ec..ceec11925 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -84,6 +84,7 @@ class PrdTableEntry { #define LCYL_OFFSET (4) #define HCYL_OFFSET (5) #define SELECT_OFFSET (6) +#define DRIVE_OFFSET (6) #define STATUS_OFFSET (7) #define COMMAND_OFFSET (7) @@ -105,10 +106,7 @@ class PrdTableEntry { typedef struct CommandReg { uint16_t data; - union { - uint8_t error; - uint8_t features; - }; + uint8_t error; uint8_t sec_count; uint8_t sec_num; uint8_t cyl_low; @@ -272,8 +270,8 @@ class IdeDisk : public SimObject } // Device register read/write - uint16_t read(const Addr &offset, RegType_t type); - void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data); + void read(const Addr &offset, RegType_t type, uint8_t *data); + void write(const Addr &offset, RegType_t type, const uint8_t *data); // Start/abort functions void startDma(const uint32_t &prdTableBase); diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 3aef9b051..f9dcbb8e0 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -329,7 +329,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) *(uint8_t *)data = tm.tm_wday + 1; return No_Fault; case RTC_DOM: - *(uint8_t *)data = tm.tm_mday + 1; + *(uint8_t *)data = tm.tm_mday; return No_Fault; case RTC_MON: *(uint8_t *)data = tm.tm_mon + 1; @@ -340,15 +340,6 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) default: panic("Unknown RTC Address\n"); } - - /* Added for keyboard reads */ - case TSDEV_KBD: - *(uint8_t *)data = 0x00; - return No_Fault; - /* Added for ATA PCI DMA */ - case ATA_PCI_DMA: - *(uint8_t *)data = 0x00; - return No_Fault; default: panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); } @@ -542,7 +533,6 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) case RTC_YEAR: tm.tm_year = *(uint8_t *)data; return No_Fault; - //panic("RTC Write not implmented (rtc.o won't work)\n"); } default: panic("I/O Write - va%#x size %d\n", req->vaddr, req->size); -- 2.30.2