X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=dev%2Fide_ctrl.cc;h=18c988b81d7a1eb3426faac6129a8756777a2d6c;hb=466284b5d29ad0d44c1b020353cf7521be2b90de;hp=dbec6d7433c0bf8380c929001cf1641e7e17b60e;hpb=b881408ed76a0ad9bd6a3992230b89dcec3a25bd;p=gem5.git diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index dbec6d743..18c988b81 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 The Regents of The University of Michigan + * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,39 +33,30 @@ #include "base/trace.hh" #include "cpu/intr_control.hh" -#include "dev/dma.hh" -#include "dev/pcireg.h" -#include "dev/pciconfigall.hh" -#include "dev/ide_disk.hh" #include "dev/ide_ctrl.hh" -#include "dev/tsunami_cchip.hh" +#include "dev/ide_disk.hh" +#include "dev/pciconfigall.hh" +#include "dev/pcireg.h" +#include "dev/platform.hh" #include "mem/bus/bus.hh" +#include "mem/bus/dma_interface.hh" #include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface_impl.hh" -#include "mem/bus/dma_interface.hh" -#include "dev/tsunami.hh" -#include "mem/functional_mem/memory_control.hh" -#include "mem/functional_mem/physical_memory.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" using namespace std; +using namespace TheISA; //// // Initialization and destruction //// -IdeController::IdeController(const string &name, IntrControl *ic, - const vector &new_disks, - MemoryController *mmu, PciConfigAll *cf, - PciConfigData *cd, Tsunami *t, uint32_t bus_num, - uint32_t dev_num, uint32_t func_num, - Bus *host_bus, Tick pio_latency, HierParams *hier) - : PciDev(name, mmu, cf, cd, bus_num, dev_num, func_num), tsunami(t) +IdeController::IdeController(Params *p) + : PciDev(p) { - // put back pointer into Tsunami - tsunami->disk_controller = this; - // initialize the PIO interface addresses pri_cmd_addr = 0; pri_cmd_size = BARSize[0]; @@ -85,37 +76,47 @@ IdeController::IdeController(const string &name, IntrControl *ic, bmi_size = BARSize[4]; // zero out all of the registers - memset(bmi_regs, 0, sizeof(bmi_regs)); - memset(pci_regs, 0, sizeof(pci_regs)); + memset(bmi_regs.data, 0, sizeof(bmi_regs)); + memset(config_regs.data, 0, sizeof(config_regs.data)); // setup initial values - *(uint32_t *)&pci_regs[IDETIM] = 0x80008000; // enable both channels - *(uint8_t *)&bmi_regs[BMIS0] = 0x60; - *(uint8_t *)&bmi_regs[BMIS1] = 0x60; + // enable both channels + config_regs.idetim0 = htole((uint16_t)IDETIM_DECODE_EN); + config_regs.idetim1 = htole((uint16_t)IDETIM_DECODE_EN); + bmi_regs.bmis0 = DMA1CAP | DMA0CAP; + bmi_regs.bmis1 = DMA1CAP | DMA0CAP; // reset all internal variables io_enabled = false; bm_enabled = false; memset(cmd_in_progress, 0, sizeof(cmd_in_progress)); + pioInterface = NULL; + dmaInterface = NULL; // create the PIO and DMA interfaces - if (host_bus) { - pioInterface = newPioInterface(name, hier, host_bus, this, + if (params()->pio_bus) { + pioInterface = newPioInterface(name() + ".pio", params()->hier, + params()->pio_bus, this, &IdeController::cacheAccess); + pioLatency = params()->pio_latency * params()->pio_bus->clockRate; + } - dmaInterface = new DMAInterface(name + ".dma", host_bus, - host_bus, 1); - pioLatency = pio_latency * host_bus->clockRatio; + if (params()->dma_bus) { + dmaInterface = new DMAInterface(name() + ".dma", + params()->dma_bus, + params()->dma_bus, 1, true); } // setup the disks attached to controller - memset(disks, 0, sizeof(IdeDisk *) * 4); + memset(disks, 0, sizeof(disks)); + dev[0] = 0; + dev[1] = 0; - if (new_disks.size() > 3) + if (params()->disks.size() > 3) panic("IDE controllers support a maximum of 4 devices attached!\n"); - for (int i = 0; i < new_disks.size(); i++) { - disks[i] = new_disks[i]; + for (int i = 0; i < params()->disks.size(); i++) { + disks[i] = params()->disks[i]; disks[i]->setController(this, dmaInterface); } } @@ -132,46 +133,46 @@ IdeController::~IdeController() /// void -IdeController::parseAddr(const Addr &addr, Addr &offset, bool &primary, - RegType_t &type) +IdeController::parseAddr(const Addr &addr, Addr &offset, IdeChannel &channel, + IdeRegType ®_type) { offset = addr; if (addr >= pri_cmd_addr && addr < (pri_cmd_addr + pri_cmd_size)) { offset -= pri_cmd_addr; - type = COMMAND_BLOCK; - primary = true; + reg_type = COMMAND_BLOCK; + channel = PRIMARY; } else if (addr >= pri_ctrl_addr && addr < (pri_ctrl_addr + pri_ctrl_size)) { offset -= pri_ctrl_addr; - type = CONTROL_BLOCK; - primary = true; + reg_type = CONTROL_BLOCK; + channel = PRIMARY; } else if (addr >= sec_cmd_addr && addr < (sec_cmd_addr + sec_cmd_size)) { offset -= sec_cmd_addr; - type = COMMAND_BLOCK; - primary = false; + reg_type = COMMAND_BLOCK; + channel = SECONDARY; } else if (addr >= sec_ctrl_addr && addr < (sec_ctrl_addr + sec_ctrl_size)) { offset -= sec_ctrl_addr; - type = CONTROL_BLOCK; - primary = false; + reg_type = CONTROL_BLOCK; + channel = SECONDARY; } else if (addr >= bmi_addr && addr < (bmi_addr + bmi_size)) { offset -= bmi_addr; - type = BMI_BLOCK; - primary = (offset < BMIC1) ? true : false; + reg_type = BMI_BLOCK; + channel = (offset < BMIC1) ? PRIMARY : SECONDARY; } else { panic("IDE controller access to invalid address: %#x\n", addr); } } int -IdeController::getDisk(bool primary) +IdeController::getDisk(IdeChannel channel) { int disk = 0; uint8_t *devBit = &dev[0]; - if (!primary) { + if (channel == SECONDARY) { disk += 2; devBit = &dev[1]; } @@ -223,37 +224,21 @@ 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; } } -//// -// Interrupt handling -//// - -void -IdeController::intrPost() -{ - tsunami->cchip->postDRIR(configData->config.hdr.pci0.interruptLine); -} - -void -IdeController::intrClear() -{ - tsunami->cchip->clearDRIR(configData->config.hdr.pci0.interruptLine); -} - //// // Bus timing and bus access functions //// @@ -270,104 +255,81 @@ IdeController::cacheAccess(MemReqPtr &req) //// void -IdeController::ReadConfig(int offset, int size, uint8_t *data) +IdeController::readConfig(int offset, int size, uint8_t *data) { - -#if TRACING_ON - Addr origOffset = offset; -#endif + int config_offset; if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::ReadConfig(offset, size, data); - } else { - if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) { - offset -= PCI_IDE_TIMING; - offset += IDETIM; - - if ((offset + size) > (IDETIM + 4)) - panic("PCI read of IDETIM with invalid size\n"); - } else if (offset == PCI_SLAVE_TIMING) { - offset -= PCI_SLAVE_TIMING; - offset += SIDETIM; - - if ((offset + size) > (SIDETIM + 1)) - panic("PCI read of SIDETIM with invalid size\n"); - } else if (offset == PCI_UDMA33_CTRL) { - offset -= PCI_UDMA33_CTRL; - offset += UDMACTL; - - if ((offset + size) > (UDMACTL + 1)) - panic("PCI read of UDMACTL with invalid size\n"); - } else if (offset >= PCI_UDMA33_TIMING && - offset < (PCI_UDMA33_TIMING + 2)) { - offset -= PCI_UDMA33_TIMING; - offset += UDMATIM; - - if ((offset + size) > (UDMATIM + 2)) - panic("PCI read of UDMATIM with invalid size\n"); - } else { - panic("PCI read of unimplemented register: %x\n", offset); + PciDev::readConfig(offset, size, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + size) <= IDE_CTRL_CONF_END) { + + config_offset = offset - IDE_CTRL_CONF_START; + + switch (size) { + case sizeof(uint8_t): + *data = config_regs.data[config_offset]; + break; + case sizeof(uint16_t): + *(uint16_t*)data = *(uint16_t*)&config_regs.data[config_offset]; + break; + case sizeof(uint32_t): + *(uint32_t*)data = *(uint32_t*)&config_regs.data[config_offset]; + break; + default: + panic("Invalid PCI configuration read size!\n"); } - memcpy((void *)data, (void *)&pci_regs[offset], size); - } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n", + offset, size, *(uint32_t*)data); - DPRINTF(IdeCtrl, "IDE PCI read offset: %#x (%#x) size: %#x data: %#x\n", - origOffset, offset, size, *(uint32_t *)data); + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } } void -IdeController::WriteConfig(int offset, int size, uint32_t data) +IdeController::writeConfig(int offset, int size, const uint8_t *data) { - DPRINTF(IdeCtrl, "IDE PCI write offset: %#x size: %#x data: %#x\n", - offset, size, data); + int config_offset; - // do standard write stuff if in standard PCI space if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::WriteConfig(offset, size, data); - } else { - if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) { - offset -= PCI_IDE_TIMING; - offset += IDETIM; - - if ((offset + size) > (IDETIM + 4)) - panic("PCI write to IDETIM with invalid size\n"); - } else if (offset == PCI_SLAVE_TIMING) { - offset -= PCI_SLAVE_TIMING; - offset += SIDETIM; - - if ((offset + size) > (SIDETIM + 1)) - panic("PCI write to SIDETIM with invalid size\n"); - } else if (offset == PCI_UDMA33_CTRL) { - offset -= PCI_UDMA33_CTRL; - offset += UDMACTL; - - if ((offset + size) > (UDMACTL + 1)) - panic("PCI write to UDMACTL with invalid size\n"); - } else if (offset >= PCI_UDMA33_TIMING && - offset < (PCI_UDMA33_TIMING + 2)) { - offset -= PCI_UDMA33_TIMING; - offset += UDMATIM; - - if ((offset + size) > (UDMATIM + 2)) - panic("PCI write to UDMATIM with invalid size\n"); - } else { - panic("PCI write to unimplemented register: %x\n", offset); - } + PciDev::writeConfig(offset, size, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + size) <= IDE_CTRL_CONF_END) { - memcpy((void *)&pci_regs[offset], (void *)&data, size); + config_offset = offset - IDE_CTRL_CONF_START; + + switch(size) { + case sizeof(uint8_t): + config_regs.data[config_offset] = *data; + break; + case sizeof(uint16_t): + *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data; + break; + case sizeof(uint32_t): + *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data; + 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); + // Catch the writes to specific PCI registers that have side affects // (like updating the PIO ranges) switch (offset) { case PCI_COMMAND: - if (config.data[offset] & PCI_CMD_IOSE) + if (letoh(config.command) & PCI_CMD_IOSE) io_enabled = true; else io_enabled = false; - if (config.data[offset] & PCI_CMD_BME) + if (letoh(config.command) & PCI_CMD_BME) bm_enabled = true; else bm_enabled = false; @@ -380,7 +342,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); - pri_cmd_addr &= PA_UNCACHED_MASK; + pri_cmd_addr &= EV5::PAddrUncachedMask; } break; @@ -391,7 +353,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size)); - pri_ctrl_addr &= PA_UNCACHED_MASK; + pri_ctrl_addr &= EV5::PAddrUncachedMask; } break; @@ -402,7 +364,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size)); - sec_cmd_addr &= PA_UNCACHED_MASK; + sec_cmd_addr &= EV5::PAddrUncachedMask; } break; @@ -413,7 +375,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size)); - sec_ctrl_addr &= PA_UNCACHED_MASK; + sec_ctrl_addr &= EV5::PAddrUncachedMask; } break; @@ -423,88 +385,101 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (pioInterface) pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - bmi_addr &= PA_UNCACHED_MASK; + bmi_addr &= EV5::PAddrUncachedMask; } break; } } -Fault +Fault * IdeController::read(MemReqPtr &req, uint8_t *data) { Addr offset; - bool primary; - bool byte; - bool cmdBlk; - RegType_t type; + IdeChannel channel; + IdeRegType reg_type; int disk; - parseAddr(req->paddr, offset, primary, type); - byte = (req->size == sizeof(uint8_t)) ? true : false; - cmdBlk = (type == COMMAND_BLOCK) ? true : false; + parseAddr(req->paddr, offset, channel, reg_type); if (!io_enabled) - return No_Fault; + return NoFault; + + switch (reg_type) { + case BMI_BLOCK: + switch (req->size) { + case sizeof(uint8_t): + *data = bmi_regs.data[offset]; + break; + case sizeof(uint16_t): + *(uint16_t*)data = *(uint16_t*)&bmi_regs.data[offset]; + break; + case sizeof(uint32_t): + *(uint32_t*)data = *(uint32_t*)&bmi_regs.data[offset]; + break; + default: + panic("IDE read of BMI reg invalid size: %#x\n", req->size); + } + break; - // sanity check the size (allows byte, word, or dword access) - if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) - panic("IDE controller read of invalid size: %#x\n", req->size); + case COMMAND_BLOCK: + case CONTROL_BLOCK: + disk = getDisk(channel); - if (type != BMI_BLOCK) { - assert(req->size != sizeof(uint32_t)); + if (disks[disk] == NULL) + break; - disk = getDisk(primary); - if (disks[disk]) - disks[disk]->read(offset, byte, cmdBlk, data); - } else { - memcpy((void *)data, &bmi_regs[offset], req->size); + switch (offset) { + case DATA_OFFSET: + switch (req->size) { + case sizeof(uint16_t): + disks[disk]->read(offset, reg_type, data); + break; + + case sizeof(uint32_t): + disks[disk]->read(offset, reg_type, data); + disks[disk]->read(offset, reg_type, &data[2]); + break; + + default: + panic("IDE read of data reg invalid size: %#x\n", req->size); + } + break; + default: + if (req->size == sizeof(uint8_t)) { + disks[disk]->read(offset, reg_type, data); + } 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, "IDE read from offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t *)data); + DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", + offset, req->size, *(uint32_t*)data); - return No_Fault; + return NoFault; } -Fault +Fault * IdeController::write(MemReqPtr &req, const uint8_t *data) { Addr offset; - bool primary; - bool byte; - bool cmdBlk; - RegType_t type; + IdeChannel channel; + IdeRegType reg_type; int disk; - - parseAddr(req->paddr, offset, primary, type); - byte = (req->size == sizeof(uint8_t)) ? true : false; - cmdBlk = (type == COMMAND_BLOCK) ? true : false; - - DPRINTF(IdeCtrl, "IDE write from offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t *)data); - uint8_t oldVal, newVal; - if (!io_enabled) - return No_Fault; + parseAddr(req->paddr, offset, channel, reg_type); - if (type == BMI_BLOCK && !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); - } + if (!io_enabled) + return NoFault; - assert(req->size != sizeof(uint32_t)); + switch (reg_type) { + case BMI_BLOCK: + if (!bm_enabled) + return NoFault; - disk = getDisk(primary); - if (disks[disk]) - disks[disk]->write(offset, byte, cmdBlk, data); - } else { switch (offset) { // Bus master IDE command register case BMIC1: @@ -513,9 +488,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) panic("Invalid BMIC write size: %x\n", req->size); // select the current disk based on DEV bit - disk = getDisk(primary); + disk = getDisk(channel); - oldVal = bmi_regs[offset]; + oldVal = bmi_regs.chan[channel].bmic; newVal = *data; // if a DMA transfer is in progress, R/W control cannot change @@ -532,7 +507,8 @@ 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.chan[channel].bmis = + bmi_regs.chan[channel].bmis & ~BMIDEA; if (disks[disk] == NULL) panic("DMA stop for disk %d which does not exist\n", @@ -545,22 +521,20 @@ 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.chan[channel].bmis = + bmi_regs.chan[channel].bmis | BMIDEA; if (disks[disk] == NULL) panic("DMA start for disk %d which does not exist\n", disk); // inform the disk of the DMA transfer start - if (primary) - disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP0]); - else - disks[disk]->startDma(*(uint32_t *)&bmi_regs[BMIDTP1]); + disks[disk]->startDma(letoh(bmi_regs.chan[channel].bmidtp)); } } // update the register value - bmi_regs[offset] = newVal; + bmi_regs.chan[channel].bmic = newVal; break; // Bus master IDE status register @@ -569,7 +543,7 @@ 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]; + oldVal = bmi_regs.chan[channel].bmis; newVal = *data; // the BMIDEA bit is RO @@ -586,16 +560,20 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) else (oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE; - bmi_regs[offset] = newVal; + bmi_regs.chan[channel].bmis = newVal; break; // Bus master IDE descriptor table pointer register case BMIDTP0: case BMIDTP1: - if (req->size != sizeof(uint32_t)) - panic("Invalid BMIDTP write size: %x\n", req->size); + { + if (req->size != sizeof(uint32_t)) + panic("Invalid BMIDTP write size: %x\n", req->size); - *(uint32_t *)&bmi_regs[offset] = *(uint32_t *)data & ~0x3; + uint32_t host_data = letoh(*(uint32_t*)data); + host_data &= ~0x3; + bmi_regs.chan[channel].bmidtp = htole(host_data); + } break; default: @@ -606,11 +584,51 @@ 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(&bmi_regs.data[offset], data, req->size); + } + break; + case COMMAND_BLOCK: + if (offset == IDE_SELECT_OFFSET) { + uint8_t *devBit = &dev[channel]; + *devBit = (letoh(*data) & IDE_SELECT_DEV_BIT) ? 1 : 0; } + // fall-through ok! + case CONTROL_BLOCK: + disk = getDisk(channel); + + if (disks[disk] == NULL) + break; + + switch (offset) { + case DATA_OFFSET: + switch (req->size) { + case sizeof(uint16_t): + disks[disk]->write(offset, reg_type, data); + break; + + case sizeof(uint32_t): + disks[disk]->write(offset, reg_type, data); + disks[disk]->write(offset, reg_type, &data[2]); + break; + default: + panic("IDE write of data reg invalid size: %#x\n", req->size); + } + break; + default: + if (req->size == sizeof(uint8_t)) { + disks[disk]->write(offset, reg_type, data); + } 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"); } - return No_Fault; + DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", + offset, req->size, *(uint32_t*)data); + + return NoFault; } //// @@ -636,14 +654,17 @@ IdeController::serialize(std::ostream &os) SERIALIZE_SCALAR(bmi_size); // Serialize registers - SERIALIZE_ARRAY(bmi_regs, 16); - SERIALIZE_ARRAY(dev, 2); - SERIALIZE_ARRAY(pci_regs, 8); + SERIALIZE_ARRAY(bmi_regs.data, + sizeof(bmi_regs.data) / sizeof(bmi_regs.data[0])); + SERIALIZE_ARRAY(dev, sizeof(dev) / sizeof(dev[0])); + SERIALIZE_ARRAY(config_regs.data, + sizeof(config_regs.data) / sizeof(config_regs.data[0])); // 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) / sizeof(cmd_in_progress[0])); } void @@ -665,14 +686,17 @@ 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_regs, 8); + UNSERIALIZE_ARRAY(bmi_regs.data, + sizeof(bmi_regs.data) / sizeof(bmi_regs.data[0])); + UNSERIALIZE_ARRAY(dev, sizeof(dev) / sizeof(dev[0])); + UNSERIALIZE_ARRAY(config_regs.data, + sizeof(config_regs.data) / sizeof(config_regs.data[0])); // 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) / sizeof(cmd_in_progress[0])); if (pioInterface) { pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); @@ -687,16 +711,17 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) - SimObjectParam intr_ctrl; + Param addr; SimObjectVectorParam disks; SimObjectParam mmu; SimObjectParam configspace; SimObjectParam configdata; - SimObjectParam tsunami; + SimObjectParam platform; Param pci_bus; Param pci_dev; Param pci_func; - SimObjectParam io_bus; + SimObjectParam pio_bus; + SimObjectParam dma_bus; Param pio_latency; SimObjectParam hier; @@ -704,16 +729,17 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeController) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) - INIT_PARAM(intr_ctrl, "Interrupt Controller"), + INIT_PARAM(addr, "Device Address"), INIT_PARAM(disks, "IDE disks attached to this controller"), INIT_PARAM(mmu, "Memory controller"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(tsunami, "Tsunami chipset pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM_DFLT(io_bus, "Host bus to attach to", NULL), + INIT_PARAM(pio_bus, ""), + INIT_PARAM(dma_bus, ""), INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) @@ -721,9 +747,22 @@ END_INIT_SIM_OBJECT_PARAMS(IdeController) CREATE_SIM_OBJECT(IdeController) { - return new IdeController(getInstanceName(), intr_ctrl, disks, mmu, - configspace, configdata, tsunami, pci_bus, - pci_dev, pci_func, io_bus, pio_latency, hier); + IdeController::Params *params = new IdeController::Params; + params->name = getInstanceName(); + params->mmu = mmu; + params->configSpace = configspace; + params->configData = configdata; + params->plat = platform; + params->busNum = pci_bus; + params->deviceNum = pci_dev; + params->functionNum = pci_func; + + params->disks = disks; + params->pio_bus = pio_bus; + params->dma_bus = dma_bus; + params->pio_latency = pio_latency; + params->hier = hier; + return new IdeController(params); } REGISTER_SIM_OBJECT("IdeController", IdeController)