tsunami_pchip.cc revision 1762
1892SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 3892SN/A * All rights reserved. 4892SN/A * 5892SN/A * Redistribution and use in source and binary forms, with or without 6892SN/A * modification, are permitted provided that the following conditions are 7892SN/A * met: redistributions of source code must retain the above copyright 8892SN/A * notice, this list of conditions and the following disclaimer; 9892SN/A * redistributions in binary form must reproduce the above copyright 10892SN/A * notice, this list of conditions and the following disclaimer in the 11892SN/A * documentation and/or other materials provided with the distribution; 12892SN/A * neither the name of the copyright holders nor the names of its 13892SN/A * contributors may be used to endorse or promote products derived from 14892SN/A * this software without specific prior written permission. 15892SN/A * 16892SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17892SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18892SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19892SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20892SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21892SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22892SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23892SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24892SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25892SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26892SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 292665SN/A/** @file 30892SN/A * Tsunami PChip (pci) 31767SN/A */ 321730SN/A 33798SN/A#include <deque> 34767SN/A#include <string> 35767SN/A#include <vector> 36767SN/A 37767SN/A#include "base/trace.hh" 38767SN/A#include "dev/tsunami_pchip.hh" 39767SN/A#include "dev/tsunamireg.h" 402432SN/A#include "dev/tsunami.hh" 41767SN/A#include "mem/bus/bus.hh" 423348SN/A#include "mem/bus/pio_interface.hh" 433348SN/A#include "mem/bus/pio_interface_impl.hh" 443540Sgblack@eecs.umich.edu#include "mem/functional/memory_control.hh" 453540Sgblack@eecs.umich.edu#include "mem/functional/physical.hh" 463540Sgblack@eecs.umich.edu#include "sim/builder.hh" 473348SN/A#include "sim/system.hh" 483348SN/A 492523SN/Ausing namespace std; 504762Snate@binkert.org 51767SN/ATsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, 52767SN/A MemoryController *mmu, HierParams *hier, 53767SN/A Bus *bus, Tick pio_latency) 542107SN/A : PioDevice(name, t), addr(a), tsunami(t) 552107SN/A{ 56767SN/A mmu->add_child(this, RangeSize(addr, size)); 574762Snate@binkert.org 582523SN/A for (int i = 0; i < 4; i++) { 59767SN/A wsba[i] = 0; 603846Shsul@eecs.umich.edu wsm[i] = 0; 61909SN/A tba[i] = 0; 62767SN/A } 631290SN/A 641290SN/A if (bus) { 651290SN/A pioInterface = newPioInterface(name, hier, bus, this, 661290SN/A &TsunamiPChip::cacheAccess); 671290SN/A pioInterface->addAddrRange(RangeSize(addr, size)); 681290SN/A pioLatency = pio_latency * bus->clockRate; 691290SN/A } 701290SN/A 71775SN/A 72775SN/A // initialize pchip control register 73775SN/A pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); 74767SN/A 75767SN/A //Set back pointer in tsunami 762523SN/A tsunami->pchip = this; 773349SN/A} 78767SN/A 792641SN/AFault 80767SN/ATsunamiPChip::read(MemReqPtr &req, uint8_t *data) 812641SN/A{ 822641SN/A DPRINTF(Tsunami, "read va=%#x size=%d\n", 831290SN/A req->vaddr, req->size); 842641SN/A 852641SN/A Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 86767SN/A 872630SN/A switch (req->size) { 882641SN/A 89767SN/A case sizeof(uint64_t): 90767SN/A switch(daddr) { 913875Sbinkertn@umich.edu case TSDEV_PC_WSBA0: 923875Sbinkertn@umich.edu *(uint64_t*)data = wsba[0]; 931290SN/A return No_Fault; 941290SN/A case TSDEV_PC_WSBA1: 952630SN/A *(uint64_t*)data = wsba[1]; 962523SN/A return No_Fault; 971290SN/A case TSDEV_PC_WSBA2: 981290SN/A *(uint64_t*)data = wsba[2]; 991290SN/A return No_Fault; 1001290SN/A case TSDEV_PC_WSBA3: 1012630SN/A *(uint64_t*)data = wsba[3]; 1022523SN/A return No_Fault; 1031290SN/A case TSDEV_PC_WSM0: 1041290SN/A *(uint64_t*)data = wsm[0]; 1051290SN/A return No_Fault; 106767SN/A case TSDEV_PC_WSM1: 1072630SN/A *(uint64_t*)data = wsm[1]; 1082523SN/A return No_Fault; 109767SN/A case TSDEV_PC_WSM2: 110767SN/A *(uint64_t*)data = wsm[2]; 1112523SN/A return No_Fault; 112767SN/A case TSDEV_PC_WSM3: 1132630SN/A *(uint64_t*)data = wsm[3]; 1142630SN/A return No_Fault; 1152523SN/A case TSDEV_PC_TBA0: 116767SN/A *(uint64_t*)data = tba[0]; 117767SN/A return No_Fault; 118767SN/A case TSDEV_PC_TBA1: 119767SN/A *(uint64_t*)data = tba[1]; 1202630SN/A return No_Fault; 1212523SN/A case TSDEV_PC_TBA2: 122767SN/A *(uint64_t*)data = tba[2]; 1232630SN/A return No_Fault; 1242523SN/A case TSDEV_PC_TBA3: 125767SN/A *(uint64_t*)data = tba[3]; 1262630SN/A return No_Fault; 1272523SN/A case TSDEV_PC_PCTL: 128767SN/A *(uint64_t*)data = pctl; 1292630SN/A return No_Fault; 1302523SN/A case TSDEV_PC_PLAT: 131767SN/A panic("PC_PLAT not implemented\n"); 1322630SN/A case TSDEV_PC_RES: 1332523SN/A panic("PC_RES not implemented\n"); 134767SN/A case TSDEV_PC_PERROR: 1352630SN/A *(uint64_t*)data = 0x00; 1362523SN/A return No_Fault; 137767SN/A case TSDEV_PC_PERRMASK: 1382630SN/A *(uint64_t*)data = 0x00; 1392523SN/A return No_Fault; 140767SN/A case TSDEV_PC_PERRSET: 1412630SN/A panic("PC_PERRSET not implemented\n"); 1422523SN/A case TSDEV_PC_TLBIV: 143767SN/A panic("PC_TLBIV not implemented\n"); 1442630SN/A case TSDEV_PC_TLBIA: 1452523SN/A *(uint64_t*)data = 0x00; // shouldn't be readable, but linux 146767SN/A return No_Fault; 1472630SN/A case TSDEV_PC_PMONCTL: 1482523SN/A panic("PC_PMONCTL not implemented\n"); 149767SN/A case TSDEV_PC_PMONCNT: 150767SN/A panic("PC_PMONCTN not implemented\n"); 1512523SN/A default: 152767SN/A panic("Default in PChip Read reached reading 0x%x\n", daddr); 153767SN/A 154767SN/A } // uint64_t 155767SN/A 156767SN/A break; 1572523SN/A case sizeof(uint32_t): 158767SN/A case sizeof(uint16_t): 159767SN/A case sizeof(uint8_t): 160767SN/A default: 161767SN/A panic("invalid access size(?) for tsunami register!\n\n"); 162767SN/A } 1632523SN/A DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 1641290SN/A 1652630SN/A return No_Fault; 1662523SN/A} 1671290SN/A 1682630SN/AFault 1692523SN/ATsunamiPChip::write(MemReqPtr &req, const uint8_t *data) 170768SN/A{ 171768SN/A DPRINTF(Tsunami, "write - va=%#x size=%d \n", 172767SN/A req->vaddr, req->size); 173767SN/A 174767SN/A Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 175767SN/A 176767SN/A switch (req->size) { 177767SN/A 178767SN/A case sizeof(uint64_t): 179768SN/A switch(daddr) { 180767SN/A case TSDEV_PC_WSBA0: 1812549SN/A wsba[0] = *(uint64_t*)data; 1822641SN/A return No_Fault; 183767SN/A case TSDEV_PC_WSBA1: 1842641SN/A wsba[1] = *(uint64_t*)data; 1852523SN/A return No_Fault; 186767SN/A case TSDEV_PC_WSBA2: 187767SN/A wsba[2] = *(uint64_t*)data; 1882523SN/A return No_Fault; 1893349SN/A case TSDEV_PC_WSBA3: 190767SN/A wsba[3] = *(uint64_t*)data; 1912641SN/A return No_Fault; 1922641SN/A case TSDEV_PC_WSM0: 1932641SN/A wsm[0] = *(uint64_t*)data; 1942539SN/A return No_Fault; 1952523SN/A case TSDEV_PC_WSM1: 1962641SN/A wsm[1] = *(uint64_t*)data; 1972523SN/A return No_Fault; 1982641SN/A case TSDEV_PC_WSM2: 199767SN/A wsm[2] = *(uint64_t*)data; 200830SN/A return No_Fault; 201830SN/A case TSDEV_PC_WSM3: 202767SN/A wsm[3] = *(uint64_t*)data; 2032539SN/A return No_Fault; 2042539SN/A case TSDEV_PC_TBA0: 2052539SN/A tba[0] = *(uint64_t*)data; 2061290SN/A return No_Fault; 2072539SN/A case TSDEV_PC_TBA1: 2082539SN/A tba[1] = *(uint64_t*)data; 2092539SN/A return No_Fault; 2101290SN/A case TSDEV_PC_TBA2: 2112539SN/A tba[2] = *(uint64_t*)data; 2122539SN/A return No_Fault; 2132630SN/A case TSDEV_PC_TBA3: 2142539SN/A tba[3] = *(uint64_t*)data; 2152539SN/A return No_Fault; 2162539SN/A case TSDEV_PC_PCTL: 2172539SN/A pctl = *(uint64_t*)data; 2182539SN/A return No_Fault; 2192539SN/A case TSDEV_PC_PLAT: 2202539SN/A panic("PC_PLAT not implemented\n"); 2212539SN/A case TSDEV_PC_RES: 2222539SN/A panic("PC_RES not implemented\n"); 2232539SN/A case TSDEV_PC_PERROR: 2242539SN/A return No_Fault; 2252539SN/A case TSDEV_PC_PERRMASK: 2262539SN/A panic("PC_PERRMASK not implemented\n"); 2272539SN/A case TSDEV_PC_PERRSET: 2282539SN/A panic("PC_PERRSET not implemented\n"); 2292539SN/A case TSDEV_PC_TLBIV: 2302539SN/A panic("PC_TLBIV not implemented\n"); 2312539SN/A case TSDEV_PC_TLBIA: 2322539SN/A return No_Fault; // value ignored, supposted to invalidate SG TLB 2332539SN/A case TSDEV_PC_PMONCTL: 2342539SN/A panic("PC_PMONCTL not implemented\n"); 2352539SN/A case TSDEV_PC_PMONCNT: 2361290SN/A panic("PC_PMONCTN not implemented\n"); 2371074SN/A default: 2381074SN/A panic("Default in PChip Read reached reading 0x%x\n", daddr); 2392539SN/A 2402539SN/A } // uint64_t 2412539SN/A 2422539SN/A break; 2432539SN/A case sizeof(uint32_t): 2442539SN/A case sizeof(uint16_t): 2452539SN/A case sizeof(uint8_t): 2462539SN/A default: 2472539SN/A panic("invalid access size(?) for tsunami register!\n\n"); 2482539SN/A } 2492539SN/A 2502630SN/A DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 2512539SN/A 2522539SN/A return No_Fault; 2532539SN/A} 2542539SN/A 2552539SN/A#define DMA_ADDR_MASK ULL(0x3ffffffff) 2562539SN/A 2572539SN/AAddr 2582539SN/ATsunamiPChip::translatePciToDma(Addr busAddr) 2592630SN/A{ 2602539SN/A // compare the address to the window base registers 2612539SN/A uint64_t tbaMask = 0; 2622539SN/A uint64_t baMask = 0; 2632539SN/A 2642539SN/A uint64_t windowMask = 0; 2652539SN/A uint64_t windowBase = 0; 2662539SN/A 2672630SN/A uint64_t pteEntry = 0; 2682539SN/A 2692539SN/A Addr pteAddr; 2702539SN/A Addr dmaAddr; 2712539SN/A 2722539SN/A#if 0 2732539SN/A DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); 2742630SN/A for (int i = 0; i < 4; i++) { 2752539SN/A DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", 2762539SN/A i, wsba[i], wsm[i]); 2772539SN/A 2782539SN/A windowBase = wsba[i]; 2792539SN/A windowMask = ~wsm[i] & (ULL(0xfff) << 20); 2802549SN/A 2812539SN/A if ((busAddr & windowMask) == (windowBase & windowMask)) { 2822539SN/A DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", 2832539SN/A i, windowBase, windowMask, (busAddr & windowMask), 2842539SN/A (windowBase & windowMask)); 2852539SN/A } 2862539SN/A } 2872539SN/A#endif 2882539SN/A 2892539SN/A for (int i = 0; i < 4; i++) { 2902539SN/A 2912539SN/A windowBase = wsba[i]; 2922539SN/A windowMask = ~wsm[i] & (ULL(0xfff) << 20); 2932539SN/A 2942539SN/A if ((busAddr & windowMask) == (windowBase & windowMask)) { 2952539SN/A 2962539SN/A if (wsba[i] & 0x1) { // see if enabled 2972539SN/A if (wsba[i] & 0x2) { // see if SG bit is set 2982539SN/A /** @todo 2992539SN/A This currently is faked by just doing a direct 3002539SN/A read from memory, however, to be realistic, this 3012539SN/A needs to actually do a bus transaction. The process 3022539SN/A is explained in the tsunami documentation on page 3032539SN/A 10-12 and basically munges the address to look up a 3042539SN/A PTE from a table in memory and then uses that mapping 3052539SN/A to create an address for the SG page 3062630SN/A */ 3072539SN/A 3082539SN/A tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); 3092539SN/A baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); 3102539SN/A pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); 3112539SN/A 3122539SN/A memcpy((void *)&pteEntry, 3132539SN/A tsunami->system-> 3142539SN/A physmem->dma_addr(pteAddr, sizeof(uint64_t)), 3152539SN/A sizeof(uint64_t)); 3162539SN/A 3172539SN/A dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); 3182539SN/A 3192539SN/A } else { 3202539SN/A baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); 3212539SN/A tbaMask = ~baMask; 3222539SN/A dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); 3232539SN/A } 3242539SN/A 3252539SN/A return (dmaAddr & DMA_ADDR_MASK); 3262539SN/A } 3272539SN/A } 3282539SN/A } 3292539SN/A 3302539SN/A // if no match was found, then return the original address 3312539SN/A return busAddr; 3322539SN/A} 3332539SN/A 3341074SN/Avoid 3352539SN/ATsunamiPChip::serialize(std::ostream &os) 3362539SN/A{ 3372539SN/A SERIALIZE_SCALAR(pctl); 3382539SN/A SERIALIZE_ARRAY(wsba, 4); 3392539SN/A SERIALIZE_ARRAY(wsm, 4); 3402539SN/A SERIALIZE_ARRAY(tba, 4); 3412539SN/A} 3422539SN/A 3432539SN/Avoid 3442539SN/ATsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) 3452539SN/A{ 3462539SN/A UNSERIALIZE_SCALAR(pctl); 3472539SN/A UNSERIALIZE_ARRAY(wsba, 4); 3482539SN/A UNSERIALIZE_ARRAY(wsm, 4); 3492539SN/A UNSERIALIZE_ARRAY(tba, 4); 3502539SN/A} 3512539SN/A 3522539SN/ATick 3532539SN/ATsunamiPChip::cacheAccess(MemReqPtr &req) 3542539SN/A{ 3552539SN/A return curTick + pioLatency; 3562630SN/A} 3572539SN/A 3582539SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 3592630SN/A 3602539SN/A SimObjectParam<Tsunami *> tsunami; 3612539SN/A SimObjectParam<MemoryController *> mmu; 3622630SN/A Param<Addr> addr; 3632539SN/A SimObjectParam<Bus*> io_bus; 3642539SN/A Param<Tick> pio_latency; 3652539SN/A SimObjectParam<HierParams *> hier; 3662539SN/A 3672539SN/AEND_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 3682641SN/A 3692539SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 370767SN/A 371767SN/A INIT_PARAM(tsunami, "Tsunami"), 372767SN/A INIT_PARAM(mmu, "Memory Controller"), 3731290SN/A INIT_PARAM(addr, "Device Address"), 3741290SN/A INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), 3754103Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), 3761290SN/A INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 3771290SN/A 3781290SN/AEND_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 3791290SN/A 3801290SN/ACREATE_SIM_OBJECT(TsunamiPChip) 3811290SN/A{ 3821290SN/A return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier, 3831290SN/A io_bus, pio_latency); 3841290SN/A} 3851290SN/A 3861290SN/AREGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) 3871290SN/A