tsunami_pchip.cc revision 857
13691Shsul@eecs.umich.edu/* $Id$ */ 23691Shsul@eecs.umich.edu 33691Shsul@eecs.umich.edu/* @file 43691Shsul@eecs.umich.edu * Tsunami PChip (pci) 53691Shsul@eecs.umich.edu */ 63691Shsul@eecs.umich.edu 73691Shsul@eecs.umich.edu#include <deque> 83691Shsul@eecs.umich.edu#include <string> 93691Shsul@eecs.umich.edu#include <vector> 103691Shsul@eecs.umich.edu 113691Shsul@eecs.umich.edu#include "base/trace.hh" 123691Shsul@eecs.umich.edu#include "cpu/exec_context.hh" 133691Shsul@eecs.umich.edu#include "dev/console.hh" 143691Shsul@eecs.umich.edu#include "dev/etherdev.hh" 153691Shsul@eecs.umich.edu#include "dev/scsi_ctrl.hh" 163691Shsul@eecs.umich.edu#include "dev/tlaser_clock.hh" 173691Shsul@eecs.umich.edu#include "dev/tsunami_pchip.hh" 183691Shsul@eecs.umich.edu#include "dev/tsunamireg.h" 193691Shsul@eecs.umich.edu#include "dev/tsunami.hh" 203691Shsul@eecs.umich.edu#include "mem/functional_mem/memory_control.hh" 213691Shsul@eecs.umich.edu#include "mem/functional_mem/physical_memory.hh" 223691Shsul@eecs.umich.edu#include "sim/builder.hh" 233691Shsul@eecs.umich.edu#include "sim/system.hh" 243691Shsul@eecs.umich.edu 253691Shsul@eecs.umich.eduusing namespace std; 263691Shsul@eecs.umich.edu 273691Shsul@eecs.umich.eduTsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, 283691Shsul@eecs.umich.edu MemoryController *mmu) 293691Shsul@eecs.umich.edu : FunctionalMemory(name), addr(a), tsunami(t) 303691Shsul@eecs.umich.edu{ 316654Snate@binkert.org mmu->add_child(this, Range<Addr>(addr, addr + size)); 323691Shsul@eecs.umich.edu 333691Shsul@eecs.umich.edu for (int i = 0; i < 4; i++) { 343691Shsul@eecs.umich.edu wsba[i] = 0; 359826Sandreas.hansson@arm.com wsm[i] = 0; 369826Sandreas.hansson@arm.com tba[i] = 0; 379793Sakash.bagdia@arm.com } 389827Sakash.bagdia@arm.com 399827Sakash.bagdia@arm.com //Set back pointer in tsunami 409827Sakash.bagdia@arm.com tsunami->pchip = this; 419793Sakash.bagdia@arm.com} 429827Sakash.bagdia@arm.com 439827Sakash.bagdia@arm.comFault 449793Sakash.bagdia@arm.comTsunamiPChip::read(MemReqPtr &req, uint8_t *data) 453691Shsul@eecs.umich.edu{ 468876Sandreas.hansson@arm.com DPRINTF(Tsunami, "read va=%#x size=%d\n", 478876Sandreas.hansson@arm.com req->vaddr, req->size); 487876Sgblack@eecs.umich.edu 499793Sakash.bagdia@arm.com Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; 509793Sakash.bagdia@arm.com// ExecContext *xc = req->xc; 519793Sakash.bagdia@arm.com// int cpuid = xc->cpu_id; 529827Sakash.bagdia@arm.com 539827Sakash.bagdia@arm.com switch (req->size) { 549827Sakash.bagdia@arm.com 559793Sakash.bagdia@arm.com case sizeof(uint64_t): 569793Sakash.bagdia@arm.com switch(daddr) { 579827Sakash.bagdia@arm.com case TSDEV_PC_WSBA0: 589827Sakash.bagdia@arm.com *(uint64_t*)data = wsba[0]; 599827Sakash.bagdia@arm.com return No_Fault; 609793Sakash.bagdia@arm.com case TSDEV_PC_WSBA1: 618713Sandreas.hansson@arm.com *(uint64_t*)data = wsba[1]; 628713Sandreas.hansson@arm.com return No_Fault; 638713Sandreas.hansson@arm.com case TSDEV_PC_WSBA2: 649408Sandreas.hansson@arm.com *(uint64_t*)data = wsba[2]; 658839Sandreas.hansson@arm.com return No_Fault; 668839Sandreas.hansson@arm.com case TSDEV_PC_WSBA3: 673691Shsul@eecs.umich.edu *(uint64_t*)data = wsba[3]; 689826Sandreas.hansson@arm.com return No_Fault; 699826Sandreas.hansson@arm.com case TSDEV_PC_WSM0: 709826Sandreas.hansson@arm.com *(uint64_t*)data = wsm[0]; 719826Sandreas.hansson@arm.com return No_Fault; 723691Shsul@eecs.umich.edu case TSDEV_PC_WSM1: 739827Sakash.bagdia@arm.com *(uint64_t*)data = wsm[1]; 749827Sakash.bagdia@arm.com return No_Fault; 759793Sakash.bagdia@arm.com case TSDEV_PC_WSM2: 769827Sakash.bagdia@arm.com *(uint64_t*)data = wsm[2]; 779827Sakash.bagdia@arm.com return No_Fault; 789827Sakash.bagdia@arm.com case TSDEV_PC_WSM3: 793691Shsul@eecs.umich.edu *(uint64_t*)data = wsm[3]; 808876Sandreas.hansson@arm.com return No_Fault; 818876Sandreas.hansson@arm.com case TSDEV_PC_TBA0: 827876Sgblack@eecs.umich.edu *(uint64_t*)data = tba[0]; 839793Sakash.bagdia@arm.com return No_Fault; 849793Sakash.bagdia@arm.com case TSDEV_PC_TBA1: 859793Sakash.bagdia@arm.com *(uint64_t*)data = tba[1]; 869827Sakash.bagdia@arm.com return No_Fault; 879827Sakash.bagdia@arm.com case TSDEV_PC_TBA2: 889827Sakash.bagdia@arm.com *(uint64_t*)data = tba[2]; 899793Sakash.bagdia@arm.com return No_Fault; 909793Sakash.bagdia@arm.com case TSDEV_PC_TBA3: 919827Sakash.bagdia@arm.com *(uint64_t*)data = tba[3]; 929827Sakash.bagdia@arm.com return No_Fault; 939827Sakash.bagdia@arm.com case TSDEV_PC_PCTL: 949793Sakash.bagdia@arm.com // might want to change the clock?? 959408Sandreas.hansson@arm.com *(uint64_t*)data = 0x00; // try this 968839Sandreas.hansson@arm.com return No_Fault; 978839Sandreas.hansson@arm.com case TSDEV_PC_PLAT: 983691Shsul@eecs.umich.edu panic("PC_PLAT not implemented\n"); 999826Sandreas.hansson@arm.com case TSDEV_PC_RES: 1009826Sandreas.hansson@arm.com panic("PC_RES not implemented\n"); 1019826Sandreas.hansson@arm.com case TSDEV_PC_PERROR: 1028801Sgblack@eecs.umich.edu panic("PC_PERROR not implemented\n"); 1033691Shsul@eecs.umich.edu case TSDEV_PC_PERRMASK: 1043691Shsul@eecs.umich.edu panic("PC_PERRMASK not implemented\n"); 105 case TSDEV_PC_PERRSET: 106 panic("PC_PERRSET not implemented\n"); 107 case TSDEV_PC_TLBIV: 108 panic("PC_TLBIV not implemented\n"); 109 case TSDEV_PC_TLBIA: 110 *(uint64_t*)data = 0x00; // shouldn't be readable, but linux 111 return No_Fault; 112 case TSDEV_PC_PMONCTL: 113 panic("PC_PMONCTL not implemented\n"); 114 case TSDEV_PC_PMONCNT: 115 panic("PC_PMONCTN not implemented\n"); 116 default: 117 panic("Default in PChip Read reached reading 0x%x\n", daddr); 118 119 } // uint64_t 120 121 break; 122 case sizeof(uint32_t): 123 case sizeof(uint16_t): 124 case sizeof(uint8_t): 125 default: 126 panic("invalid access size(?) for tsunami register!\n\n"); 127 } 128 DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 129 130 return No_Fault; 131} 132 133Fault 134TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) 135{ 136 DPRINTF(Tsunami, "write - va=%#x size=%d \n", 137 req->vaddr, req->size); 138 139 Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; 140 141 switch (req->size) { 142 143 case sizeof(uint64_t): 144 switch(daddr) { 145 case TSDEV_PC_WSBA0: 146 wsba[0] = *(uint64_t*)data; 147 return No_Fault; 148 case TSDEV_PC_WSBA1: 149 wsba[1] = *(uint64_t*)data; 150 return No_Fault; 151 case TSDEV_PC_WSBA2: 152 wsba[2] = *(uint64_t*)data; 153 return No_Fault; 154 case TSDEV_PC_WSBA3: 155 wsba[3] = *(uint64_t*)data; 156 return No_Fault; 157 case TSDEV_PC_WSM0: 158 wsm[0] = *(uint64_t*)data; 159 return No_Fault; 160 case TSDEV_PC_WSM1: 161 wsm[1] = *(uint64_t*)data; 162 return No_Fault; 163 case TSDEV_PC_WSM2: 164 wsm[2] = *(uint64_t*)data; 165 return No_Fault; 166 case TSDEV_PC_WSM3: 167 wsm[3] = *(uint64_t*)data; 168 return No_Fault; 169 case TSDEV_PC_TBA0: 170 tba[0] = *(uint64_t*)data; 171 return No_Fault; 172 case TSDEV_PC_TBA1: 173 tba[1] = *(uint64_t*)data; 174 return No_Fault; 175 case TSDEV_PC_TBA2: 176 tba[2] = *(uint64_t*)data; 177 return No_Fault; 178 case TSDEV_PC_TBA3: 179 tba[3] = *(uint64_t*)data; 180 return No_Fault; 181 case TSDEV_PC_PCTL: 182 // might want to change the clock?? 183 //*(uint64_t*)data; // try this 184 return No_Fault; 185 case TSDEV_PC_PLAT: 186 panic("PC_PLAT not implemented\n"); 187 case TSDEV_PC_RES: 188 panic("PC_RES not implemented\n"); 189 case TSDEV_PC_PERROR: 190 panic("PC_PERROR not implemented\n"); 191 case TSDEV_PC_PERRMASK: 192 panic("PC_PERRMASK not implemented\n"); 193 case TSDEV_PC_PERRSET: 194 panic("PC_PERRSET not implemented\n"); 195 case TSDEV_PC_TLBIV: 196 panic("PC_TLBIV not implemented\n"); 197 case TSDEV_PC_TLBIA: 198 return No_Fault; // value ignored, supposted to invalidate SG TLB 199 case TSDEV_PC_PMONCTL: 200 panic("PC_PMONCTL not implemented\n"); 201 case TSDEV_PC_PMONCNT: 202 panic("PC_PMONCTN not implemented\n"); 203 default: 204 panic("Default in PChip Read reached reading 0x%x\n", daddr); 205 206 } // uint64_t 207 208 break; 209 case sizeof(uint32_t): 210 case sizeof(uint16_t): 211 case sizeof(uint8_t): 212 default: 213 panic("invalid access size(?) for tsunami register!\n\n"); 214 } 215 216 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 217 218 return No_Fault; 219} 220 221#define DMA_ADDR_MASK ULL(0x3ffffffff) 222 223Addr 224TsunamiPChip::translatePciToDma(Addr busAddr) 225{ 226 // compare the address to the window base registers 227 uint64_t tbaMask = 0; 228 uint64_t baMask = 0; 229 230 uint64_t windowMask = 0; 231 uint64_t windowBase = 0; 232 233 uint64_t pteEntry = 0; 234 235 Addr pteAddr; 236 Addr dmaAddr; 237 238 for (int i = 0; i < 4; i++) { 239 windowBase = wsba[i]; 240 windowMask = ~wsm[i] & (0x7ff << 20); 241 242 if ((busAddr & windowMask) == (windowBase & windowMask)) { 243 244 245 if (wsba[i] & 0x1) { // see if enabled 246 if (wsba[i] & 0x2) { // see if SG bit is set 247 /** @todo 248 This currently is faked by just doing a direct 249 read from memory, however, to be realistic, this 250 needs to actually do a bus transaction. The process 251 is explained in the tsunami documentation on page 252 10-12 and basically munges the address to look up a 253 PTE from a table in memory and then uses that mapping 254 to create an address for the SG page 255 */ 256 257 tbaMask = ~(((wsm[i] & (0x7ff << 20)) >> 10) | 0x3ff); 258 baMask = (wsm[i] & (0x7ff << 20)) | (0x7f << 13); 259 pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); 260 261 memcpy((void *)&pteEntry, 262 tsunami->system-> 263 physmem->dma_addr(pteAddr, sizeof(uint64_t)), 264 sizeof(uint64_t)); 265 266 dmaAddr = ((pteEntry & ~0x1) << 12) | (busAddr & 0xfff); 267 268 } else { 269 baMask = (wsm[i] & (0x7ff << 20)) | 0xfffff; 270 tbaMask = ~baMask; 271 dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); 272 } 273 274 return (dmaAddr & DMA_ADDR_MASK); 275 } 276 } 277 } 278 279 return 0; 280} 281 282void 283TsunamiPChip::serialize(std::ostream &os) 284{ 285 SERIALIZE_ARRAY(wsba, 4); 286 SERIALIZE_ARRAY(wsm, 4); 287 SERIALIZE_ARRAY(tba, 4); 288} 289 290void 291TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) 292{ 293 UNSERIALIZE_ARRAY(wsba, 4); 294 UNSERIALIZE_ARRAY(wsm, 4); 295 UNSERIALIZE_ARRAY(tba, 4); 296} 297 298BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 299 300 SimObjectParam<Tsunami *> tsunami; 301 SimObjectParam<MemoryController *> mmu; 302 Param<Addr> addr; 303 304END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) 305 306BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 307 308 INIT_PARAM(tsunami, "Tsunami"), 309 INIT_PARAM(mmu, "Memory Controller"), 310 INIT_PARAM(addr, "Device Address") 311 312END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) 313 314CREATE_SIM_OBJECT(TsunamiPChip) 315{ 316 return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu); 317} 318 319REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) 320