tsunami_cchip.cc revision 777
14679Sgblack@eecs.umich.edu/* $Id$ */ 24679Sgblack@eecs.umich.edu 34679Sgblack@eecs.umich.edu/* @file 44679Sgblack@eecs.umich.edu * Tsunami CChip (processor, memory, or IO) 54679Sgblack@eecs.umich.edu */ 64679Sgblack@eecs.umich.edu 74679Sgblack@eecs.umich.edu#include <deque> 84679Sgblack@eecs.umich.edu#include <string> 94679Sgblack@eecs.umich.edu#include <vector> 104679Sgblack@eecs.umich.edu 114679Sgblack@eecs.umich.edu#include "base/trace.hh" 124679Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 134679Sgblack@eecs.umich.edu#include "dev/console.hh" 144679Sgblack@eecs.umich.edu#include "dev/etherdev.hh" 154679Sgblack@eecs.umich.edu#include "dev/scsi_ctrl.hh" 164679Sgblack@eecs.umich.edu#include "dev/tlaser_clock.hh" 174679Sgblack@eecs.umich.edu#include "dev/tsunami_cchip.hh" 184679Sgblack@eecs.umich.edu#include "dev/tsunamireg.h" 194679Sgblack@eecs.umich.edu#include "dev/tsunami.hh" 204679Sgblack@eecs.umich.edu#include "cpu/intr_control.hh" 214679Sgblack@eecs.umich.edu#include "mem/functional_mem/memory_control.hh" 224679Sgblack@eecs.umich.edu#include "sim/builder.hh" 234679Sgblack@eecs.umich.edu#include "sim/system.hh" 244679Sgblack@eecs.umich.edu 254679Sgblack@eecs.umich.eduusing namespace std; 264679Sgblack@eecs.umich.edu 274679Sgblack@eecs.umich.eduTsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, 284679Sgblack@eecs.umich.edu Addr addr, Addr mask, MemoryController *mmu) 294679Sgblack@eecs.umich.edu : MmapDevice(name, addr, mask, mmu), tsunami(t) 304679Sgblack@eecs.umich.edu{ 314679Sgblack@eecs.umich.edu for(int i=0; i < Tsunami::Max_CPUs; i++) { 324679Sgblack@eecs.umich.edu dim[i] = 0; 334679Sgblack@eecs.umich.edu dir[i] = 0; 344679Sgblack@eecs.umich.edu dirInterrupting[i] = false; 354679Sgblack@eecs.umich.edu } 364679Sgblack@eecs.umich.edu 374679Sgblack@eecs.umich.edu drir = 0; 384679Sgblack@eecs.umich.edu misc = 0; 394679Sgblack@eecs.umich.edu RTCInterrupting = false; 404679Sgblack@eecs.umich.edu 414679Sgblack@eecs.umich.edu //Put back pointer in tsunami 424679Sgblack@eecs.umich.edu tsunami->cchip = this; 434679Sgblack@eecs.umich.edu} 444679Sgblack@eecs.umich.edu 454679Sgblack@eecs.umich.eduFault 464679Sgblack@eecs.umich.eduTsunamiCChip::read(MemReqPtr req, uint8_t *data) 474679Sgblack@eecs.umich.edu{ 484679Sgblack@eecs.umich.edu DPRINTF(Tsunami, "read va=%#x size=%d\n", 494679Sgblack@eecs.umich.edu req->vaddr, req->size); 504679Sgblack@eecs.umich.edu 514679Sgblack@eecs.umich.edu Addr daddr = (req->paddr & addr_mask) >> 6; 524679Sgblack@eecs.umich.edu// ExecContext *xc = req->xc; 534679Sgblack@eecs.umich.edu// int cpuid = xc->cpu_id; 544679Sgblack@eecs.umich.edu 554679Sgblack@eecs.umich.edu switch (req->size) { 564679Sgblack@eecs.umich.edu 574679Sgblack@eecs.umich.edu case sizeof(uint64_t): 584679Sgblack@eecs.umich.edu switch(daddr) { 594679Sgblack@eecs.umich.edu case TSDEV_CC_CSR: 604679Sgblack@eecs.umich.edu *(uint64_t*)data = 0x0; 614679Sgblack@eecs.umich.edu return No_Fault; 624679Sgblack@eecs.umich.edu case TSDEV_CC_MTR: 634679Sgblack@eecs.umich.edu panic("TSDEV_CC_MTR not implemeted\n"); 644679Sgblack@eecs.umich.edu return No_Fault; 655083Sgblack@eecs.umich.edu case TSDEV_CC_MISC: 665083Sgblack@eecs.umich.edu *(uint64_t*)data = misc; 675083Sgblack@eecs.umich.edu return No_Fault; 685083Sgblack@eecs.umich.edu case TSDEV_CC_AAR0: 695083Sgblack@eecs.umich.edu case TSDEV_CC_AAR1: 705083Sgblack@eecs.umich.edu case TSDEV_CC_AAR2: 715083Sgblack@eecs.umich.edu case TSDEV_CC_AAR3: 725083Sgblack@eecs.umich.edu panic("TSDEV_CC_AARx not implemeted\n"); 735083Sgblack@eecs.umich.edu return No_Fault; 745083Sgblack@eecs.umich.edu case TSDEV_CC_DIM0: 755083Sgblack@eecs.umich.edu *(uint64_t*)data = dim[0]; 765083Sgblack@eecs.umich.edu return No_Fault; 775083Sgblack@eecs.umich.edu case TSDEV_CC_DIM1: 785083Sgblack@eecs.umich.edu *(uint64_t*)data = dim[1]; 795083Sgblack@eecs.umich.edu return No_Fault; 805083Sgblack@eecs.umich.edu case TSDEV_CC_DIM2: 815083Sgblack@eecs.umich.edu *(uint64_t*)data = dim[2]; 825083Sgblack@eecs.umich.edu return No_Fault; 835083Sgblack@eecs.umich.edu case TSDEV_CC_DIM3: 845083Sgblack@eecs.umich.edu *(uint64_t*)data = dim[3]; 855083Sgblack@eecs.umich.edu return No_Fault; 865083Sgblack@eecs.umich.edu case TSDEV_CC_DIR0: 875083Sgblack@eecs.umich.edu *(uint64_t*)data = dir[0]; 885083Sgblack@eecs.umich.edu return No_Fault; 895083Sgblack@eecs.umich.edu case TSDEV_CC_DIR1: 905083Sgblack@eecs.umich.edu *(uint64_t*)data = dir[1]; 915083Sgblack@eecs.umich.edu return No_Fault; 925083Sgblack@eecs.umich.edu case TSDEV_CC_DIR2: 935083Sgblack@eecs.umich.edu *(uint64_t*)data = dir[2]; 945083Sgblack@eecs.umich.edu return No_Fault; 955083Sgblack@eecs.umich.edu case TSDEV_CC_DIR3: 965083Sgblack@eecs.umich.edu *(uint64_t*)data = dir[3]; 975083Sgblack@eecs.umich.edu return No_Fault; 985083Sgblack@eecs.umich.edu case TSDEV_CC_DRIR: 995083Sgblack@eecs.umich.edu *(uint64_t*)data = drir; 1005083Sgblack@eecs.umich.edu return No_Fault; 1015083Sgblack@eecs.umich.edu case TSDEV_CC_PRBEN: 1025083Sgblack@eecs.umich.edu panic("TSDEV_CC_PRBEN not implemented\n"); 1035083Sgblack@eecs.umich.edu return No_Fault; 1045083Sgblack@eecs.umich.edu case TSDEV_CC_IIC0: 1055083Sgblack@eecs.umich.edu case TSDEV_CC_IIC1: 1064679Sgblack@eecs.umich.edu case TSDEV_CC_IIC2: 1074679Sgblack@eecs.umich.edu case TSDEV_CC_IIC3: 1084679Sgblack@eecs.umich.edu panic("TSDEV_CC_IICx not implemented\n"); 1094679Sgblack@eecs.umich.edu return No_Fault; 1104679Sgblack@eecs.umich.edu case TSDEV_CC_MPR0: 1114679Sgblack@eecs.umich.edu case TSDEV_CC_MPR1: 1124679Sgblack@eecs.umich.edu case TSDEV_CC_MPR2: 1134679Sgblack@eecs.umich.edu case TSDEV_CC_MPR3: 1144679Sgblack@eecs.umich.edu panic("TSDEV_CC_MPRx not implemented\n"); 1154679Sgblack@eecs.umich.edu return No_Fault; 1164679Sgblack@eecs.umich.edu default: 1174679Sgblack@eecs.umich.edu panic("default in cchip read reached, accessing 0x%x\n"); 1184679Sgblack@eecs.umich.edu } // uint64_t 1194679Sgblack@eecs.umich.edu 1204679Sgblack@eecs.umich.edu break; 1214679Sgblack@eecs.umich.edu case sizeof(uint32_t): 1224679Sgblack@eecs.umich.edu case sizeof(uint16_t): 1234679Sgblack@eecs.umich.edu case sizeof(uint8_t): 1244679Sgblack@eecs.umich.edu default: 1254679Sgblack@eecs.umich.edu panic("invalid access size(?) for tsunami register!\n"); 1264679Sgblack@eecs.umich.edu } 1274679Sgblack@eecs.umich.edu DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 1284679Sgblack@eecs.umich.edu 1294679Sgblack@eecs.umich.edu return No_Fault; 1304679Sgblack@eecs.umich.edu} 1314679Sgblack@eecs.umich.edu 1324679Sgblack@eecs.umich.eduFault 1334679Sgblack@eecs.umich.eduTsunamiCChip::write(MemReqPtr req, const uint8_t *data) 1344679Sgblack@eecs.umich.edu{ 1354679Sgblack@eecs.umich.edu DPRINTF(Tsunami, "write - va=%#x size=%d \n", 1364679Sgblack@eecs.umich.edu req->vaddr, req->size); 1374679Sgblack@eecs.umich.edu 1385083Sgblack@eecs.umich.edu Addr daddr = (req->paddr & addr_mask) >> 6; 1395083Sgblack@eecs.umich.edu 1404679Sgblack@eecs.umich.edu switch (req->size) { 1414679Sgblack@eecs.umich.edu 1424679Sgblack@eecs.umich.edu case sizeof(uint64_t): 1434679Sgblack@eecs.umich.edu switch(daddr) { 144 case TSDEV_CC_CSR: 145 panic("TSDEV_CC_CSR write\n"); 146 return No_Fault; 147 case TSDEV_CC_MTR: 148 panic("TSDEV_CC_MTR write not implemented\n"); 149 return No_Fault; 150 case TSDEV_CC_MISC: 151 //If it is the seventh bit, clear the RTC interrupt 152 if ((*(uint64_t*) data) & (1<<4)) { 153 RTCInterrupting = false; 154 tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0); 155 DPRINTF(Tsunami, "clearing rtc interrupt\n"); 156 misc &= ~(1<<4); 157 } else panic("TSDEV_CC_MISC write not implemented\n"); 158 return No_Fault; 159 case TSDEV_CC_AAR0: 160 case TSDEV_CC_AAR1: 161 case TSDEV_CC_AAR2: 162 case TSDEV_CC_AAR3: 163 panic("TSDEV_CC_AARx write not implemeted\n"); 164 return No_Fault; 165 case TSDEV_CC_DIM0: 166 dim[0] = *(uint64_t*)data; 167 if (dim[0] & drir) { 168 dir[0] = dim[0] & drir; 169 if (!dirInterrupting[0]) { 170 dirInterrupting[0] = true; 171 tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); 172 DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 173 } 174 } 175 return No_Fault; 176 case TSDEV_CC_DIM1: 177 dim[1] = *(uint64_t*)data; 178 if (dim[1] & drir) { 179 dir[1] = dim[1] & drir; 180 if (!dirInterrupting[1]) { 181 dirInterrupting[1] = true; 182 tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0); 183 DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n"); 184 } 185 } 186 return No_Fault; 187 case TSDEV_CC_DIM2: 188 dim[2] = *(uint64_t*)data; 189 if (dim[2] & drir) { 190 dir[2] = dim[2] & drir; 191 if (!dirInterrupting[2]) { 192 dirInterrupting[2] = true; 193 tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0); 194 DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n"); 195 } 196 } 197 return No_Fault; 198 case TSDEV_CC_DIM3: 199 dim[3] = *(uint64_t*)data; 200 if ((dim[3] & drir) /*And Not Already Int*/) { 201 dir[3] = dim[3] & drir; 202 if (!dirInterrupting[3]) { 203 dirInterrupting[3] = true; 204 tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0); 205 DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n"); 206 } 207 } 208 return No_Fault; 209 case TSDEV_CC_DIR0: 210 case TSDEV_CC_DIR1: 211 case TSDEV_CC_DIR2: 212 case TSDEV_CC_DIR3: 213 panic("TSDEV_CC_DIR write not implemented\n"); 214 return No_Fault; 215 case TSDEV_CC_DRIR: 216 panic("TSDEV_CC_DRIR write not implemented\n"); 217 return No_Fault; 218 case TSDEV_CC_PRBEN: 219 panic("TSDEV_CC_PRBEN write not implemented\n"); 220 return No_Fault; 221 case TSDEV_CC_IIC0: 222 case TSDEV_CC_IIC1: 223 case TSDEV_CC_IIC2: 224 case TSDEV_CC_IIC3: 225 panic("TSDEV_CC_IICx write not implemented\n"); 226 return No_Fault; 227 case TSDEV_CC_MPR0: 228 case TSDEV_CC_MPR1: 229 case TSDEV_CC_MPR2: 230 case TSDEV_CC_MPR3: 231 panic("TSDEV_CC_MPRx write not implemented\n"); 232 return No_Fault; 233 default: 234 panic("default in cchip read reached, accessing 0x%x\n"); 235 } 236 237 break; 238 case sizeof(uint32_t): 239 case sizeof(uint16_t): 240 case sizeof(uint8_t): 241 default: 242 panic("invalid access size(?) for tsunami register!\n"); 243 } 244 245 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 246 247 return No_Fault; 248} 249 250void 251TsunamiCChip::postDRIR(uint64_t bitvector) 252{ 253 drir |= bitvector; 254 for(int i=0; i < Tsunami::Max_CPUs; i++) { 255 if (bitvector & dim[i]) { 256 dir[i] |= bitvector; 257 if (!dirInterrupting[i]) { 258 dirInterrupting[i] = true; 259 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0); 260 DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i); 261 } 262 } 263 } 264} 265 266void 267TsunamiCChip::clearDRIR(uint64_t bitvector) 268{ 269 drir &= ~bitvector; 270 for(int i=0; i < Tsunami::Max_CPUs; i++) { 271 dir[i] &= ~bitvector; 272 if (!dir[i]) { 273 dirInterrupting[i] = false; 274 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0); 275 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i); 276 277 } 278 } 279} 280 281void 282TsunamiCChip::serialize(std::ostream &os) 283{ 284 // code should be written 285} 286 287void 288TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 289{ 290 //code should be written 291} 292 293BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 294 295 SimObjectParam<Tsunami *> tsunami; 296 SimObjectParam<MemoryController *> mmu; 297 Param<Addr> addr; 298 Param<Addr> mask; 299 300END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 301 302BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 303 304 INIT_PARAM(tsunami, "Tsunami"), 305 INIT_PARAM(mmu, "Memory Controller"), 306 INIT_PARAM(addr, "Device Address"), 307 INIT_PARAM(mask, "Address Mask") 308 309END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 310 311CREATE_SIM_OBJECT(TsunamiCChip) 312{ 313 return new TsunamiCChip(getInstanceName(), tsunami, addr, mask, mmu); 314} 315 316REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 317