device.hh revision 2565
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* @file 30 * Interface for devices using PCI configuration 31 */ 32 33#ifndef __DEV_PCIDEV_HH__ 34#define __DEV_PCIDEV_HH__ 35 36#include "dev/io_device.hh" 37#include "dev/pcireg.h" 38#include "dev/platform.hh" 39 40#define BAR_IO_MASK 0x3 41#define BAR_MEM_MASK 0xF 42#define BAR_IO_SPACE_BIT 0x1 43#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT) 44#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); 45 46class PciConfigAll; 47 48 49/** 50 * This class encapulates the first 64 bytes of a singles PCI 51 * devices config space that in configured by the configuration file. 52 */ 53class PciConfigData : public SimObject 54{ 55 public: 56 /** 57 * Constructor to initialize the devices config space to 0. 58 */ 59 PciConfigData(const std::string &name) 60 : SimObject(name) 61 { 62 memset(config.data, 0, sizeof(config.data)); 63 memset(BARAddrs, 0, sizeof(BARAddrs)); 64 memset(BARSize, 0, sizeof(BARSize)); 65 } 66 67 /** The first 64 bytes */ 68 PCIConfig config; 69 70 /** The size of the BARs */ 71 uint32_t BARSize[6]; 72 73 /** The addresses of the BARs */ 74 Addr BARAddrs[6]; 75}; 76 77/** 78 * PCI device, base implemnation is only config space. 79 * Each device is connected to a PCIConfigSpace device 80 * which returns -1 for everything but the pcidevs that 81 * register with it. This object registers with the PCIConfig space 82 * object. 83 */ 84class PciDev : public DmaDevice 85{ 86 public: 87 struct Params : public ::PioDevice::Params 88 { 89 /** 90 * A pointer to the configspace all object that calls us when 91 * a read comes to this particular device/function. 92 */ 93 PciConfigAll *configSpace; 94 95 /** 96 * A pointer to the object that contains the first 64 bytes of 97 * config space 98 */ 99 PciConfigData *configData; 100 101 /** The bus number we are on */ 102 uint32_t busNum; 103 104 /** The device number we have */ 105 uint32_t deviceNum; 106 107 /** The function number */ 108 uint32_t functionNum; 109 110 /** The latency for pio accesses. */ 111 Tick pio_delay; 112 }; 113 114 public: 115 const Params *params() const { return (const Params *)_params; } 116 117 protected: 118 /** The current config space. Unlike the PciConfigData this is 119 * updated during simulation while continues to reflect what was 120 * in the config file. 121 */ 122 PCIConfig config; 123 124 /** The size of the BARs */ 125 uint32_t BARSize[6]; 126 127 /** The current address mapping of the BARs */ 128 Addr BARAddrs[6]; 129 130 bool 131 isBAR(Addr addr, int bar) const 132 { 133 assert(bar >= 0 && bar < 6); 134 return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar]; 135 } 136 137 int 138 getBAR(Addr addr) 139 { 140 for (int i = 0; i <= 5; ++i) 141 if (isBAR(addr, i)) 142 return i; 143 144 return -1; 145 } 146 147 bool 148 getBAR(Addr paddr, Addr &daddr, int &bar) 149 { 150 int b = getBAR(paddr); 151 if (b < 0) 152 return false; 153 154 daddr = paddr - BARAddrs[b]; 155 bar = b; 156 return true; 157 } 158 159 protected: 160 Platform *plat; 161 PciConfigData *configData; 162 Tick pioDelay; 163 164 public: 165 Addr pciToDma(Addr pciAddr) const 166 { return plat->pciToDma(pciAddr); } 167 168 void 169 intrPost() 170 { plat->postPciInt(configData->config.interruptLine); } 171 172 void 173 intrClear() 174 { plat->clearPciInt(configData->config.interruptLine); } 175 176 uint8_t 177 interruptLine() 178 { return configData->config.interruptLine; } 179 180 /** return the address ranges that this device responds to. 181 * @params range_list range list to populate with ranges 182 */ 183 void addressRanges(AddrRangeList &range_list); 184 185 /** 186 * Constructor for PCI Dev. This function copies data from the 187 * config file object PCIConfigData and registers the device with 188 * a PciConfigAll object. 189 */ 190 PciDev(Params *params); 191 192 /** 193 * Write to the PCI config space data that is stored locally. This may be 194 * overridden by the device but at some point it will eventually call this 195 * for normal operations that it does not need to override. 196 * @param offset the offset into config space 197 * @param size the size of the write 198 * @param data the data to write 199 */ 200 virtual void writeConfig(int offset, const uint8_t data); 201 virtual void writeConfig(int offset, const uint16_t data); 202 virtual void writeConfig(int offset, const uint32_t data); 203 204 205 /** 206 * Read from the PCI config space data that is stored locally. This may be 207 * overridden by the device but at some point it will eventually call this 208 * for normal operations that it does not need to override. 209 * @param offset the offset into config space 210 * @param size the size of the read 211 * @param data pointer to the location where the read value should be stored 212 */ 213 virtual void readConfig(int offset, uint8_t *data); 214 virtual void readConfig(int offset, uint16_t *data); 215 virtual void readConfig(int offset, uint32_t *data); 216 217 /** 218 * Serialize this object to the given output stream. 219 * @param os The stream to serialize to. 220 */ 221 virtual void serialize(std::ostream &os); 222 223 /** 224 * Reconstruct the state of this object from a checkpoint. 225 * @param cp The checkpoint use. 226 * @param section The section name of this object 227 */ 228 virtual void unserialize(Checkpoint *cp, const std::string §ion); 229}; 230#endif // __DEV_PCIDEV_HH__ 231