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