tsunami_pchip.cc revision 835
1/* $Id$ */ 2 3/* @file 4 * Tsunami PChip (pci) 5 */ 6 7#include <deque> 8#include <string> 9#include <vector> 10 11#include "base/trace.hh" 12#include "cpu/exec_context.hh" 13#include "dev/console.hh" 14#include "dev/etherdev.hh" 15#include "dev/scsi_ctrl.hh" 16#include "dev/tlaser_clock.hh" 17#include "dev/tsunami_pchip.hh" 18#include "dev/tsunamireg.h" 19#include "dev/tsunami.hh" 20#include "mem/functional_mem/memory_control.hh" 21#include "sim/builder.hh" 22#include "sim/system.hh" 23 24using namespace std; 25 26TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, 27 MemoryController *mmu) 28 : FunctionalMemory(name), addr(a), tsunami(t) 29{ 30 mmu->add_child(this, Range<Addr>(addr, addr + size)); 31 32 for (int i = 0; i < 4; i++) { 33 wsba[i] = 0; 34 wsm[i] = 0; 35 tba[i] = 0; 36 } 37 38 //Set back pointer in tsunami 39 tsunami->pchip = this; 40} 41 42Fault 43TsunamiPChip::read(MemReqPtr &req, uint8_t *data) 44{ 45 DPRINTF(Tsunami, "read va=%#x size=%d\n", 46 req->vaddr, req->size); 47 48 Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; 49// ExecContext *xc = req->xc; 50// int cpuid = xc->cpu_id; 51 52 switch (req->size) { 53 54 case sizeof(uint64_t): 55 switch(daddr) { 56 case TSDEV_PC_WSBA0: 57 *(uint64_t*)data = wsba[0]; 58 return No_Fault; 59 case TSDEV_PC_WSBA1: 60 *(uint64_t*)data = wsba[1]; 61 return No_Fault; 62 case TSDEV_PC_WSBA2: 63 *(uint64_t*)data = wsba[2]; 64 return No_Fault; 65 case TSDEV_PC_WSBA3: 66 *(uint64_t*)data = wsba[3]; 67 return No_Fault; 68 case TSDEV_PC_WSM0: 69 *(uint64_t*)data = wsm[0]; 70 return No_Fault; 71 case TSDEV_PC_WSM1: 72 *(uint64_t*)data = wsm[1]; 73 return No_Fault; 74 case TSDEV_PC_WSM2: 75 *(uint64_t*)data = wsm[2]; 76 return No_Fault; 77 case TSDEV_PC_WSM3: 78 *(uint64_t*)data = wsm[3]; 79 return No_Fault; 80 case TSDEV_PC_TBA0: 81 *(uint64_t*)data = tba[0]; 82 return No_Fault; 83 case TSDEV_PC_TBA1: 84 *(uint64_t*)data = tba[1]; 85 return No_Fault; 86 case TSDEV_PC_TBA2: 87 *(uint64_t*)data = tba[2]; 88 return No_Fault; 89 case TSDEV_PC_TBA3: 90 *(uint64_t*)data = tba[3]; 91 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