#include "sim/sim_object.hh"
using namespace std;
+using namespace TheISA;
////
// Initialization and destruction
bm_enabled = false;
memset(cmd_in_progress, 0, sizeof(cmd_in_progress));
+ pioInterface = NULL;
+ dmaInterface = NULL;
// create the PIO and DMA interfaces
- if (params()->host_bus) {
- pioInterface = newPioInterface(name(), params()->hier,
- params()->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;
+ }
+ if (params()->dma_bus) {
dmaInterface = new DMAInterface<Bus>(name() + ".dma",
- params()->host_bus,
- params()->host_bus, 1,
- true);
- pioLatency = params()->pio_latency * params()->host_bus->clockRate;
+ 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;
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;
}
}
-Fault
+Fault *
IdeController::read(MemReqPtr &req, uint8_t *data)
{
Addr offset;
parseAddr(req->paddr, offset, channel, reg_type);
if (!io_enabled)
- return No_Fault;
+ return NoFault;
switch (reg_type) {
case BMI_BLOCK:
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;
parseAddr(req->paddr, offset, channel, reg_type);
if (!io_enabled)
- return No_Fault;
+ return NoFault;
switch (reg_type) {
case BMI_BLOCK:
if (!bm_enabled)
- return No_Fault;
+ return NoFault;
switch (offset) {
// Bus master IDE command register
// select the current disk based on DEV bit
disk = getDisk(channel);
- oldVal = letoh(bmi_regs.chan[channel].bmic);
- newVal = letoh(*data);
+ oldVal = bmi_regs.chan[channel].bmic;
+ newVal = *data;
// if a DMA transfer is in progress, R/W control cannot change
if (oldVal & SSBM) {
DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
// clear the BMIDEA bit
- bmi_regs.chan[channel].bmis = letoh(
- letoh(bmi_regs.chan[channel].bmis) & ~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",
DPRINTF(IdeCtrl, "Starting DMA transfer\n");
// set the BMIDEA bit
- bmi_regs.chan[channel].bmis = letoh(
- letoh(bmi_regs.chan[channel].bmis) | 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",
}
// update the register value
- bmi_regs.chan[channel].bmic = letoh(newVal);
+ bmi_regs.chan[channel].bmic = newVal;
break;
// Bus master IDE status register
if (req->size != sizeof(uint8_t))
panic("Invalid BMIS write size: %x\n", req->size);
- oldVal = letoh(bmi_regs.chan[channel].bmis);
- newVal = letoh(*data);
+ oldVal = bmi_regs.chan[channel].bmis;
+ newVal = *data;
// the BMIDEA bit is RO
newVal |= (oldVal & BMIDEA);
else
(oldVal & IDEDMAE) ? newVal |= IDEDMAE : newVal &= ~IDEDMAE;
- bmi_regs.chan[channel].bmis = letoh(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);
- bmi_regs.chan[channel].bmidtp = letoh(
- letoh(*(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:
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
offset, req->size, *(uint32_t*)data);
- return No_Fault;
+ return NoFault;
}
////
SERIALIZE_SCALAR(bmi_size);
// Serialize registers
- SERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
- SERIALIZE_ARRAY(dev, sizeof(dev));
- SERIALIZE_ARRAY(config_regs.data, sizeof(config_regs));
+ 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));
+ SERIALIZE_ARRAY(cmd_in_progress,
+ sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
}
void
UNSERIALIZE_SCALAR(bmi_size);
// Unserialize registers
- UNSERIALIZE_ARRAY(bmi_regs.data, sizeof(bmi_regs));
- UNSERIALIZE_ARRAY(dev, sizeof(dev));
- UNSERIALIZE_ARRAY(config_regs.data, sizeof(config_regs));
+ 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));
+ 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));
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
- SimObjectParam<Bus *> io_bus;
+ SimObjectParam<Bus *> pio_bus;
+ SimObjectParam<Bus *> dma_bus;
Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
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)
params->functionNum = pci_func;
params->disks = disks;
- params->host_bus = io_bus;
+ params->pio_bus = pio_bus;
+ params->dma_bus = dma_bus;
params->pio_latency = pio_latency;
params->hier = hier;
return new IdeController(params);