X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=dev%2Fide_ctrl.cc;h=4805570d20bbb861545776214cb4ea56318a7e9d;hb=19fd3439c738e06be8c43078f520054011a385cc;hp=7507a8d7fd29560fbb614d37653fb358046b9fa4;hpb=6807c319b02af31626ab2ed716da6341924eb857;p=gem5.git diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 7507a8d7f..4805570d2 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -126,6 +126,88 @@ IdeController::~IdeController() delete disks[i]; } +//// +// Utility functions +/// + +void +IdeController::parseAddr(const Addr &addr, Addr &offset, bool &primary, + RegType_t &type) +{ + offset = addr; + + if (addr >= pri_cmd_addr && addr < (pri_cmd_addr + pri_cmd_size)) { + offset -= pri_cmd_addr; + type = COMMAND_BLOCK; + primary = true; + } else if (addr >= pri_ctrl_addr && + addr < (pri_ctrl_addr + pri_ctrl_size)) { + offset -= pri_ctrl_addr; + type = CONTROL_BLOCK; + primary = true; + } else if (addr >= sec_cmd_addr && + addr < (sec_cmd_addr + sec_cmd_size)) { + offset -= sec_cmd_addr; + type = COMMAND_BLOCK; + primary = false; + } else if (addr >= sec_ctrl_addr && + addr < (sec_ctrl_addr + sec_ctrl_size)) { + offset -= sec_ctrl_addr; + type = CONTROL_BLOCK; + primary = false; + } else if (addr >= bmi_addr && addr < (bmi_addr + bmi_size)) { + offset -= bmi_addr; + type = BMI_BLOCK; + primary = (offset < BMIC1) ? true : false; + } else { + panic("IDE controller access to invalid address: %#x\n", addr); + } +} + +int +IdeController::getDisk(bool primary) +{ + int disk = 0; + uint8_t *devBit = &dev[0]; + + if (!primary) { + 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 //// @@ -189,7 +271,10 @@ IdeController::cacheAccess(MemReqPtr &req) void IdeController::ReadConfig(int offset, int size, uint8_t *data) { + +#if TRACING_ON Addr origOffset = offset; +#endif if (offset < PCI_DEVICE_SPECIFIC) { PciDev::ReadConfig(offset, size, data); @@ -272,63 +357,74 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) memcpy((void *)&pci_regs[offset], (void *)&data, size); } - if (offset == PCI_COMMAND) { - if (config.data[offset] & IOSE) + // 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) io_enabled = true; else io_enabled = false; - if (config.data[offset] & BME) + if (config.data[offset] & PCI_CMD_BME) bm_enabled = true; else bm_enabled = false; + break; - } else if (data != 0xffffffff) { - switch (offset) { - case PCI0_BASE_ADDR0: + case PCI0_BASE_ADDR0: + if (BARAddrs[0] != 0) { pri_cmd_addr = BARAddrs[0]; if (pioInterface) pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + pri_cmd_size - 1); - pri_cmd_addr = ((pri_cmd_addr | 0xf0000000000) & PA_IMPL_MASK); - break; + pri_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR1: + case PCI0_BASE_ADDR1: + if (BARAddrs[1] != 0) { pri_ctrl_addr = BARAddrs[1]; if (pioInterface) pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + pri_ctrl_size - 1); - pri_ctrl_addr = ((pri_ctrl_addr | 0xf0000000000) & PA_IMPL_MASK); - break; + pri_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR2: + case PCI0_BASE_ADDR2: + if (BARAddrs[2] != 0) { sec_cmd_addr = BARAddrs[2]; if (pioInterface) pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + sec_cmd_size - 1); - sec_cmd_addr = ((sec_cmd_addr | 0xf0000000000) & PA_IMPL_MASK); - break; + sec_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR3: + case PCI0_BASE_ADDR3: + if (BARAddrs[3] != 0) { sec_ctrl_addr = BARAddrs[3]; if (pioInterface) pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + sec_ctrl_size - 1); - sec_ctrl_addr = ((sec_ctrl_addr | 0xf0000000000) & PA_IMPL_MASK); - break; + sec_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR4: + case PCI0_BASE_ADDR4: + if (BARAddrs[4] != 0) { bmi_addr = BARAddrs[4]; if (pioInterface) pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); - bmi_addr = ((bmi_addr | 0xf0000000000) & PA_IMPL_MASK); - break; + bmi_addr &= PA_UNCACHED_MASK; } + break; } } @@ -523,11 +619,71 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) 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, 16); + SERIALIZE_ARRAY(dev, 2); + SERIALIZE_ARRAY(pci_regs, 8); + + // Serialize internal state + SERIALIZE_SCALAR(io_enabled); + SERIALIZE_SCALAR(bm_enabled); + SERIALIZE_ARRAY(cmd_in_progress, 4); } void IdeController::unserialize(Checkpoint *cp, const std::string §ion) { + // 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, 16); + UNSERIALIZE_ARRAY(dev, 2); + UNSERIALIZE_ARRAY(pci_regs, 8); + + // Unserialize internal state + UNSERIALIZE_SCALAR(io_enabled); + UNSERIALIZE_SCALAR(bm_enabled); + UNSERIALIZE_ARRAY(cmd_in_progress, 4); + + if (pioInterface) { + pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + + pri_cmd_size - 1); + pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + + pri_ctrl_size - 1); + pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + + sec_cmd_size - 1); + pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + + sec_ctrl_size - 1); + pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); + } } #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -543,7 +699,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) Param pci_bus; Param pci_dev; Param pci_func; - SimObjectParam host_bus; + SimObjectParam io_bus; SimObjectParam hier; END_DECLARE_SIM_OBJECT_PARAMS(IdeController) @@ -559,7 +715,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM_DFLT(host_bus, "Host bus to attach to", NULL), + INIT_PARAM_DFLT(io_bus, "Host bus to attach to", NULL), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(IdeController) @@ -568,7 +724,7 @@ CREATE_SIM_OBJECT(IdeController) { return new IdeController(getInstanceName(), intr_ctrl, disks, mmu, configspace, configdata, tsunami, pci_bus, - pci_dev, pci_func, host_bus, hier); + pci_dev, pci_func, io_bus, hier); } REGISTER_SIM_OBJECT("IdeController", IdeController)