tsunami_pchip.cc revision 835
12SN/A/* $Id$ */ 21762SN/A 32SN/A/* @file 42SN/A * Tsunami PChip (pci) 52SN/A */ 62SN/A 72SN/A#include <deque> 82SN/A#include <string> 92SN/A#include <vector> 102SN/A 112SN/A#include "base/trace.hh" 122SN/A#include "cpu/exec_context.hh" 132SN/A#include "dev/console.hh" 142SN/A#include "dev/etherdev.hh" 152SN/A#include "dev/scsi_ctrl.hh" 162SN/A#include "dev/tlaser_clock.hh" 172SN/A#include "dev/tsunami_pchip.hh" 182SN/A#include "dev/tsunamireg.h" 192SN/A#include "dev/tsunami.hh" 202SN/A#include "mem/functional_mem/memory_control.hh" 212SN/A#include "sim/builder.hh" 222SN/A#include "sim/system.hh" 232SN/A 242SN/Ausing namespace std; 252SN/A 262SN/ATsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, 272665Ssaidi@eecs.umich.edu MemoryController *mmu) 282665Ssaidi@eecs.umich.edu : FunctionalMemory(name), addr(a), tsunami(t) 292665Ssaidi@eecs.umich.edu{ 302SN/A mmu->add_child(this, Range<Addr>(addr, addr + size)); 312SN/A 322SN/A for (int i = 0; i < 4; i++) { 332SN/A wsba[i] = 0; 342SN/A wsm[i] = 0; 352147SN/A tba[i] = 0; 362147SN/A } 372174SN/A 382147SN/A //Set back pointer in tsunami 392680Sktlim@umich.edu tsunami->pchip = this; 402132SN/A} 412147SN/A 422132SN/AFault 432147SN/ATsunamiPChip::read(MemReqPtr &req, uint8_t *data) 442147SN/A{ 452147SN/A DPRINTF(Tsunami, "read va=%#x size=%d\n", 462147SN/A req->vaddr, req->size); 472147SN/A 482147SN/A Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; 492147SN/A// ExecContext *xc = req->xc; 502147SN/A// int cpuid = xc->cpu_id; 512147SN/A 522147SN/A switch (req->size) { 532147SN/A 542090SN/A case sizeof(uint64_t): 552147SN/A switch(daddr) { 564695Sgblack@eecs.umich.edu case TSDEV_PC_WSBA0: 572680Sktlim@umich.edu *(uint64_t*)data = wsba[0]; 582201SN/A return No_Fault; 592201SN/A case TSDEV_PC_WSBA1: 604695Sgblack@eecs.umich.edu *(uint64_t*)data = wsba[1]; 614695Sgblack@eecs.umich.edu return No_Fault; 622SN/A case TSDEV_PC_WSBA2: 632SN/A *(uint64_t*)data = wsba[2]; 642168SN/A return No_Fault; 652168SN/A case TSDEV_PC_WSBA3: 662612SN/A *(uint64_t*)data = wsba[3]; 672612SN/A return No_Fault; 682612SN/A case TSDEV_PC_WSM0: 692612SN/A *(uint64_t*)data = wsm[0]; 702612SN/A return No_Fault; 712612SN/A case TSDEV_PC_WSM1: 722612SN/A *(uint64_t*)data = wsm[1]; 732612SN/A return No_Fault; 742612SN/A case TSDEV_PC_WSM2: 754695Sgblack@eecs.umich.edu *(uint64_t*)data = wsm[2]; 762680Sktlim@umich.edu return No_Fault; 772612SN/A case TSDEV_PC_WSM3: 782612SN/A *(uint64_t*)data = wsm[3]; 794183Sgblack@eecs.umich.edu return No_Fault; 804183Sgblack@eecs.umich.edu case TSDEV_PC_TBA0: 814183Sgblack@eecs.umich.edu *(uint64_t*)data = tba[0]; 824183Sgblack@eecs.umich.edu return No_Fault; 834183Sgblack@eecs.umich.edu case TSDEV_PC_TBA1: 844183Sgblack@eecs.umich.edu *(uint64_t*)data = tba[1]; 854695Sgblack@eecs.umich.edu return No_Fault; 864183Sgblack@eecs.umich.edu case TSDEV_PC_TBA2: 874183Sgblack@eecs.umich.edu *(uint64_t*)data = tba[2]; 884183Sgblack@eecs.umich.edu return No_Fault; 894183Sgblack@eecs.umich.edu case TSDEV_PC_TBA3: 904183Sgblack@eecs.umich.edu *(uint64_t*)data = tba[3]; 912SN/A return No_Fault; 92 case TSDEV_PC_PCTL: 93 // might want to change the clock?? 94 *(uint64_t*)data = 0x00; // try this 95 return No_Fault; 96 case TSDEV_PC_PLAT: 97 panic("PC_PLAT not implemented\n"); 98 case TSDEV_PC_RES: 99 panic("PC_RES not implemented\n"); 100 case TSDEV_PC_PERROR: 101 panic("PC_PERROR not implemented\n"); 102 case TSDEV_PC_PERRMASK: 103 panic("PC_PERRMASK not implemented\n"); 104 case TSDEV_PC_PERRSET: 105 panic("PC_PERRSET not implemented\n"); 106 case TSDEV_PC_TLBIV: 107 panic("PC_TLBIV not implemented\n"); 108 case TSDEV_PC_TLBIA: 109 *(uint64_t*)data = 0x00; // shouldn't be readable, but linux 110 return No_Fault; 111 case TSDEV_PC_PMONCTL: 112 panic("PC_PMONCTL not implemented\n"); 113 case TSDEV_PC_PMONCNT: 114 panic("PC_PMONCTN not implemented\n"); 115 default: 116 panic("Default in PChip Read reached reading 0x%x\n", daddr); 117 118 } // uint64_t 119 120 break; 121 case sizeof(uint32_t): 122 case sizeof(uint16_t): 123 case sizeof(uint8_t): 124 default: 125 panic("invalid access size(?) for tsunami register!\n\n"); 126 } 127 DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 128 129 return No_Fault; 130} 131 132Fault 133TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) 134{ 135 DPRINTF(Tsunami, "write - va=%#x size=%d \n", 136 req->vaddr, req->size); 137 138 Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; 139 140 switch (req->size) { 141 142 case sizeof(uint64_t): 143 switch(daddr) { 144 case TSDEV_PC_WSBA0: 145 wsba[0] = *(uint64_t*)data; 146 return No_Fault; 147 case TSDEV_PC_WSBA1: 148 wsba[1] = *(uint64_t*)data; 149 return No_Fault; 150 case TSDEV_PC_WSBA2: 151 wsba[2] = *(uint64_t*)data; 152 return No_Fault; 153 case TSDEV_PC_WSBA3: 154 wsba[3] = *(uint64_t*)data; 155 return No_Fault; 156 case TSDEV_PC_WSM0: 157 wsm[0] = *(uint64_t*)data; 158 return No_Fault; 159 case TSDEV_PC_WSM1: 160 wsm[1] = *(uint64_t*)data; 161 return No_Fault; 162 case TSDEV_PC_WSM2: 163 wsm[2] = *(uint64_t*)data; 164 return No_Fault; 165 case TSDEV_PC_WSM3: 166 wsm[3] = *(uint64_t*)data; 167 return No_Fault; 168 case TSDEV_PC_TBA0: 169 tba[0] = *(uint64_t*)data; 170 return No_Fault; 171 case TSDEV_PC_TBA1: 172 tba[1] = *(uint64_t*)data; 173 return No_Fault; 174 case TSDEV_PC_TBA2: 175 tba[2] = *(uint64_t*)data; 176 return No_Fault; 177 case TSDEV_PC_TBA3: 178 tba[3] = *(uint64_t*)data; 179 return No_Fault; 180 case TSDEV_PC_PCTL: 181 // might want to change the clock?? 182 //*(uint64_t*)data; // try this 183 return No_Fault; 184 case TSDEV_PC_PLAT: 185 panic("PC_PLAT not implemented\n"); 186 case TSDEV_PC_RES: 187 panic("PC_RES not implemented\n"); 188 case TSDEV_PC_PERROR: 189 panic("PC_PERROR not implemented\n"); 190 case TSDEV_PC_PERRMASK: 191 panic("PC_PERRMASK not implemented\n"); 192 case TSDEV_PC_PERRSET: 193 panic("PC_PERRSET not implemented\n"); 194 case TSDEV_PC_TLBIV: 195 panic("PC_TLBIV not implemented\n"); 196 case TSDEV_PC_TLBIA: 197 return No_Fault; // value ignored, supposted to invalidate SG TLB 198 case TSDEV_PC_PMONCTL: 199 panic("PC_PMONCTL not implemented\n"); 200 case TSDEV_PC_PMONCNT: 201 panic("PC_PMONCTN not implemented\n"); 202 default: 203 panic("Default in PChip Read reached reading 0x%x\n", daddr); 204 205 } // uint64_t 206 207 break; 208 case sizeof(uint32_t): 209 case sizeof(uint16_t): 210 case sizeof(uint8_t): 211 default: 212 panic("invalid access size(?) for tsunami register!\n\n"); 213 } 214 215 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 216 217 return No_Fault; 218} 219 220Addr 221TsunamiPChip::translatePciToDma(Addr busAddr) 222{ 223 // compare the address to the window base registers 224 uint64_t windowMask = 0; 225 uint64_t windowBase = 0; 226 Addr dmaAddr; 227 228 for (int i = 0; i < 4; i++) { 229 windowBase = wsba[i]; 230 windowMask = ~wsm[i] & (0x7ff << 20); 231 232 if ((busAddr & windowMask) == (windowBase & windowMask)) { 233 windowMask = (wsm[i] & (0x7ff << 20)) | 0xfffff; 234 235 if (wsba[i] & 0x1) { // see if enabled 236 if (wsba[i] & 0x2) // see if SG bit is set 237 panic("PCI to system SG mapping not currently implemented!\n"); 238 else 239 dmaAddr = (tba[i] & ~windowMask) | (busAddr & windowMask); 240 241 return dmaAddr; 242 } 243 } 244 } 245 246 return 0; 247} 248 249void 250TsunamiPChip::serialize(std::ostream &os) 251{ 252 SERIALIZE_ARRAY(wsba, 4); 253 SERIALIZE_ARRAY(wsm, 4); 254 SERIALIZE_ARRAY(tba, 4); 255} 256 257void 258TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) 259{ 260 UNSERIALIZE_ARRAY(wsba, 4); 261 UNSERIALIZE_ARRAY(wsm, 4); 262 UNSERIALIZE_ARRAY(tba, 4); 263} 264 265BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 266 267 SimObjectParam<Tsunami *> tsunami; 268 SimObjectParam<MemoryController *> mmu; 269 Param<Addr> addr; 270 271END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 272 273BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 274 275 INIT_PARAM(tsunami, "Tsunami"), 276 INIT_PARAM(mmu, "Memory Controller"), 277 INIT_PARAM(addr, "Device Address") 278 279END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 280 281CREATE_SIM_OBJECT(TsunamiPChip) 282{ 283 return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu); 284} 285 286REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) 287