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 &section)
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