tsunami_cchip.cc revision 798
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, 25 Addr addr, Addr mask, MemoryController *mmu) 26 : MmapDevice(name, addr, mask, mmu), tsunami(t) 27{ 28 for(int i=0; i < Tsunami::Max_CPUs; i++) { 29 dim[i] = 0; 30 dir[i] = 0; 31 dirInterrupting[i] = false; 32 } 33 34 drir = 0; 35 misc = 0; 36 RTCInterrupting = false; 37 38 //Put back pointer in tsunami 39 tsunami->cchip = this; 40} 41 42Fault 43TsunamiCChip::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_mask) >> 6; 49 ExecContext *xc = req->xc; 50 51 switch (req->size) { 52 53 case sizeof(uint64_t): 54 switch(daddr) { 55 case TSDEV_CC_CSR: 56 *(uint64_t*)data = 0x0; 57 return No_Fault; 58 case TSDEV_CC_MTR: 59 panic("TSDEV_CC_MTR not implemeted\n"); 60 return No_Fault; 61 case TSDEV_CC_MISC: 62 *(uint64_t*)data = misc | (xc->cpu_id & 0x3); 63 return No_Fault; 64 case TSDEV_CC_AAR0: 65 case TSDEV_CC_AAR1: 66 case TSDEV_CC_AAR2: 67 case TSDEV_CC_AAR3: 68 panic("TSDEV_CC_AARx not implemeted\n"); 69 return No_Fault; 70 case TSDEV_CC_DIM0: 71 *(uint64_t*)data = dim[0]; 72 return No_Fault; 73 case TSDEV_CC_DIM1: 74 *(uint64_t*)data = dim[1]; 75 return No_Fault; 76 case TSDEV_CC_DIM2: 77 *(uint64_t*)data = dim[2]; 78 return No_Fault; 79 case TSDEV_CC_DIM3: 80 *(uint64_t*)data = dim[3]; 81 return No_Fault; 82 case TSDEV_CC_DIR0: 83 *(uint64_t*)data = dir[0]; 84 return No_Fault; 85 case TSDEV_CC_DIR1: 86 *(uint64_t*)data = dir[1]; 87 return No_Fault; 88 case TSDEV_CC_DIR2: 89 *(uint64_t*)data = dir[2]; 90 return No_Fault; 91 case TSDEV_CC_DIR3: 92 *(uint64_t*)data = dir[3]; 93 return No_Fault; 94 case TSDEV_CC_DRIR: 95 *(uint64_t*)data = drir; 96 return No_Fault; 97 case TSDEV_CC_PRBEN: 98 panic("TSDEV_CC_PRBEN not implemented\n"); 99 return No_Fault; 100 case TSDEV_CC_IIC0: 101 case TSDEV_CC_IIC1: 102 case TSDEV_CC_IIC2: 103 case TSDEV_CC_IIC3: 104 panic("TSDEV_CC_IICx not implemented\n"); 105 return No_Fault; 106 case TSDEV_CC_MPR0: 107 case TSDEV_CC_MPR1: 108 case TSDEV_CC_MPR2: 109 case TSDEV_CC_MPR3: 110 panic("TSDEV_CC_MPRx not implemented\n"); 111 return No_Fault; 112 default: 113 panic("default in cchip read reached, accessing 0x%x\n"); 114 } // uint64_t 115 116 break; 117 case sizeof(uint32_t): 118 case sizeof(uint16_t): 119 case sizeof(uint8_t): 120 default: 121 panic("invalid access size(?) for tsunami register!\n"); 122 } 123 DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 124 125 return No_Fault; 126} 127 128Fault 129TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 130{ 131 DPRINTF(Tsunami, "write - va=%#x size=%d \n", 132 req->vaddr, req->size); 133 134 Addr daddr = (req->paddr & addr_mask) >> 6; 135 136 switch (req->size) { 137 138 case sizeof(uint64_t): 139 switch(daddr) { 140 case TSDEV_CC_CSR: 141 panic("TSDEV_CC_CSR write\n"); 142 return No_Fault; 143 case TSDEV_CC_MTR: 144 panic("TSDEV_CC_MTR write not implemented\n"); 145 return No_Fault; 146 case TSDEV_CC_MISC: 147 //If it is the seventh bit, clear the RTC interrupt 148 if ((*(uint64_t*) data) & (1<<4)) { 149 RTCInterrupting = false; 150 tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0); 151 DPRINTF(Tsunami, "clearing rtc interrupt\n"); 152 misc &= ~(1<<4); 153 } else panic("TSDEV_CC_MISC write not implemented\n"); 154 return No_Fault; 155 case TSDEV_CC_AAR0: 156 case TSDEV_CC_AAR1: 157 case TSDEV_CC_AAR2: 158 case TSDEV_CC_AAR3: 159 panic("TSDEV_CC_AARx write not implemeted\n"); 160 return No_Fault; 161 case TSDEV_CC_DIM0: 162 dim[0] = *(uint64_t*)data; 163 if (dim[0] & drir) { 164 dir[0] = dim[0] & drir; 165 if (!dirInterrupting[0]) { 166 dirInterrupting[0] = true; 167 tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0); 168 DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 169 } 170 } 171 return No_Fault; 172 case TSDEV_CC_DIM1: 173 dim[1] = *(uint64_t*)data; 174 if (dim[1] & drir) { 175 dir[1] = dim[1] & drir; 176 if (!dirInterrupting[1]) { 177 dirInterrupting[1] = true; 178 tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0); 179 DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n"); 180 } 181 } 182 return No_Fault; 183 case TSDEV_CC_DIM2: 184 dim[2] = *(uint64_t*)data; 185 if (dim[2] & drir) { 186 dir[2] = dim[2] & drir; 187 if (!dirInterrupting[2]) { 188 dirInterrupting[2] = true; 189 tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0); 190 DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n"); 191 } 192 } 193 return No_Fault; 194 case TSDEV_CC_DIM3: 195 dim[3] = *(uint64_t*)data; 196 if ((dim[3] & drir) /*And Not Already Int*/) { 197 dir[3] = dim[3] & drir; 198 if (!dirInterrupting[3]) { 199 dirInterrupting[3] = true; 200 tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0); 201 DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n"); 202 } 203 } 204 return No_Fault; 205 case TSDEV_CC_DIR0: 206 case TSDEV_CC_DIR1: 207 case TSDEV_CC_DIR2: 208 case TSDEV_CC_DIR3: 209 panic("TSDEV_CC_DIR write not implemented\n"); 210 return No_Fault; 211 case TSDEV_CC_DRIR: 212 panic("TSDEV_CC_DRIR write not implemented\n"); 213 return No_Fault; 214 case TSDEV_CC_PRBEN: 215 panic("TSDEV_CC_PRBEN write not implemented\n"); 216 return No_Fault; 217 case TSDEV_CC_IIC0: 218 case TSDEV_CC_IIC1: 219 case TSDEV_CC_IIC2: 220 case TSDEV_CC_IIC3: 221 panic("TSDEV_CC_IICx write not implemented\n"); 222 return No_Fault; 223 case TSDEV_CC_MPR0: 224 case TSDEV_CC_MPR1: 225 case TSDEV_CC_MPR2: 226 case TSDEV_CC_MPR3: 227 panic("TSDEV_CC_MPRx write not implemented\n"); 228 return No_Fault; 229 default: 230 panic("default in cchip read reached, accessing 0x%x\n"); 231 } 232 233 break; 234 case sizeof(uint32_t): 235 case sizeof(uint16_t): 236 case sizeof(uint8_t): 237 default: 238 panic("invalid access size(?) for tsunami register!\n"); 239 } 240 241 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 242 243 return No_Fault; 244} 245 246void 247TsunamiCChip::postDRIR(uint64_t bitvector) 248{ 249 drir |= bitvector; 250 for(int i=0; i < Tsunami::Max_CPUs; i++) { 251 if (bitvector & dim[i]) { 252 dir[i] |= bitvector; 253 if (!dirInterrupting[i]) { 254 dirInterrupting[i] = true; 255 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0); 256 DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i); 257 } 258 } 259 } 260} 261 262void 263TsunamiCChip::clearDRIR(uint64_t bitvector) 264{ 265 drir &= ~bitvector; 266 for(int i=0; i < Tsunami::Max_CPUs; i++) { 267 dir[i] &= ~bitvector; 268 if (!dir[i]) { 269 dirInterrupting[i] = false; 270 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0); 271 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i); 272 273 } 274 } 275} 276 277void 278TsunamiCChip::serialize(std::ostream &os) 279{ 280 // code should be written 281} 282 283void 284TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 285{ 286 //code should be written 287} 288 289BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 290 291 SimObjectParam<Tsunami *> tsunami; 292 SimObjectParam<MemoryController *> mmu; 293 Param<Addr> addr; 294 Param<Addr> mask; 295 296END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 297 298BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 299 300 INIT_PARAM(tsunami, "Tsunami"), 301 INIT_PARAM(mmu, "Memory Controller"), 302 INIT_PARAM(addr, "Device Address"), 303 INIT_PARAM(mask, "Address Mask") 304 305END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 306 307CREATE_SIM_OBJECT(TsunamiCChip) 308{ 309 return new TsunamiCChip(getInstanceName(), tsunami, addr, mask, mmu); 310} 311 312REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 313