tsunami_cchip.cc revision 811
1/* $Id$ */ 2 3/* @file 4 * Emulation of the Tsunami CChip CSRs 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/tsunami_cchip.hh" 15#include "dev/tsunamireg.h" 16#include "dev/tsunami.hh" 17#include "cpu/intr_control.hh" 18#include "mem/functional_mem/memory_control.hh" 19#include "sim/builder.hh" 20#include "sim/system.hh" 21 22using namespace std; 23 24TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, 25 MemoryController *mmu) 26 : FunctionalMemory(name), addr(a), tsunami(t) 27{ 28 mmu->add_child(this, Range<Addr>(addr, addr + size)); 29 30 for(int i=0; i < Tsunami::Max_CPUs; i++) { 31 dim[i] = 0; 32 dir[i] = 0; 33 dirInterrupting[i] = false; 34 } 35 36 drir = 0; 37 misc = 0; 38 RTCInterrupting = false; 39 40 //Put back pointer in tsunami 41 tsunami->cchip = this; 42} 43 44Fault 45TsunamiCChip::read(MemReqPtr &req, uint8_t *data) 46{ 47 DPRINTF(Tsunami, "read va=%#x size=%d\n", 48 req->vaddr, req->size); 49 50 Addr daddr = (req->paddr & size) >> 6; 51 ExecContext *xc = req->xc; 52 53 switch (req->size) { 54 55 case sizeof(uint64_t): 56 switch(daddr) { 57 case TSDEV_CC_CSR: 58 *(uint64_t*)data = 0x0; 59 return No_Fault; 60 case TSDEV_CC_MTR: 61 panic("TSDEV_CC_MTR not implemeted\n"); 62 return No_Fault; 63 case TSDEV_CC_MISC: 64 *(uint64_t*)data = misc | (xc->cpu_id & 0x3); 65 return No_Fault; 66 case TSDEV_CC_AAR0: 67 case TSDEV_CC_AAR1: 68 case TSDEV_CC_AAR2: 69 case TSDEV_CC_AAR3: 70 panic("TSDEV_CC_AARx not implemeted\n"); 71 return No_Fault; 72 case TSDEV_CC_DIM0: 73 *(uint64_t*)data = dim[0]; 74 return No_Fault; 75 case TSDEV_CC_DIM1: 76 *(uint64_t*)data = dim[1]; 77 return No_Fault; 78 case TSDEV_CC_DIM2: 79 *(uint64_t*)data = dim[2]; 80 return No_Fault; 81 case TSDEV_CC_DIM3: 82 *(uint64_t*)data = dim[3]; 83 return No_Fault; 84 case TSDEV_CC_DIR0: 85 *(uint64_t*)data = dir[0]; 86 return No_Fault; 87 case TSDEV_CC_DIR1: 88 *(uint64_t*)data = dir[1]; 89 return No_Fault; 90 case TSDEV_CC_DIR2: 91 *(uint64_t*)data = dir[2]; 92 return No_Fault; 93 case TSDEV_CC_DIR3: 94 *(uint64_t*)data = dir[3]; 95 return No_Fault; 96 case TSDEV_CC_DRIR: 97 *(uint64_t*)data = drir; 98 return No_Fault; 99 case TSDEV_CC_PRBEN: 100 panic("TSDEV_CC_PRBEN not implemented\n"); 101 return No_Fault; 102 case TSDEV_CC_IIC0: 103 case TSDEV_CC_IIC1: 104 case TSDEV_CC_IIC2: 105 case TSDEV_CC_IIC3: 106 panic("TSDEV_CC_IICx not implemented\n"); 107 return No_Fault; 108 case TSDEV_CC_MPR0: 109 case TSDEV_CC_MPR1: 110 case TSDEV_CC_MPR2: 111 case TSDEV_CC_MPR3: 112 panic("TSDEV_CC_MPRx not implemented\n"); 113 return No_Fault; 114 default: 115 panic("default in cchip read reached, accessing 0x%x\n"); 116 } // uint64_t 117 118 break; 119 case sizeof(uint32_t): 120 case sizeof(uint16_t): 121 case sizeof(uint8_t): 122 default: 123 panic("invalid access size(?) for tsunami register!\n"); 124 } 125 DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 126 127 return No_Fault; 128} 129 130Fault 131TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 132{ 133 DPRINTF(Tsunami, "write - va=%#x size=%d \n", 134 req->vaddr, req->size); 135 136 Addr daddr = (req->paddr & size) >> 6; 137 138 switch (req->size) { 139 140 case sizeof(uint64_t): 141 switch(daddr) { 142 case TSDEV_CC_CSR: 143 panic("TSDEV_CC_CSR write\n"); 144 return No_Fault; 145 case TSDEV_CC_MTR: 146 panic("TSDEV_CC_MTR write not implemented\n"); 147 return No_Fault; 148 case TSDEV_CC_MISC: 149 //If it is the seventh bit, clear the RTC interrupt 150 if ((*(uint64_t*) data) & (1<<4)) { 151 RTCInterrupting = false; 152 tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0); 153 DPRINTF(Tsunami, "clearing rtc interrupt\n"); 154 misc &= ~(1<<4); 155 } else panic("TSDEV_CC_MISC write not implemented\n"); 156 return No_Fault; 157 case TSDEV_CC_AAR0: 158 case TSDEV_CC_AAR1: 159 case TSDEV_CC_AAR2: 160 case TSDEV_CC_AAR3: 161 panic("TSDEV_CC_AARx write not implemeted\n"); 162 return No_Fault; 163 case TSDEV_CC_DIM0: 164 dim[0] = *(uint64_t*)data; 165 if (dim[0] & drir) { 166 dir[0] = dim[0] & drir; 167 if (!dirInterrupting[0]) { 168 dirInterrupting[0] = true; 169 tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); 170 DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 171 } 172 } 173 return No_Fault; 174 case TSDEV_CC_DIM1: 175 dim[1] = *(uint64_t*)data; 176 if (dim[1] & drir) { 177 dir[1] = dim[1] & drir; 178 if (!dirInterrupting[1]) { 179 dirInterrupting[1] = true; 180 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