tsunami_cchip.cc revision 798
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, 2512855Sgabeblack@google.com Addr addr, Addr mask, MemoryController *mmu) 2612855Sgabeblack@google.com : MmapDevice(name, addr, mask, mmu), tsunami(t) 2712855Sgabeblack@google.com{ 2812855Sgabeblack@google.com for(int i=0; i < Tsunami::Max_CPUs; i++) { 2912855Sgabeblack@google.com dim[i] = 0; 3012855Sgabeblack@google.com dir[i] = 0; 3112855Sgabeblack@google.com dirInterrupting[i] = false; 3212855Sgabeblack@google.com } 3312855Sgabeblack@google.com 3412855Sgabeblack@google.com drir = 0; 3512855Sgabeblack@google.com misc = 0; 3612855Sgabeblack@google.com RTCInterrupting = false; 3712855Sgabeblack@google.com 3812855Sgabeblack@google.com //Put back pointer in tsunami 3912855Sgabeblack@google.com tsunami->cchip = this; 4012855Sgabeblack@google.com} 4112855Sgabeblack@google.com 4212855Sgabeblack@google.comFault 4312855Sgabeblack@google.comTsunamiCChip::read(MemReqPtr &req, uint8_t *data) 4412855Sgabeblack@google.com{ 4512855Sgabeblack@google.com DPRINTF(Tsunami, "read va=%#x size=%d\n", 4612855Sgabeblack@google.com req->vaddr, req->size); 4712855Sgabeblack@google.com 4812855Sgabeblack@google.com Addr daddr = (req->paddr & addr_mask) >> 6; 4912855Sgabeblack@google.com ExecContext *xc = req->xc; 5012855Sgabeblack@google.com 5112855Sgabeblack@google.com switch (req->size) { 5212855Sgabeblack@google.com 5312855Sgabeblack@google.com case sizeof(uint64_t): 5412855Sgabeblack@google.com switch(daddr) { 5512855Sgabeblack@google.com case TSDEV_CC_CSR: 5612855Sgabeblack@google.com *(uint64_t*)data = 0x0; 5712855Sgabeblack@google.com return No_Fault; 5812855Sgabeblack@google.com case TSDEV_CC_MTR: 5912855Sgabeblack@google.com panic("TSDEV_CC_MTR not implemeted\n"); 6012855Sgabeblack@google.com return No_Fault; 6112855Sgabeblack@google.com case TSDEV_CC_MISC: 6212855Sgabeblack@google.com *(uint64_t*)data = misc | (xc->cpu_id & 0x3); 6312855Sgabeblack@google.com return No_Fault; 6412855Sgabeblack@google.com case TSDEV_CC_AAR0: 6512855Sgabeblack@google.com case TSDEV_CC_AAR1: 6612855Sgabeblack@google.com case TSDEV_CC_AAR2: 6712855Sgabeblack@google.com case TSDEV_CC_AAR3: 6812855Sgabeblack@google.com panic("TSDEV_CC_AARx not implemeted\n"); 6912855Sgabeblack@google.com return No_Fault; 7012855Sgabeblack@google.com case TSDEV_CC_DIM0: 7112855Sgabeblack@google.com *(uint64_t*)data = dim[0]; 7212855Sgabeblack@google.com return No_Fault; 7312855Sgabeblack@google.com case TSDEV_CC_DIM1: 7412855Sgabeblack@google.com *(uint64_t*)data = dim[1]; 7512855Sgabeblack@google.com return No_Fault; 7612855Sgabeblack@google.com case TSDEV_CC_DIM2: 7712855Sgabeblack@google.com *(uint64_t*)data = dim[2]; 7812855Sgabeblack@google.com return No_Fault; 7912855Sgabeblack@google.com case TSDEV_CC_DIM3: 8012855Sgabeblack@google.com *(uint64_t*)data = dim[3]; 8112855Sgabeblack@google.com return No_Fault; 8212855Sgabeblack@google.com case TSDEV_CC_DIR0: 8312855Sgabeblack@google.com *(uint64_t*)data = dir[0]; 8412855Sgabeblack@google.com return No_Fault; 8512855Sgabeblack@google.com case TSDEV_CC_DIR1: 8612855Sgabeblack@google.com *(uint64_t*)data = dir[1]; 8712855Sgabeblack@google.com return No_Fault; 8812855Sgabeblack@google.com case TSDEV_CC_DIR2: 8912855Sgabeblack@google.com *(uint64_t*)data = dir[2]; 9012855Sgabeblack@google.com return No_Fault; 9112855Sgabeblack@google.com case TSDEV_CC_DIR3: 9212855Sgabeblack@google.com *(uint64_t*)data = dir[3]; 9312855Sgabeblack@google.com return No_Fault; 9412855Sgabeblack@google.com case TSDEV_CC_DRIR: 9512855Sgabeblack@google.com *(uint64_t*)data = drir; 9612855Sgabeblack@google.com return No_Fault; 9712855Sgabeblack@google.com case TSDEV_CC_PRBEN: 9812855Sgabeblack@google.com panic("TSDEV_CC_PRBEN not implemented\n"); 9912855Sgabeblack@google.com return No_Fault; 10012855Sgabeblack@google.com case TSDEV_CC_IIC0: 10112855Sgabeblack@google.com case TSDEV_CC_IIC1: 10212855Sgabeblack@google.com case TSDEV_CC_IIC2: 10312855Sgabeblack@google.com case TSDEV_CC_IIC3: 10412855Sgabeblack@google.com panic("TSDEV_CC_IICx not implemented\n"); 10512855Sgabeblack@google.com return No_Fault; 10612855Sgabeblack@google.com case TSDEV_CC_MPR0: 10712855Sgabeblack@google.com case TSDEV_CC_MPR1: 10812855Sgabeblack@google.com case TSDEV_CC_MPR2: 10912855Sgabeblack@google.com case TSDEV_CC_MPR3: 11012855Sgabeblack@google.com panic("TSDEV_CC_MPRx not implemented\n"); 11112855Sgabeblack@google.com return No_Fault; 11212855Sgabeblack@google.com default: 11312855Sgabeblack@google.com panic("default in cchip read reached, accessing 0x%x\n"); 11412855Sgabeblack@google.com } // 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