tsunami_cchip.cc revision 811
112855Sgabeblack@google.com/* $Id$ */ 212855Sgabeblack@google.com 312855Sgabeblack@google.com/* @file 412855Sgabeblack@google.com * Emulation of the Tsunami CChip CSRs 512855Sgabeblack@google.com */ 612855Sgabeblack@google.com 712855Sgabeblack@google.com#include <deque> 812855Sgabeblack@google.com#include <string> 912855Sgabeblack@google.com#include <vector> 1012855Sgabeblack@google.com 1112855Sgabeblack@google.com#include "base/trace.hh" 1212855Sgabeblack@google.com#include "cpu/exec_context.hh" 1312855Sgabeblack@google.com#include "dev/console.hh" 1412855Sgabeblack@google.com#include "dev/tsunami_cchip.hh" 1512855Sgabeblack@google.com#include "dev/tsunamireg.h" 1612855Sgabeblack@google.com#include "dev/tsunami.hh" 1712855Sgabeblack@google.com#include "cpu/intr_control.hh" 1812855Sgabeblack@google.com#include "mem/functional_mem/memory_control.hh" 1912855Sgabeblack@google.com#include "sim/builder.hh" 2012855Sgabeblack@google.com#include "sim/system.hh" 2112855Sgabeblack@google.com 2212855Sgabeblack@google.comusing namespace std; 2312855Sgabeblack@google.com 2412855Sgabeblack@google.comTsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, 2512855Sgabeblack@google.com MemoryController *mmu) 2612855Sgabeblack@google.com : FunctionalMemory(name), addr(a), tsunami(t) 2712855Sgabeblack@google.com{ 2812855Sgabeblack@google.com mmu->add_child(this, Range<Addr>(addr, addr + size)); 2912855Sgabeblack@google.com 3012855Sgabeblack@google.com for(int i=0; i < Tsunami::Max_CPUs; i++) { 3112855Sgabeblack@google.com dim[i] = 0; 3212855Sgabeblack@google.com dir[i] = 0; 3312855Sgabeblack@google.com dirInterrupting[i] = false; 3412855Sgabeblack@google.com } 3512855Sgabeblack@google.com 3612855Sgabeblack@google.com drir = 0; 3712855Sgabeblack@google.com misc = 0; 3812855Sgabeblack@google.com RTCInterrupting = false; 3912855Sgabeblack@google.com 4012855Sgabeblack@google.com //Put back pointer in tsunami 4112855Sgabeblack@google.com tsunami->cchip = this; 4212855Sgabeblack@google.com} 4312855Sgabeblack@google.com 4412855Sgabeblack@google.comFault 4512855Sgabeblack@google.comTsunamiCChip::read(MemReqPtr &req, uint8_t *data) 4612855Sgabeblack@google.com{ 4712855Sgabeblack@google.com DPRINTF(Tsunami, "read va=%#x size=%d\n", 4812855Sgabeblack@google.com req->vaddr, req->size); 4912855Sgabeblack@google.com 5012855Sgabeblack@google.com Addr daddr = (req->paddr & size) >> 6; 5112855Sgabeblack@google.com ExecContext *xc = req->xc; 5212855Sgabeblack@google.com 5312855Sgabeblack@google.com switch (req->size) { 5412855Sgabeblack@google.com 5512855Sgabeblack@google.com case sizeof(uint64_t): 5612855Sgabeblack@google.com switch(daddr) { 5712855Sgabeblack@google.com case TSDEV_CC_CSR: 5812855Sgabeblack@google.com *(uint64_t*)data = 0x0; 5912855Sgabeblack@google.com return No_Fault; 6012855Sgabeblack@google.com case TSDEV_CC_MTR: 6112855Sgabeblack@google.com panic("TSDEV_CC_MTR not implemeted\n"); 6212855Sgabeblack@google.com return No_Fault; 6312855Sgabeblack@google.com case TSDEV_CC_MISC: 6412855Sgabeblack@google.com *(uint64_t*)data = misc | (xc->cpu_id & 0x3); 6512855Sgabeblack@google.com return No_Fault; 6612855Sgabeblack@google.com case TSDEV_CC_AAR0: 6712855Sgabeblack@google.com case TSDEV_CC_AAR1: 6812855Sgabeblack@google.com case TSDEV_CC_AAR2: 6912855Sgabeblack@google.com case TSDEV_CC_AAR3: 7012855Sgabeblack@google.com panic("TSDEV_CC_AARx not implemeted\n"); 7112855Sgabeblack@google.com return No_Fault; 7212855Sgabeblack@google.com case TSDEV_CC_DIM0: 7312855Sgabeblack@google.com *(uint64_t*)data = dim[0]; 7412855Sgabeblack@google.com return No_Fault; 7512855Sgabeblack@google.com case TSDEV_CC_DIM1: 7612855Sgabeblack@google.com *(uint64_t*)data = dim[1]; 7712855Sgabeblack@google.com return No_Fault; 7812855Sgabeblack@google.com case TSDEV_CC_DIM2: 7912855Sgabeblack@google.com *(uint64_t*)data = dim[2]; 8012855Sgabeblack@google.com return No_Fault; 8112855Sgabeblack@google.com case TSDEV_CC_DIM3: 8212855Sgabeblack@google.com *(uint64_t*)data = dim[3]; 8312855Sgabeblack@google.com return No_Fault; 8412855Sgabeblack@google.com case TSDEV_CC_DIR0: 8512855Sgabeblack@google.com *(uint64_t*)data = dir[0]; 8612855Sgabeblack@google.com return No_Fault; 8712855Sgabeblack@google.com case TSDEV_CC_DIR1: 8812855Sgabeblack@google.com *(uint64_t*)data = dir[1]; 8912855Sgabeblack@google.com return No_Fault; 9012855Sgabeblack@google.com case TSDEV_CC_DIR2: 9112855Sgabeblack@google.com *(uint64_t*)data = dir[2]; 9212855Sgabeblack@google.com return No_Fault; 9312855Sgabeblack@google.com case TSDEV_CC_DIR3: 9412855Sgabeblack@google.com *(uint64_t*)data = dir[3]; 9512855Sgabeblack@google.com return No_Fault; 9612855Sgabeblack@google.com case TSDEV_CC_DRIR: 9712855Sgabeblack@google.com *(uint64_t*)data = drir; 9812855Sgabeblack@google.com return No_Fault; 9912855Sgabeblack@google.com case TSDEV_CC_PRBEN: 10012855Sgabeblack@google.com panic("TSDEV_CC_PRBEN not implemented\n"); 10112855Sgabeblack@google.com return No_Fault; 10212855Sgabeblack@google.com case TSDEV_CC_IIC0: 10312855Sgabeblack@google.com case TSDEV_CC_IIC1: 10412855Sgabeblack@google.com case TSDEV_CC_IIC2: 10512855Sgabeblack@google.com case TSDEV_CC_IIC3: 10612855Sgabeblack@google.com panic("TSDEV_CC_IICx not implemented\n"); 10712855Sgabeblack@google.com return No_Fault; 10812855Sgabeblack@google.com case TSDEV_CC_MPR0: 10912855Sgabeblack@google.com case TSDEV_CC_MPR1: 11012855Sgabeblack@google.com case TSDEV_CC_MPR2: 11112855Sgabeblack@google.com case TSDEV_CC_MPR3: 11212855Sgabeblack@google.com panic("TSDEV_CC_MPRx not implemented\n"); 11312855Sgabeblack@google.com return No_Fault; 11412855Sgabeblack@google.com default: 11512855Sgabeblack@google.com panic("default in cchip read reached, accessing 0x%x\n"); 11612855Sgabeblack@google.com } // uint64_t 11712855Sgabeblack@google.com 11812855Sgabeblack@google.com break; 11912855Sgabeblack@google.com case sizeof(uint32_t): 12012855Sgabeblack@google.com case sizeof(uint16_t): 12112855Sgabeblack@google.com case sizeof(uint8_t): 12212855Sgabeblack@google.com default: 12312855Sgabeblack@google.com panic("invalid access size(?) for tsunami register!\n"); 12412855Sgabeblack@google.com } 12512855Sgabeblack@google.com DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 12612855Sgabeblack@google.com 12712855Sgabeblack@google.com return No_Fault; 12812855Sgabeblack@google.com} 12912855Sgabeblack@google.com 13012855Sgabeblack@google.comFault 13112855Sgabeblack@google.comTsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 13212855Sgabeblack@google.com{ 13312855Sgabeblack@google.com DPRINTF(Tsunami, "write - va=%#x size=%d \n", 13412855Sgabeblack@google.com req->vaddr, req->size); 13512855Sgabeblack@google.com 13612855Sgabeblack@google.com Addr daddr = (req->paddr & size) >> 6; 13712855Sgabeblack@google.com 13812855Sgabeblack@google.com switch (req->size) { 13912855Sgabeblack@google.com 14012855Sgabeblack@google.com case sizeof(uint64_t): 14112855Sgabeblack@google.com switch(daddr) { 14212855Sgabeblack@google.com case TSDEV_CC_CSR: 14312855Sgabeblack@google.com panic("TSDEV_CC_CSR write\n"); 14412855Sgabeblack@google.com return No_Fault; 14512855Sgabeblack@google.com case TSDEV_CC_MTR: 14612855Sgabeblack@google.com panic("TSDEV_CC_MTR write not implemented\n"); 14712855Sgabeblack@google.com return No_Fault; 14812855Sgabeblack@google.com case TSDEV_CC_MISC: 14912855Sgabeblack@google.com //If it is the seventh bit, clear the RTC interrupt 15012855Sgabeblack@google.com if ((*(uint64_t*) data) & (1<<4)) { 15112855Sgabeblack@google.com RTCInterrupting = false; 15212855Sgabeblack@google.com tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0); 15312855Sgabeblack@google.com DPRINTF(Tsunami, "clearing rtc interrupt\n"); 15412855Sgabeblack@google.com misc &= ~(1<<4); 15512855Sgabeblack@google.com } else panic("TSDEV_CC_MISC write not implemented\n"); 15612855Sgabeblack@google.com return No_Fault; 15712855Sgabeblack@google.com case TSDEV_CC_AAR0: 15812855Sgabeblack@google.com case TSDEV_CC_AAR1: 15912855Sgabeblack@google.com case TSDEV_CC_AAR2: 16012855Sgabeblack@google.com case TSDEV_CC_AAR3: 16112855Sgabeblack@google.com panic("TSDEV_CC_AARx write not implemeted\n"); 16212855Sgabeblack@google.com return No_Fault; 16312855Sgabeblack@google.com case TSDEV_CC_DIM0: 16412855Sgabeblack@google.com dim[0] = *(uint64_t*)data; 16512855Sgabeblack@google.com if (dim[0] & drir) { 16612855Sgabeblack@google.com dir[0] = dim[0] & drir; 16712855Sgabeblack@google.com if (!dirInterrupting[0]) { 16812855Sgabeblack@google.com dirInterrupting[0] = true; 16912855Sgabeblack@google.com tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); 17012855Sgabeblack@google.com DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 17112855Sgabeblack@google.com } 17212855Sgabeblack@google.com } 17312855Sgabeblack@google.com return No_Fault; 17412855Sgabeblack@google.com case TSDEV_CC_DIM1: 17512855Sgabeblack@google.com dim[1] = *(uint64_t*)data; 17612855Sgabeblack@google.com if (dim[1] & drir) { 17712855Sgabeblack@google.com dir[1] = dim[1] & drir; 17812855Sgabeblack@google.com if (!dirInterrupting[1]) { 17912855Sgabeblack@google.com dirInterrupting[1] = true; 18012855Sgabeblack@google.com tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0); 181 DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n"); 182 } 183 } 184 return No_Fault; 185 case TSDEV_CC_DIM2: 186 dim[2] = *(uint64_t*)data; 187 if (dim[2] & drir) { 188 dir[2] = dim[2] & drir; 189 if (!dirInterrupting[2]) { 190 dirInterrupting[2] = true; 191 tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0); 192 DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n"); 193 } 194 } 195 return No_Fault; 196 case TSDEV_CC_DIM3: 197 dim[3] = *(uint64_t*)data; 198 if ((dim[3] & drir) /*And Not Already Int*/) { 199 dir[3] = dim[3] & drir; 200 if (!dirInterrupting[3]) { 201 dirInterrupting[3] = true; 202 tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0); 203 DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n"); 204 } 205 } 206 return No_Fault; 207 case TSDEV_CC_DIR0: 208 case TSDEV_CC_DIR1: 209 case TSDEV_CC_DIR2: 210 case TSDEV_CC_DIR3: 211 panic("TSDEV_CC_DIR write not implemented\n"); 212 return No_Fault; 213 case TSDEV_CC_DRIR: 214 panic("TSDEV_CC_DRIR write not implemented\n"); 215 return No_Fault; 216 case TSDEV_CC_PRBEN: 217 panic("TSDEV_CC_PRBEN write not implemented\n"); 218 return No_Fault; 219 case TSDEV_CC_IIC0: 220 case TSDEV_CC_IIC1: 221 case TSDEV_CC_IIC2: 222 case TSDEV_CC_IIC3: 223 panic("TSDEV_CC_IICx write not implemented\n"); 224 return No_Fault; 225 case TSDEV_CC_MPR0: 226 case TSDEV_CC_MPR1: 227 case TSDEV_CC_MPR2: 228 case TSDEV_CC_MPR3: 229 panic("TSDEV_CC_MPRx write not implemented\n"); 230 return No_Fault; 231 default: 232 panic("default in cchip read reached, accessing 0x%x\n"); 233 } 234 235 break; 236 case sizeof(uint32_t): 237 case sizeof(uint16_t): 238 case sizeof(uint8_t): 239 default: 240 panic("invalid access size(?) for tsunami register!\n"); 241 } 242 243 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 244 245 return No_Fault; 246} 247 248void 249TsunamiCChip::postDRIR(uint64_t bitvector) 250{ 251 drir |= bitvector; 252 for(int i=0; i < Tsunami::Max_CPUs; i++) { 253 if (bitvector & dim[i]) { 254 dir[i] |= bitvector; 255 if (!dirInterrupting[i]) { 256 dirInterrupting[i] = true; 257 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0); 258 DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i); 259 } 260 } 261 } 262} 263 264void 265TsunamiCChip::clearDRIR(uint64_t bitvector) 266{ 267 drir &= ~bitvector; 268 for(int i=0; i < Tsunami::Max_CPUs; i++) { 269 dir[i] &= ~bitvector; 270 if (!dir[i]) { 271 dirInterrupting[i] = false; 272 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0); 273 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i); 274 275 } 276 } 277} 278 279void 280TsunamiCChip::serialize(std::ostream &os) 281{ 282 SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 283 SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 284 SERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs); 285 SERIALIZE_SCALAR(drir); 286 SERIALIZE_SCALAR(misc); 287 SERIALIZE_SCALAR(RTCInterrupting); 288} 289 290void 291TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 292{ 293 UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 294 UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 295 UNSERIALIZE_ARRAY(dirInterrupting, Tsunami::Max_CPUs); 296 UNSERIALIZE_SCALAR(drir); 297 UNSERIALIZE_SCALAR(misc); 298 UNSERIALIZE_SCALAR(RTCInterrupting); 299} 300 301BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 302 303 SimObjectParam<Tsunami *> tsunami; 304 SimObjectParam<MemoryController *> mmu; 305 Param<Addr> addr; 306 307END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 308 309BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 310 311 INIT_PARAM(tsunami, "Tsunami"), 312 INIT_PARAM(mmu, "Memory Controller"), 313 INIT_PARAM(addr, "Device Address") 314 315END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 316 317CREATE_SIM_OBJECT(TsunamiCChip) 318{ 319 return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu); 320} 321 322REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 323