tsunami_cchip.cc revision 798
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,
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
42Fault
43TsunamiCChip::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
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 &section)
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