375664be039da43603a22d7003cef73ac7066ebc
4 * Emulation of the Tsunami CChip CSRs
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"
24 TsunamiCChip::TsunamiCChip(const string
&name
, Tsunami
*t
, Addr a
,
25 MemoryController
*mmu
)
26 : FunctionalMemory(name
), addr(a
), tsunami(t
)
28 mmu
->add_child(this, Range
<Addr
>(addr
, addr
+ size
));
30 for(int i
=0; i
< Tsunami::Max_CPUs
; i
++) {
33 dirInterrupting
[i
] = false;
38 RTCInterrupting
= false;
40 //Put back pointer in tsunami
41 tsunami
->cchip
= this;
45 TsunamiCChip::read(MemReqPtr
&req
, uint8_t *data
)
47 DPRINTF(Tsunami
, "read va=%#x size=%d\n",
48 req
->vaddr
, req
->size
);
50 Addr daddr
= (req
->paddr
- (addr
& PA_IMPL_MASK
)) >> 6;
51 ExecContext
*xc
= req
->xc
;
55 case sizeof(uint64_t):
58 *(uint64_t*)data
= 0x0;
61 panic("TSDEV_CC_MTR not implemeted\n");
64 *(uint64_t*)data
= misc
| (xc
->cpu_id
& 0x3);
70 panic("TSDEV_CC_AARx not implemeted\n");
73 *(uint64_t*)data
= dim
[0];
76 *(uint64_t*)data
= dim
[1];
79 *(uint64_t*)data
= dim
[2];
82 *(uint64_t*)data
= dim
[3];
85 *(uint64_t*)data
= dir
[0];
88 *(uint64_t*)data
= dir
[1];
91 *(uint64_t*)data
= dir
[2];
94 *(uint64_t*)data
= dir
[3];
97 *(uint64_t*)data
= drir
;
100 panic("TSDEV_CC_PRBEN not implemented\n");
106 panic("TSDEV_CC_IICx not implemented\n");
112 panic("TSDEV_CC_MPRx not implemented\n");
115 panic("default in cchip read reached, accessing 0x%x\n");
119 case sizeof(uint32_t):
120 case sizeof(uint16_t):
121 case sizeof(uint8_t):
123 panic("invalid access size(?) for tsunami register!\n");
125 DPRINTFN("Tsunami CChip ERROR: read daddr=%#x size=%d\n", daddr
, req
->size
);
131 TsunamiCChip::write(MemReqPtr
&req
, const uint8_t *data
)
133 DPRINTF(Tsunami
, "write - va=%#x size=%d \n",
134 req
->vaddr
, req
->size
);
136 Addr daddr
= (req
->paddr
- (addr
& PA_IMPL_MASK
)) >> 6;
141 case sizeof(uint64_t):
144 panic("TSDEV_CC_CSR write\n");
147 panic("TSDEV_CC_MTR write not implemented\n");
150 //If it is the seventh bit, clear the RTC interrupt
151 if ((*(uint64_t*) data
) & (1<<4)) {
152 RTCInterrupting
= false;
153 tsunami
->intrctrl
->clear(0, TheISA::INTLEVEL_IRQ2
, 0);
154 DPRINTF(Tsunami
, "clearing rtc interrupt\n");
156 } else panic("TSDEV_CC_MISC write not implemented\n");
162 panic("TSDEV_CC_AARx write not implemeted\n");
169 if(daddr
== TSDEV_CC_DIM0
)
171 else if(daddr
== TSDEV_CC_DIM1
)
173 else if(daddr
== TSDEV_CC_DIM2
)
178 olddim
= dim
[number
];
179 dim
[number
] = *(uint64_t*)data
;
180 dir
[number
] = dim
[number
] & drir
;
182 for(int x
= 0; x
< 64; x
++)
185 // Figure out which bits have changed
186 if ((dim
[number
] & bitvector
) != (olddim
& bitvector
))
188 // The bit is now set and it wasn't before (set)
189 if((dim
[number
] & bitvector
) && (dir
[number
] & bitvector
))
191 tsunami
->intrctrl
->post(number
, TheISA::INTLEVEL_IRQ1
, x
);
192 DPRINTF(Tsunami
, "posting dir interrupt to cpu 0\n");
194 else if (!(dir
[number
] & bitvector
))
196 // The bit was set and now its now clear and
197 // we were interrupting on that bit before
198 tsunami
->intrctrl
->clear(number
, TheISA::INTLEVEL_IRQ1
, x
);
199 DPRINTF(Tsunami
, "dim write resulting in clear"
200 "dir interrupt to cpu 0\n");
212 panic("TSDEV_CC_DIR write not implemented\n");
214 panic("TSDEV_CC_DRIR write not implemented\n");
216 panic("TSDEV_CC_PRBEN write not implemented\n");
221 panic("TSDEV_CC_IICx write not implemented\n");
226 panic("TSDEV_CC_MPRx write not implemented\n");
228 panic("default in cchip read reached, accessing 0x%x\n");
232 case sizeof(uint32_t):
233 case sizeof(uint16_t):
234 case sizeof(uint8_t):
236 panic("invalid access size(?) for tsunami register!\n");
239 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr
, req
->size
);
245 TsunamiCChip::postDRIR(uint32_t interrupt
)
247 uint64_t bitvector
= 0x1 << interrupt
;
249 for(int i
=0; i
< Tsunami::Max_CPUs
; i
++) {
250 dir
[i
] = dim
[i
] & drir
;
251 if (dim
[i
] & bitvector
) {
252 tsunami
->intrctrl
->post(i
, TheISA::INTLEVEL_IRQ1
, interrupt
);
253 DPRINTF(Tsunami
, "posting dir interrupt to cpu %d,"
254 "interrupt %d\n",i
, interrupt
);
260 TsunamiCChip::clearDRIR(uint32_t interrupt
)
262 uint64_t bitvector
= 0x1 << interrupt
;
263 if (drir
& bitvector
)
266 for(int i
=0; i
< Tsunami::Max_CPUs
; i
++) {
267 if (dir
[i
] & bitvector
) {
268 tsunami
->intrctrl
->clear(i
, TheISA::INTLEVEL_IRQ1
, interrupt
);
269 DPRINTF(Tsunami
, "clearing dir interrupt to cpu %d,"
270 "interrupt %d\n",i
, interrupt
);
273 dir
[i
] = dim
[i
] & drir
;
277 DPRINTF(Tsunami
, "Spurrious clear? interrupt %d\n", interrupt
);
281 TsunamiCChip::serialize(std::ostream
&os
)
283 SERIALIZE_ARRAY(dim
, Tsunami::Max_CPUs
);
284 SERIALIZE_ARRAY(dir
, Tsunami::Max_CPUs
);
285 SERIALIZE_ARRAY(dirInterrupting
, Tsunami::Max_CPUs
);
286 SERIALIZE_SCALAR(drir
);
287 SERIALIZE_SCALAR(misc
);
288 SERIALIZE_SCALAR(RTCInterrupting
);
292 TsunamiCChip::unserialize(Checkpoint
*cp
, const std::string
§ion
)
294 UNSERIALIZE_ARRAY(dim
, Tsunami::Max_CPUs
);
295 UNSERIALIZE_ARRAY(dir
, Tsunami::Max_CPUs
);
296 UNSERIALIZE_ARRAY(dirInterrupting
, Tsunami::Max_CPUs
);
297 UNSERIALIZE_SCALAR(drir
);
298 UNSERIALIZE_SCALAR(misc
);
299 UNSERIALIZE_SCALAR(RTCInterrupting
);
302 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip
)
304 SimObjectParam
<Tsunami
*> tsunami
;
305 SimObjectParam
<MemoryController
*> mmu
;
308 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip
)
310 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip
)
312 INIT_PARAM(tsunami
, "Tsunami"),
313 INIT_PARAM(mmu
, "Memory Controller"),
314 INIT_PARAM(addr
, "Device Address")
316 END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip
)
318 CREATE_SIM_OBJECT(TsunamiCChip
)
320 return new TsunamiCChip(getInstanceName(), tsunami
, addr
, mmu
);
323 REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip
)