Fix PCI code so it builds properly now
[gem5.git] / dev / tsunami_cchip.cc
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/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
22 using namespace std;
23
24 TsunamiCChip::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
42 Fault
43 TsunamiCChip::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
128 Fault
129 TsunamiCChip::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
246 void
247 TsunamiCChip::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
262 void
263 TsunamiCChip::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
277 void
278 TsunamiCChip::serialize(std::ostream &os)
279 {
280 // code should be written
281 }
282
283 void
284 TsunamiCChip::unserialize(Checkpoint *cp, const std::string &section)
285 {
286 //code should be written
287 }
288
289 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
290
291 SimObjectParam<Tsunami *> tsunami;
292 SimObjectParam<MemoryController *> mmu;
293 Param<Addr> addr;
294 Param<Addr> mask;
295
296 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
297
298 BEGIN_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
305 END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
306
307 CREATE_SIM_OBJECT(TsunamiCChip)
308 {
309 return new TsunamiCChip(getInstanceName(), tsunami, addr, mask, mmu);
310 }
311
312 REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)