tsunami_cchip.cc revision 777
1/* $Id$ */ 2 3/* @file 4 * Tsunami CChip (processor, memory, or IO) 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/etherdev.hh" 15#include "dev/scsi_ctrl.hh" 16#include "dev/tlaser_clock.hh" 17#include "dev/tsunami_cchip.hh" 18#include "dev/tsunamireg.h" 19#include "dev/tsunami.hh" 20#include "cpu/intr_control.hh" 21#include "mem/functional_mem/memory_control.hh" 22#include "sim/builder.hh" 23#include "sim/system.hh" 24 25using namespace std; 26 27TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, 28 Addr addr, Addr mask, MemoryController *mmu) 29 : MmapDevice(name, addr, mask, mmu), tsunami(t) 30{ 31 for(int i=0; i < Tsunami::Max_CPUs; i++) { 32 dim[i] = 0; 33 dir[i] = 0; 34 dirInterrupting[i] = false; 35 } 36 37 drir = 0; 38 misc = 0; 39 RTCInterrupting = false; 40 41 //Put back pointer in tsunami 42 tsunami->cchip = this; 43} 44 45Fault 46TsunamiCChip::read(MemReqPtr req, uint8_t *data) 47{ 48 DPRINTF(Tsunami, "read va=%#x size=%d\n", 49 req->vaddr, req->size); 50 51 Addr daddr = (req->paddr & addr_mask) >> 6; 52// ExecContext *xc = req->xc; 53// int cpuid = xc->cpu_id; 54 55 switch (req->size) { 56 57 case sizeof(uint64_t): 58 switch(daddr) { 59 case TSDEV_CC_CSR: 60 *(uint64_t*)data = 0x0; 61 return No_Fault; 62 case TSDEV_CC_MTR: 63 panic("TSDEV_CC_MTR not implemeted\n"); 64 return No_Fault; 65 case TSDEV_CC_MISC: 66 *(uint64_t*)data = misc; 67 return No_Fault; 68 case TSDEV_CC_AAR0: 69 case TSDEV_CC_AAR1: 70 case TSDEV_CC_AAR2: 71 case TSDEV_CC_AAR3: 72 panic("TSDEV_CC_AARx not implemeted\n"); 73 return No_Fault; 74 case TSDEV_CC_DIM0: 75 *(uint64_t*)data = dim[0]; 76 return No_Fault; 77 case TSDEV_CC_DIM1: 78 *(uint64_t*)data = dim[1]; 79 return No_Fault; 80 case TSDEV_CC_DIM2: 81 *(uint64_t*)data = dim[2]; 82 return No_Fault; 83 case TSDEV_CC_DIM3: 84 *(uint64_t*)data = dim[3]; 85 return No_Fault; 86 case TSDEV_CC_DIR0: 87 *(uint64_t*)data = dir[0]; 88 return No_Fault; 89 case TSDEV_CC_DIR1: 90 *(uint64_t*)data = dir[1]; 91 return No_Fault; 92 case TSDEV_CC_DIR2: 93 *(uint64_t*)data = dir[2]; 94 return No_Fault; 95 case TSDEV_CC_DIR3: 96 *(uint64_t*)data = dir[3]; 97 return No_Fault; 98 case TSDEV_CC_DRIR: 99 *(uint64_t*)data = drir; 100 return No_Fault; 101 case TSDEV_CC_PRBEN: 102 panic("TSDEV_CC_PRBEN not implemented\n"); 103 return No_Fault; 104 case TSDEV_CC_IIC0: 105 case TSDEV_CC_IIC1: 106 case TSDEV_CC_IIC2: 107 case TSDEV_CC_IIC3: 108 panic("TSDEV_CC_IICx not implemented\n"); 109 return No_Fault; 110 case TSDEV_CC_MPR0: 111 case TSDEV_CC_MPR1: 112 case TSDEV_CC_MPR2: 113 case TSDEV_CC_MPR3: 114 panic("TSDEV_CC_MPRx not implemented\n"); 115 return No_Fault; 116 default: 117 panic("default in cchip read reached, accessing 0x%x\n"); 118 } // uint64_t 119 120 break; 121 case sizeof(uint32_t): 122 case sizeof(uint16_t): 123 case sizeof(uint8_t): 124 default: 125 panic("invalid access size(?) for tsunami register!\n"); 126 } 127 DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); 128 129 return No_Fault; 130} 131 132Fault 133TsunamiCChip::write(MemReqPtr req, const uint8_t *data) 134{ 135 DPRINTF(Tsunami, "write - va=%#x size=%d \n", 136 req->vaddr, req->size); 137 138 Addr daddr = (req->paddr & addr_mask) >> 6; 139 140 switch (req->size) { 141 142 case sizeof(uint64_t): 143 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