summaryrefslogtreecommitdiff
path: root/dev/ide_ctrl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/ide_ctrl.cc')
-rw-r--r--dev/ide_ctrl.cc813
1 files changed, 0 insertions, 813 deletions
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
deleted file mode 100644
index 05c756f04..000000000
--- a/dev/ide_ctrl.cc
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * 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
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cstddef>
-#include <cstdlib>
-#include <string>
-#include <vector>
-
-#include "base/trace.hh"
-#include "cpu/intr_control.hh"
-#include "dev/ide_ctrl.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/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(Params *p)
- : PciDev(p)
-{
- // initialize the PIO interface addresses
- pri_cmd_addr = 0;
- pri_cmd_size = BARSize[0];
-
- pri_ctrl_addr = 0;
- pri_ctrl_size = BARSize[1];
-
- sec_cmd_addr = 0;
- sec_cmd_size = BARSize[2];
-
- sec_ctrl_addr = 0;
- sec_ctrl_size = BARSize[3];
-
- // initialize the bus master interface (BMI) address to be configured
- // via PCI
- bmi_addr = 0;
- bmi_size = BARSize[4];
-
- // zero out all of the registers
- memset(bmi_regs.data, 0, sizeof(bmi_regs));
- memset(config_regs.data, 0, sizeof(config_regs.data));
-
- // setup initial values
- // 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 (params()->pio_bus) {
- pioInterface = newPioInterface(name() + ".pio", params()->hier,
- params()->pio_bus, this,
- &IdeController::cacheAccess);
- pioLatency = params()->pio_latency * params()->pio_bus->clockRate;
- }
-
- if (params()->dma_bus) {
- dmaInterface = new DMAInterface<Bus>(name() + ".dma",
- params()->dma_bus,
- params()->dma_bus, 1, true);
- }
-
- // setup the disks attached to controller
- memset(disks, 0, sizeof(disks));
- dev[0] = 0;
- dev[1] = 0;
-
- if (params()->disks.size() > 3)
- panic("IDE controllers support a maximum of 4 devices attached!\n");
-
- for (int i = 0; i < params()->disks.size(); i++) {
- disks[i] = params()->disks[i];
- disks[i]->setController(this, dmaInterface);
- }
-}
-
-IdeController::~IdeController()
-{
- for (int i = 0; i < 4; i++)
- if (disks[i])
- delete disks[i];
-}
-
-////
-// Utility functions
-///
-
-void
-IdeController::parseAddr(const Addr &addr, Addr &offset, IdeChannel &channel,
- IdeRegType &reg_type)
-{
- offset = addr;
-
- if (addr >= pri_cmd_addr && addr < (pri_cmd_addr + pri_cmd_size)) {
- offset -= pri_cmd_addr;
- reg_type = COMMAND_BLOCK;
- channel = PRIMARY;
- } else if (addr >= pri_ctrl_addr &&
- addr < (pri_ctrl_addr + pri_ctrl_size)) {
- offset -= pri_ctrl_addr;
- reg_type = CONTROL_BLOCK;
- channel = PRIMARY;
- } else if (addr >= sec_cmd_addr &&
- addr < (sec_cmd_addr + sec_cmd_size)) {
- offset -= sec_cmd_addr;
- reg_type = COMMAND_BLOCK;
- channel = SECONDARY;
- } else if (addr >= sec_ctrl_addr &&
- addr < (sec_ctrl_addr + sec_ctrl_size)) {
- offset -= sec_ctrl_addr;
- reg_type = CONTROL_BLOCK;
- channel = SECONDARY;
- } else if (addr >= bmi_addr && addr < (bmi_addr + bmi_size)) {
- offset -= bmi_addr;
- reg_type = BMI_BLOCK;
- channel = (offset < BMIC1) ? PRIMARY : SECONDARY;
- } else {
- panic("IDE controller access to invalid address: %#x\n", addr);
- }
-}
-
-int
-IdeController::getDisk(IdeChannel channel)
-{
- int disk = 0;
- uint8_t *devBit = &dev[0];
-
- if (channel == SECONDARY) {
- disk += 2;
- devBit = &dev[1];
- }
-
- disk += *devBit;
-
- assert(*devBit == 0 || *devBit == 1);
-
- return disk;
-}
-
-int
-IdeController::getDisk(IdeDisk *diskPtr)
-{
- for (int i = 0; i < 4; i++) {
- if ((long)diskPtr == (long)disks[i])
- return i;
- }
- return -1;
-}
-
-bool
-IdeController::isDiskSelected(IdeDisk *diskPtr)
-{
- for (int i = 0; i < 4; i++) {
- if ((long)diskPtr == (long)disks[i]) {
- // is disk is on primary or secondary channel
- int channel = i/2;
- // is disk the master or slave
- int devID = i%2;
-
- return (dev[channel] == devID);
- }
- }
- panic("Unable to find disk by pointer!!\n");
-}
-
-////
-// Command completion
-////
-
-void
-IdeController::setDmaComplete(IdeDisk *disk)
-{
- int diskNum = getDisk(disk);
-
- if (diskNum < 0)
- panic("Unable to find disk based on pointer %#x\n", disk);
-
- if (diskNum < 2) {
- // clear the start/stop bit in the command register
- bmi_regs.bmic0 &= ~SSBM;
- // clear the bus master active bit in the status register
- bmi_regs.bmis0 &= ~BMIDEA;
- // set the interrupt bit
- bmi_regs.bmis0 |= IDEINTS;
- } else {
- // clear the start/stop bit in the command register
- bmi_regs.bmic1 &= ~SSBM;
- // clear the bus master active bit in the status register
- bmi_regs.bmis1 &= ~BMIDEA;
- // set the interrupt bit
- bmi_regs.bmis1 |= IDEINTS;
- }
-}
-
-////
-// Bus timing and bus access functions
-////
-
-Tick
-IdeController::cacheAccess(MemReqPtr &req)
-{
- // @todo Add more accurate timing to cache access
- return curTick + pioLatency;
-}
-
-////
-// Read and write handling
-////
-
-void
-IdeController::readConfig(int offset, int size, uint8_t *data)
-{
- int config_offset;
-
- if (offset < PCI_DEVICE_SPECIFIC) {
- 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");
- }
-
-
-
- } else {
- panic("Read of unimplemented PCI config. register: %x\n", offset);
- }
- switch (size) {
- case sizeof(uint8_t):
- DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n",
- offset, size, (uint32_t)*data);
- break;
- case sizeof(uint16_t):
- DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n",
- offset, size, *(uint16_t*)data);
- break;
- case sizeof(uint32_t):
- DPRINTF(IdeCtrl, "PCI read offset: %#x size: %d data: %#x\n",
- offset, size, *(uint32_t*)data);
- break;
- default:
- panic("Invalid PCI configuration read size!\n");
- }
-
-}
-
-void
-IdeController::writeConfig(int offset, int size, const uint8_t *data)
-{
- int config_offset;
-
- if (offset < PCI_DEVICE_SPECIFIC) {
- PciDev::writeConfig(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):
- 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);
- }
-
- switch(size) {
- case sizeof(uint8_t):
- DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n",
- offset, size, (uint32_t)*data);
- break;
- case sizeof(uint16_t):
- DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n",
- offset, size, *(uint16_t*)data);
- break;
- case sizeof(uint32_t):
- DPRINTF(IdeCtrl, "PCI write offset: %#x size: %d data: %#x\n",
- offset, size, *(uint32_t*)data);
- break;
- default:
- panic("Invalid PCI configuration write size!\n");
- }
-
- // Catch the writes to specific PCI registers that have side affects
- // (like updating the PIO ranges)
- switch (offset) {
- case PCI_COMMAND:
- if (letoh(config.command) & PCI_CMD_IOSE)
- io_enabled = true;
- else
- io_enabled = false;
-
- if (letoh(config.command) & PCI_CMD_BME)
- bm_enabled = true;
- else
- bm_enabled = false;
- break;
-
- case PCI0_BASE_ADDR0:
- if (BARAddrs[0] != 0) {
- pri_cmd_addr = BARAddrs[0];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(pri_cmd_addr,
- pri_cmd_size));
-
- pri_cmd_addr &= EV5::PAddrUncachedMask;
- }
- break;
-
- case PCI0_BASE_ADDR1:
- if (BARAddrs[1] != 0) {
- pri_ctrl_addr = BARAddrs[1];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(pri_ctrl_addr,
- pri_ctrl_size));
-
- pri_ctrl_addr &= EV5::PAddrUncachedMask;
- }
- break;
-
- case PCI0_BASE_ADDR2:
- if (BARAddrs[2] != 0) {
- sec_cmd_addr = BARAddrs[2];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(sec_cmd_addr,
- sec_cmd_size));
-
- sec_cmd_addr &= EV5::PAddrUncachedMask;
- }
- break;
-
- case PCI0_BASE_ADDR3:
- if (BARAddrs[3] != 0) {
- sec_ctrl_addr = BARAddrs[3];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(sec_ctrl_addr,
- sec_ctrl_size));
-
- sec_ctrl_addr &= EV5::PAddrUncachedMask;
- }
- break;
-
- case PCI0_BASE_ADDR4:
- if (BARAddrs[4] != 0) {
- bmi_addr = BARAddrs[4];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
-
- bmi_addr &= EV5::PAddrUncachedMask;
- }
- break;
- }
-}
-
-Fault
-IdeController::read(MemReqPtr &req, uint8_t *data)
-{
- Addr offset;
- IdeChannel channel;
- IdeRegType reg_type;
- int disk;
-
- parseAddr(req->paddr, offset, channel, reg_type);
-
- if (!io_enabled)
- 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;
-
- case COMMAND_BLOCK:
- 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]->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");
- }
-
- if (req->size == 1)
- DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, req->size, (uint32_t)*data);
- else if (req->size == 2)
- DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, req->size, *(uint16_t*)data);
- else
- DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, req->size, *(uint32_t*)data);
-
- return NoFault;
-}
-
-Fault
-IdeController::write(MemReqPtr &req, const uint8_t *data)
-{
- Addr offset;
- IdeChannel channel;
- IdeRegType reg_type;
- int disk;
- uint8_t oldVal, newVal;
-
- parseAddr(req->paddr, offset, channel, reg_type);
-
- if (!io_enabled)
- return NoFault;
-
- switch (reg_type) {
- case BMI_BLOCK:
- if (!bm_enabled)
- return NoFault;
-
- switch (offset) {
- // Bus master IDE command register
- case BMIC1:
- case BMIC0:
- if (req->size != sizeof(uint8_t))
- panic("Invalid BMIC write size: %x\n", req->size);
-
- // select the current disk based on DEV bit
- disk = getDisk(channel);
-
- oldVal = bmi_regs.chan[channel].bmic;
- newVal = *data;
-
- // if a DMA transfer is in progress, R/W control cannot change
- if (oldVal & SSBM) {
- if ((oldVal & RWCON) ^ (newVal & RWCON)) {
- (oldVal & RWCON) ? newVal |= RWCON : newVal &= ~RWCON;
- }
- }
-
- // see if the start/stop bit is being changed
- if ((oldVal & SSBM) ^ (newVal & SSBM)) {
- if (oldVal & SSBM) {
- // stopping DMA transfer
- DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
-
- // clear the BMIDEA bit
- 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",
- disk);
-
- // inform the disk of the DMA transfer abort
- disks[disk]->abortDma();
- } else {
- // starting DMA transfer
- DPRINTF(IdeCtrl, "Starting DMA transfer\n");
-
- // set the BMIDEA bit
- 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
- disks[disk]->startDma(letoh(bmi_regs.chan[channel].bmidtp));
- }
- }
-
- // update the register value
- bmi_regs.chan[channel].bmic = newVal;
- break;
-
- // Bus master IDE status register
- case BMIS0:
- case BMIS1:
- if (req->size != sizeof(uint8_t))
- panic("Invalid BMIS write size: %x\n", req->size);
-
- oldVal = bmi_regs.chan[channel].bmis;
- newVal = *data;
-
- // the BMIDEA bit is RO
- newVal |= (oldVal & BMIDEA);
-
- // to reset (set 0) IDEINTS and IDEDMAE, write 1 to each
- if ((oldVal & IDEINTS) && (newVal & IDEINTS))
- newVal &= ~IDEINTS; // clear the interrupt?
- else
- (oldVal & IDEINTS) ? newVal |= IDEINTS : newVal &= ~IDEINTS;
-
- if ((oldVal & IDEDMAE) && (newVal & IDEDMAE))
- newVal &= ~IDEDMAE;
- else
- (oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE;
-
- 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);
-
- uint32_t host_data = letoh(*(uint32_t*)data);
- host_data &= ~0x3;
- bmi_regs.chan[channel].bmidtp = htole(host_data);
- }
- break;
-
- default:
- if (req->size != sizeof(uint8_t) &&
- req->size != sizeof(uint16_t) &&
- req->size != sizeof(uint32_t))
- panic("IDE controller write of invalid write size: %x\n",
- req->size);
-
- // do a default copy of data into the registers
- 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");
- }
- if (req->size == 1)
- DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
- offset, req->size, (uint32_t)*data);
- else if (req->size == 2)
- DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
- offset, req->size, *(uint16_t*)data);
- else
- DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
- offset, req->size, *(uint32_t*)data);
-
- return NoFault;
-}
-
-////
-// Serialization
-////
-
-void
-IdeController::serialize(std::ostream &os)
-{
- // Serialize the PciDev base class
- PciDev::serialize(os);
-
- // Serialize register addresses and sizes
- SERIALIZE_SCALAR(pri_cmd_addr);
- SERIALIZE_SCALAR(pri_cmd_size);
- SERIALIZE_SCALAR(pri_ctrl_addr);
- SERIALIZE_SCALAR(pri_ctrl_size);
- SERIALIZE_SCALAR(sec_cmd_addr);
- SERIALIZE_SCALAR(sec_cmd_size);
- SERIALIZE_SCALAR(sec_ctrl_addr);
- SERIALIZE_SCALAR(sec_ctrl_size);
- SERIALIZE_SCALAR(bmi_addr);
- SERIALIZE_SCALAR(bmi_size);
-
- // Serialize registers
- 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,
- sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
-}
-
-void
-IdeController::unserialize(Checkpoint *cp, const std::string &section)
-{
- // Unserialize the PciDev base class
- PciDev::unserialize(cp, section);
-
- // Unserialize register addresses and sizes
- UNSERIALIZE_SCALAR(pri_cmd_addr);
- UNSERIALIZE_SCALAR(pri_cmd_size);
- UNSERIALIZE_SCALAR(pri_ctrl_addr);
- UNSERIALIZE_SCALAR(pri_ctrl_size);
- UNSERIALIZE_SCALAR(sec_cmd_addr);
- UNSERIALIZE_SCALAR(sec_cmd_size);
- UNSERIALIZE_SCALAR(sec_ctrl_addr);
- UNSERIALIZE_SCALAR(sec_ctrl_size);
- UNSERIALIZE_SCALAR(bmi_addr);
- UNSERIALIZE_SCALAR(bmi_size);
-
- // Unserialize registers
- 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,
- sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
-
- if (pioInterface) {
- pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size));
- pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size));
- pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size));
- pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size));
- pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
- }
-}
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
-
- Param<Addr> addr;
- SimObjectVectorParam<IdeDisk *> disks;
- SimObjectParam<MemoryController *> mmu;
- SimObjectParam<PciConfigAll *> configspace;
- SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Platform *> platform;
- Param<uint32_t> pci_bus;
- Param<uint32_t> pci_dev;
- Param<uint32_t> pci_func;
- SimObjectParam<Bus *> pio_bus;
- SimObjectParam<Bus *> dma_bus;
- Param<Tick> pio_latency;
- SimObjectParam<HierParams *> hier;
-
-END_DECLARE_SIM_OBJECT_PARAMS(IdeController)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
-
- 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(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(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)
-
-END_INIT_SIM_OBJECT_PARAMS(IdeController)
-
-CREATE_SIM_OBJECT(IdeController)
-{
- 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)
-
-#endif //DOXYGEN_SHOULD_SKIP_THIS