tsunami_pchip.cc revision 2539
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 312855Sgabeblack@google.com * All rights reserved. 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412855Sgabeblack@google.com * this software without specific prior written permission. 1512855Sgabeblack@google.com * 1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712855Sgabeblack@google.com */ 2812855Sgabeblack@google.com 2912855Sgabeblack@google.com/** @file 3012855Sgabeblack@google.com * Tsunami PChip (pci) 3112855Sgabeblack@google.com */ 3212855Sgabeblack@google.com 3312855Sgabeblack@google.com#include <deque> 3412855Sgabeblack@google.com#include <string> 3512855Sgabeblack@google.com#include <vector> 3612855Sgabeblack@google.com 3712855Sgabeblack@google.com#include "arch/alpha/ev5.hh" 3812855Sgabeblack@google.com#include "base/trace.hh" 3912855Sgabeblack@google.com#include "dev/tsunami_pchip.hh" 4012855Sgabeblack@google.com#include "dev/tsunamireg.h" 4112855Sgabeblack@google.com#include "dev/tsunami.hh" 4212855Sgabeblack@google.com#include "mem/bus/bus.hh" 4312855Sgabeblack@google.com#include "mem/bus/pio_interface.hh" 4412855Sgabeblack@google.com#include "mem/bus/pio_interface_impl.hh" 4512855Sgabeblack@google.com#include "mem/functional/memory_control.hh" 4612855Sgabeblack@google.com#include "mem/functional/physical.hh" 4712855Sgabeblack@google.com#include "sim/builder.hh" 4812855Sgabeblack@google.com#include "sim/system.hh" 4912855Sgabeblack@google.com 5012855Sgabeblack@google.comusing namespace std; 5112855Sgabeblack@google.com//Should this be AlphaISA? 5212855Sgabeblack@google.comusing namespace TheISA; 5312855Sgabeblack@google.com 5412855Sgabeblack@google.comTsunamiPChip::TsunamiPChip(Params *p) 5512855Sgabeblack@google.com: BasicPioDevice(p), 5612855Sgabeblack@google.com{ 5712855Sgabeblack@google.com pioSize = 0xfff; 5812855Sgabeblack@google.com 5912855Sgabeblack@google.com for (int i = 0; i < 4; i++) { 6012855Sgabeblack@google.com wsba[i] = 0; 6112855Sgabeblack@google.com wsm[i] = 0; 6212855Sgabeblack@google.com tba[i] = 0; 6312855Sgabeblack@google.com } 6412855Sgabeblack@google.com 6512855Sgabeblack@google.com // initialize pchip control register 6612855Sgabeblack@google.com pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); 6712855Sgabeblack@google.com 6812855Sgabeblack@google.com //Set back pointer in tsunami 6912855Sgabeblack@google.com p->tsunami->pchip = this; 7012855Sgabeblack@google.com} 7112855Sgabeblack@google.com 7212855Sgabeblack@google.comTick 7312855Sgabeblack@google.comTsunamiPChip::read(Packet &pkt) 7412855Sgabeblack@google.com{ 7512855Sgabeblack@google.com assert(pkt.result == Unknown); 7612855Sgabeblack@google.com assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); 7712855Sgabeblack@google.com 78 pkt.time = curTick + pioDelay; 79 Addr daddr = pkt.addr - pioAddr; 80 81 uint64_t *data64; 82 83 if (!pkt.data) { 84 data64 = new uint64_t; 85 pkt.data = (uint8_t*)data64; 86 } else 87 data64 = (uint64_t*)pkt.data; 88 89 DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); 90 91 switch(daddr) { 92 case TSDEV_PC_WSBA0: 93 *data64 = wsba[0]; 94 break; 95 case TSDEV_PC_WSBA1: 96 *data64 = wsba[1]; 97 break; 98 case TSDEV_PC_WSBA2: 99 *data64 = wsba[2]; 100 break; 101 case TSDEV_PC_WSBA3: 102 *data64 = wsba[3]; 103 break; 104 case TSDEV_PC_WSM0: 105 *data64 = wsm[0]; 106 break; 107 case TSDEV_PC_WSM1: 108 *data64 = wsm[1]; 109 break; 110 case TSDEV_PC_WSM2: 111 *data64 = wsm[2]; 112 break; 113 case TSDEV_PC_WSM3: 114 *data64 = wsm[3]; 115 break; 116 case TSDEV_PC_TBA0: 117 *data64 = tba[0]; 118 break; 119 case TSDEV_PC_TBA1: 120 *data64 = tba[1]; 121 break; 122 case TSDEV_PC_TBA2: 123 *data64 = tba[2]; 124 break; 125 case Tbreak; 126 *data64 = tba[3]; 127 break; 128 case TSDEV_PC_PCTL: 129 *data64 = pctl; 130 break; 131 case TSDEV_PC_PLAT: 132 panic("PC_PLAT not implemented\n"); 133 case TSDEV_PC_RES: 134 panic("PC_RES not implemented\n"); 135 case TSDEV_PC_PERROR: 136 *data64 = 0x00; 137 break; 138 case TSDEV_PC_PERRMASK: 139 *data64 = 0x00; 140 break; 141 case TSDEV_PC_PERRSET: 142 panic("PC_PERRSET not implemented\n"); 143 case TSDEV_PC_TLBIV: 144 panic("PC_TLBIV not implemented\n"); 145 case TSDEV_PC_TLBIA: 146 *data64 = 0x00; // shouldn't be readable, but linux 147 break; 148 case TSDEV_PC_PMONCTL: 149 panic("PC_PMONCTL not implemented\n"); 150 case TSDEV_PC_PMONCNT: 151 panic("PC_PMONCTN not implemented\n"); 152 default: 153 panic("Default in PChip Read reached reading 0x%x\n", daddr); 154 } 155 pkt.result = Success; 156 return pioDelay; 157 158} 159 160Fault 161TsunamiPChip::write(Packet &pkt) 162{ 163 pkt.time = curTick + pioDelay; 164 165 assert(pkt.result == Unknown); 166 assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); 167 Addr daddr = pkt.addr - pioAddr; 168 169 uint64_t val = *(uint64_t *)pkt.data; 170 assert(pkt.size == sizeof(uint64_t)); 171 172 DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); 173 174 switch(daddr) { 175 case TSDEV_PC_WSBA0: 176 wsba[0] = data64; 177 break; 178 case TSDEV_PC_WSBA1: 179 wsba[1] = data64; 180 break; 181 case TSDEV_PC_WSBA2: 182 wsba[2] = data64; 183 break; 184 case TSDEV_PC_WSBA3: 185 wsba[3] = data64; 186 break; 187 case TSDEV_PC_WSM0: 188 wsm[0] = data64; 189 break; 190 case TSDEV_PC_WSM1: 191 wsm[1] = data64; 192 break; 193 case TSDEV_PC_WSM2: 194 wsm[2] = data64; 195 break; 196 case TSDEV_PC_WSM3: 197 wsm[3] = data64; 198 break; 199 case TSDEV_PC_TBA0: 200 tba[0] = data64; 201 break; 202 case TSDEV_PC_TBA1: 203 tba[1] = data64; 204 break; 205 case TSDEV_PC_TBA2: 206 tba[2] = data64; 207 break; 208 case TSDEV_PC_TBA3: 209 tba[3] = data64; 210 break; 211 case TSDEV_PC_PCTL: 212 pctl = data64; 213 break; 214 case TSDEV_PC_PLAT: 215 panic("PC_PLAT not implemented\n"); 216 case TSDEV_PC_RES: 217 panic("PC_RES not implemented\n"); 218 case TSDEV_PC_PERROR: 219 break; 220 case TSDEV_PC_PERRMASK: 221 panic("PC_PERRMASK not implemented\n"); 222 case TSDEV_PC_PERRSET: 223 panic("PC_PERRSET not implemented\n"); 224 case TSDEV_PC_TLBIV: 225 panic("PC_TLBIV not implemented\n"); 226 case TSDEV_PC_TLBIA: 227 break; // value ignored, supposted to invalidate SG TLB 228 case TSDEV_PC_PMONCTL: 229 panic("PC_PMONCTL not implemented\n"); 230 case TSDEV_PC_PMONCNT: 231 panic("PC_PMONCTN not implemented\n"); 232 default: 233 panic("Default in PChip Read reached reading 0x%x\n", daddr); 234 235 } // uint64_t 236 237 pkt.result = Success; 238 return pioDelay; 239} 240 241#define DMA_ADDR_MASK ULL(0x3ffffffff) 242 243Addr 244TsunamiPChip::translatePciToDma(Addr busAddr) 245{ 246 // compare the address to the window base registers 247 uint64_t tbaMask = 0; 248 uint64_t baMask = 0; 249 250 uint64_t windowMask = 0; 251 uint64_t windowBase = 0; 252 253 uint64_t pteEntry = 0; 254 255 Addr pteAddr; 256 Addr dmaAddr; 257 258#if 0 259 DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); 260 for (int i = 0; i < 4; i++) { 261 DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", 262 i, wsba[i], wsm[i]); 263 264 windowBase = wsba[i]; 265 windowMask = ~wsm[i] & (ULL(0xfff) << 20); 266 267 if ((busAddr & windowMask) == (windowBase & windowMask)) { 268 DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", 269 i, windowBase, windowMask, (busAddr & windowMask), 270 (windowBase & windowMask)); 271 } 272 } 273#endif 274 275 for (int i = 0; i < 4; i++) { 276 277 windowBase = wsba[i]; 278 windowMask = ~wsm[i] & (ULL(0xfff) << 20); 279 280 if ((busAddr & windowMask) == (windowBase & windowMask)) { 281 282 if (wsba[i] & 0x1) { // see if enabled 283 if (wsba[i] & 0x2) { // see if SG bit is set 284 /** @todo 285 This currently is faked by just doing a direct 286 read from memory, however, to be realistic, this 287 needs to actually do a bus transaction. The process 288 is explained in the tsunami documentation on page 289 10-12 and basically munges the address to look up a 290 PTE from a table in memory and then uses that mapping 291 to create an address for the SG page 292 */ 293 294 tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); 295 baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); 296 pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); 297 298 pioPort->readBlob(&pteEntry, pteAddr, sizeof(uint64_t)); 299 300 dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); 301 302 } else { 303 baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); 304 tbaMask = ~baMask; 305 dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); 306 } 307 308 return (dmaAddr & DMA_ADDR_MASK); 309 } 310 } 311 } 312 313 // if no match was found, then return the original address 314 return busAddr; 315} 316 317void 318TsunamiPChip::serialize(std::ostream &os) 319{ 320 SERIALIZE_SCALAR(pctl); 321 SERIALIZE_ARRAY(wsba, 4); 322 SERIALIZE_ARRAY(wsm, 4); 323 SERIALIZE_ARRAY(tba, 4); 324} 325 326void 327TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) 328{ 329 UNSERIALIZE_SCALAR(pctl); 330 UNSERIALIZE_ARRAY(wsba, 4); 331 UNSERIALIZE_ARRAY(wsm, 4); 332 UNSERIALIZE_ARRAY(tba, 4); 333} 334 335Tick 336TsunamiPChip::cacheAccess(MemReqPtr &req) 337{ 338 return curTick + pioLatency; 339} 340 341BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 342 343 Param<Addr> pio_addr; 344 Param<Tick> pio_latency; 345 SimObjectParam<Platform *> platform; 346 SimObjectParam<System *> system; 347 SimObjectParam<Tsunami *> tsunami; 348 349END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 350 351BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 352 353 INIT_PARAM(pio_addr, "Device Address"), 354 INIT_PARAM(pio_latency, "Programmed IO latency"), 355 INIT_PARAM(platform, "platform"), 356 INIT_PARAM(system, "system object"), 357 INIT_PARAM(tsunami, "Tsunami") 358 359END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 360 361CREATE_SIM_OBJECT(TsunamiPChip) 362{ 363 TsunamiPChip::Params *p = new TsunamiPChip::Params; 364 p->name = getInstanceName(); 365 p->pio_addr = pio_addr; 366 p->pio_delay = pio_latency; 367 p->platform = platform; 368 p->system = system; 369 p->tsunami = tsunami; 370 return new TsunamiPChip(p); 371} 372 373REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) 374