diff options
Diffstat (limited to 'dev/pcidev.cc')
-rw-r--r-- | dev/pcidev.cc | 427 |
1 files changed, 0 insertions, 427 deletions
diff --git a/dev/pcidev.cc b/dev/pcidev.cc deleted file mode 100644 index a05ee3803..000000000 --- a/dev/pcidev.cc +++ /dev/null @@ -1,427 +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. - */ - -/* @file - * A single PCI device configuration space entry. - */ - -#include <list> -#include <sstream> -#include <string> -#include <vector> - -#include "base/inifile.hh" -#include "base/misc.hh" -#include "base/str.hh" // for to_number -#include "base/trace.hh" -#include "dev/pcidev.hh" -#include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/functional/memory_control.hh" -#include "sim/builder.hh" -#include "sim/param.hh" -#include "sim/root.hh" -#include "dev/tsunamireg.h" - -using namespace std; - -PciDev::PciDev(Params *p) - : DmaDevice(p->name, p->plat), _params(p), plat(p->plat), - configData(p->configData) -{ - // copy the config data from the PciConfigData object - if (configData) { - memcpy(config.data, configData->config.data, sizeof(config.data)); - memcpy(BARSize, configData->BARSize, sizeof(BARSize)); - memcpy(BARAddrs, configData->BARAddrs, sizeof(BARAddrs)); - } else - panic("NULL pointer to configuration data"); - - // Setup pointer in config space to point to this entry - if (p->configSpace->deviceExists(p->deviceNum, p->functionNum)) - panic("Two PCI devices occuping same dev: %#x func: %#x", - p->deviceNum, p->functionNum); - else - p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); -} - -Fault -PciDev::read(MemReqPtr &req, uint8_t *data) -{ return NoFault; } - -Fault -PciDev::write(MemReqPtr &req, const uint8_t *data) -{ return NoFault; } - -Fault -PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } - -void -PciDev::readConfig(int offset, int size, uint8_t *data) -{ - if (offset >= PCI_DEVICE_SPECIFIC) - panic("Device specific PCI config space not implemented!\n"); - - switch(size) { - case sizeof(uint8_t): - *data = config.data[offset]; - break; - case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&config.data[offset]; - break; - case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&config.data[offset]; - break; - default: - panic("Invalid PCI configuration read size!\n"); - } - - DPRINTF(PCIDEV, - "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, - *(uint32_t*)data); -} - -void -PciDev::writeConfig(int offset, int size, const uint8_t *data) -{ - if (offset >= PCI_DEVICE_SPECIFIC) - panic("Device specific PCI config space not implemented!\n"); - - uint8_t &data8 = *(uint8_t*)data; - uint16_t &data16 = *(uint16_t*)data; - uint32_t &data32 = *(uint32_t*)data; - - DPRINTF(PCIDEV, - "write device: %#x function: %#x reg: %#x size: %d data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, data32); - - switch (size) { - case sizeof(uint8_t): // 1-byte access - switch (offset) { - case PCI0_INTERRUPT_LINE: - config.interruptLine = data8; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data8; - case PCI_LATENCY_TIMER: - config.latencyTimer = data8; - break; - /* Do nothing for these read-only registers */ - case PCI0_INTERRUPT_PIN: - case PCI0_MINIMUM_GRANT: - case PCI0_MAXIMUM_LATENCY: - case PCI_CLASS_CODE: - case PCI_REVISION_ID: - break; - default: - panic("writing to a read only register"); - } - break; - - case sizeof(uint16_t): // 2-byte access - switch (offset) { - case PCI_COMMAND: - config.command = data16; - case PCI_STATUS: - config.status = data16; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data16; - break; - default: - panic("writing to a read only register"); - } - break; - - case sizeof(uint32_t): // 4-byte access - switch (offset) { - case PCI0_BASE_ADDR0: - case PCI0_BASE_ADDR1: - case PCI0_BASE_ADDR2: - case PCI0_BASE_ADDR3: - case PCI0_BASE_ADDR4: - case PCI0_BASE_ADDR5: - - uint32_t barnum, bar_mask; - Addr base_addr, base_size, space_base; - - barnum = BAR_NUMBER(offset); - - if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) { - bar_mask = BAR_IO_MASK; - space_base = TSUNAMI_PCI0_IO; - } else { - bar_mask = BAR_MEM_MASK; - space_base = TSUNAMI_PCI0_MEMORY; - } - - // Writing 0xffffffff to a BAR tells the card to set the - // value of the bar to size of memory it needs - if (letoh(data32) == 0xffffffff) { - // This is I/O Space, bottom two bits are read only - - config.baseAddr[barnum] = letoh( - (~(BARSize[barnum] - 1) & ~bar_mask) | - (letoh(config.baseAddr[barnum]) & bar_mask)); - } else { - MemoryController *mmu = params()->mmu; - - config.baseAddr[barnum] = letoh( - (letoh(data32) & ~bar_mask) | - (letoh(config.baseAddr[barnum]) & bar_mask)); - - if (letoh(config.baseAddr[barnum]) & ~bar_mask) { - base_addr = (letoh(data32) & ~bar_mask) + space_base; - base_size = BARSize[barnum]; - - // It's never been set - if (BARAddrs[barnum] == 0) - mmu->add_child((FunctionalMemory *)this, - RangeSize(base_addr, base_size)); - else - mmu->update_child((FunctionalMemory *)this, - RangeSize(BARAddrs[barnum], base_size), - RangeSize(base_addr, base_size)); - - BARAddrs[barnum] = base_addr; - } - } - break; - - case PCI0_ROM_BASE_ADDR: - if (letoh(data32) == 0xfffffffe) - config.expansionROM = htole((uint32_t)0xffffffff); - else - config.expansionROM = data32; - break; - - case PCI_COMMAND: - // This could also clear some of the error bits in the Status - // register. However they should never get set, so lets ignore - // it for now - config.command = data16; - break; - - default: - DPRINTF(PCIDEV, "Writing to a read only register"); - } - break; - - default: - panic("invalid access size"); - } -} - -void -PciDev::serialize(ostream &os) -{ - SERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0])); - SERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); - SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0])); -} - -void -PciDev::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0])); - UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); - UNSERIALIZE_ARRAY(config.data, - sizeof(config.data) / sizeof(config.data[0])); - - // Add the MMU mappings for the BARs - for (int i=0; i < 6; i++) { - if (BARAddrs[i] != 0) - params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); - } -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) - - Param<uint16_t> VendorID; - Param<uint16_t> DeviceID; - Param<uint16_t> Command; - Param<uint16_t> Status; - Param<uint8_t> Revision; - Param<uint8_t> ProgIF; - Param<uint8_t> SubClassCode; - Param<uint8_t> ClassCode; - Param<uint8_t> CacheLineSize; - Param<uint8_t> LatencyTimer; - Param<uint8_t> HeaderType; - Param<uint8_t> BIST; - Param<uint32_t> BAR0; - Param<uint32_t> BAR1; - Param<uint32_t> BAR2; - Param<uint32_t> BAR3; - Param<uint32_t> BAR4; - Param<uint32_t> BAR5; - Param<uint32_t> CardbusCIS; - Param<uint16_t> SubsystemVendorID; - Param<uint16_t> SubsystemID; - Param<uint32_t> ExpansionROM; - Param<uint8_t> InterruptLine; - Param<uint8_t> InterruptPin; - Param<uint8_t> MinimumGrant; - Param<uint8_t> MaximumLatency; - Param<uint32_t> BAR0Size; - Param<uint32_t> BAR1Size; - Param<uint32_t> BAR2Size; - Param<uint32_t> BAR3Size; - Param<uint32_t> BAR4Size; - Param<uint32_t> BAR5Size; - -END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) - -BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData) - - INIT_PARAM(VendorID, "Vendor ID"), - INIT_PARAM(DeviceID, "Device ID"), - INIT_PARAM_DFLT(Command, "Command Register", 0x00), - INIT_PARAM_DFLT(Status, "Status Register", 0x00), - INIT_PARAM_DFLT(Revision, "Device Revision", 0x00), - INIT_PARAM_DFLT(ProgIF, "Programming Interface", 0x00), - INIT_PARAM(SubClassCode, "Sub-Class Code"), - INIT_PARAM(ClassCode, "Class Code"), - INIT_PARAM_DFLT(CacheLineSize, "System Cacheline Size", 0x00), - INIT_PARAM_DFLT(LatencyTimer, "PCI Latency Timer", 0x00), - INIT_PARAM_DFLT(HeaderType, "PCI Header Type", 0x00), - INIT_PARAM_DFLT(BIST, "Built In Self Test", 0x00), - INIT_PARAM_DFLT(BAR0, "Base Address Register 0", 0x00), - INIT_PARAM_DFLT(BAR1, "Base Address Register 1", 0x00), - INIT_PARAM_DFLT(BAR2, "Base Address Register 2", 0x00), - INIT_PARAM_DFLT(BAR3, "Base Address Register 3", 0x00), - INIT_PARAM_DFLT(BAR4, "Base Address Register 4", 0x00), - INIT_PARAM_DFLT(BAR5, "Base Address Register 5", 0x00), - INIT_PARAM_DFLT(CardbusCIS, "Cardbus Card Information Structure", 0x00), - INIT_PARAM_DFLT(SubsystemVendorID, "Subsystem Vendor ID", 0x00), - INIT_PARAM_DFLT(SubsystemID, "Subsystem ID", 0x00), - INIT_PARAM_DFLT(ExpansionROM, "Expansion ROM Base Address Register", 0x00), - INIT_PARAM(InterruptLine, "Interrupt Line Register"), - INIT_PARAM(InterruptPin, "Interrupt Pin Register"), - INIT_PARAM_DFLT(MinimumGrant, "Minimum Grant", 0x00), - INIT_PARAM_DFLT(MaximumLatency, "Maximum Latency", 0x00), - INIT_PARAM_DFLT(BAR0Size, "Base Address Register 0 Size", 0x00), - INIT_PARAM_DFLT(BAR1Size, "Base Address Register 1 Size", 0x00), - INIT_PARAM_DFLT(BAR2Size, "Base Address Register 2 Size", 0x00), - INIT_PARAM_DFLT(BAR3Size, "Base Address Register 3 Size", 0x00), - INIT_PARAM_DFLT(BAR4Size, "Base Address Register 4 Size", 0x00), - INIT_PARAM_DFLT(BAR5Size, "Base Address Register 5 Size", 0x00) - -END_INIT_SIM_OBJECT_PARAMS(PciConfigData) - -CREATE_SIM_OBJECT(PciConfigData) -{ - PciConfigData *data = new PciConfigData(getInstanceName()); - - data->config.vendor = htole(VendorID); - data->config.device = htole(DeviceID); - data->config.command = htole(Command); - data->config.status = htole(Status); - data->config.revision = htole(Revision); - data->config.progIF = htole(ProgIF); - data->config.subClassCode = htole(SubClassCode); - data->config.classCode = htole(ClassCode); - data->config.cacheLineSize = htole(CacheLineSize); - data->config.latencyTimer = htole(LatencyTimer); - data->config.headerType = htole(HeaderType); - data->config.bist = htole(BIST); - - data->config.baseAddr0 = htole(BAR0); - data->config.baseAddr1 = htole(BAR1); - data->config.baseAddr2 = htole(BAR2); - data->config.baseAddr3 = htole(BAR3); - data->config.baseAddr4 = htole(BAR4); - data->config.baseAddr5 = htole(BAR5); - data->config.cardbusCIS = htole(CardbusCIS); - data->config.subsystemVendorID = htole(SubsystemVendorID); - data->config.subsystemID = htole(SubsystemVendorID); - data->config.expansionROM = htole(ExpansionROM); - data->config.interruptLine = htole(InterruptLine); - data->config.interruptPin = htole(InterruptPin); - data->config.minimumGrant = htole(MinimumGrant); - data->config.maximumLatency = htole(MaximumLatency); - - data->BARSize[0] = BAR0Size; - data->BARSize[1] = BAR1Size; - data->BARSize[2] = BAR2Size; - data->BARSize[3] = BAR3Size; - data->BARSize[4] = BAR4Size; - data->BARSize[5] = BAR5Size; - - return data; -} - -REGISTER_SIM_OBJECT("PciConfigData", PciConfigData) - -#endif // DOXYGEN_SHOULD_SKIP_THIS |