tsunami_cchip.cc revision 798
112855Sgabeblack@google.com/* $Id$ */
212855Sgabeblack@google.com
312855Sgabeblack@google.com/* @file
412855Sgabeblack@google.com * Emulation of the Tsunami CChip CSRs
512855Sgabeblack@google.com */
612855Sgabeblack@google.com
712855Sgabeblack@google.com#include <deque>
812855Sgabeblack@google.com#include <string>
912855Sgabeblack@google.com#include <vector>
1012855Sgabeblack@google.com
1112855Sgabeblack@google.com#include "base/trace.hh"
1212855Sgabeblack@google.com#include "cpu/exec_context.hh"
1312855Sgabeblack@google.com#include "dev/console.hh"
1412855Sgabeblack@google.com#include "dev/tsunami_cchip.hh"
1512855Sgabeblack@google.com#include "dev/tsunamireg.h"
1612855Sgabeblack@google.com#include "dev/tsunami.hh"
1712855Sgabeblack@google.com#include "cpu/intr_control.hh"
1812855Sgabeblack@google.com#include "mem/functional_mem/memory_control.hh"
1912855Sgabeblack@google.com#include "sim/builder.hh"
2012855Sgabeblack@google.com#include "sim/system.hh"
2112855Sgabeblack@google.com
2212855Sgabeblack@google.comusing namespace std;
2312855Sgabeblack@google.com
2412855Sgabeblack@google.comTsunamiCChip::TsunamiCChip(const string &name, Tsunami *t,
2512855Sgabeblack@google.com                       Addr addr, Addr mask, MemoryController *mmu)
2612855Sgabeblack@google.com    : MmapDevice(name, addr, mask, mmu), tsunami(t)
2712855Sgabeblack@google.com{
2812855Sgabeblack@google.com    for(int i=0; i < Tsunami::Max_CPUs; i++) {
2912855Sgabeblack@google.com        dim[i] = 0;
3012855Sgabeblack@google.com        dir[i] = 0;
3112855Sgabeblack@google.com        dirInterrupting[i] = false;
3212855Sgabeblack@google.com    }
3312855Sgabeblack@google.com
3412855Sgabeblack@google.com    drir = 0;
3512855Sgabeblack@google.com    misc = 0;
3612855Sgabeblack@google.com    RTCInterrupting = false;
3712855Sgabeblack@google.com
3812855Sgabeblack@google.com    //Put back pointer in tsunami
3912855Sgabeblack@google.com    tsunami->cchip = this;
4012855Sgabeblack@google.com}
4112855Sgabeblack@google.com
4212855Sgabeblack@google.comFault
4312855Sgabeblack@google.comTsunamiCChip::read(MemReqPtr &req, uint8_t *data)
4412855Sgabeblack@google.com{
4512855Sgabeblack@google.com    DPRINTF(Tsunami, "read  va=%#x size=%d\n",
4612855Sgabeblack@google.com            req->vaddr, req->size);
4712855Sgabeblack@google.com
4812855Sgabeblack@google.com    Addr daddr = (req->paddr & addr_mask) >> 6;
4912855Sgabeblack@google.com    ExecContext *xc = req->xc;
5012855Sgabeblack@google.com
5112855Sgabeblack@google.com    switch (req->size) {
5212855Sgabeblack@google.com
5312855Sgabeblack@google.com      case sizeof(uint64_t):
5412855Sgabeblack@google.com          switch(daddr) {
5512855Sgabeblack@google.com              case TSDEV_CC_CSR:
5612855Sgabeblack@google.com                  *(uint64_t*)data = 0x0;
5712855Sgabeblack@google.com                  return No_Fault;
5812855Sgabeblack@google.com              case TSDEV_CC_MTR:
5912855Sgabeblack@google.com                  panic("TSDEV_CC_MTR not implemeted\n");
6012855Sgabeblack@google.com                   return No_Fault;
6112855Sgabeblack@google.com              case TSDEV_CC_MISC:
6212855Sgabeblack@google.com                *(uint64_t*)data = misc | (xc->cpu_id & 0x3);
6312855Sgabeblack@google.com                  return No_Fault;
6412855Sgabeblack@google.com              case TSDEV_CC_AAR0:
6512855Sgabeblack@google.com              case TSDEV_CC_AAR1:
6612855Sgabeblack@google.com              case TSDEV_CC_AAR2:
6712855Sgabeblack@google.com              case TSDEV_CC_AAR3:
6812855Sgabeblack@google.com                  panic("TSDEV_CC_AARx not implemeted\n");
6912855Sgabeblack@google.com                  return No_Fault;
7012855Sgabeblack@google.com              case TSDEV_CC_DIM0:
7112855Sgabeblack@google.com                  *(uint64_t*)data = dim[0];
7212855Sgabeblack@google.com                  return No_Fault;
7312855Sgabeblack@google.com              case TSDEV_CC_DIM1:
7412855Sgabeblack@google.com                  *(uint64_t*)data = dim[1];
7512855Sgabeblack@google.com                  return No_Fault;
7612855Sgabeblack@google.com              case TSDEV_CC_DIM2:
7712855Sgabeblack@google.com                  *(uint64_t*)data = dim[2];
7812855Sgabeblack@google.com                  return No_Fault;
7912855Sgabeblack@google.com              case TSDEV_CC_DIM3:
8012855Sgabeblack@google.com                  *(uint64_t*)data = dim[3];
8112855Sgabeblack@google.com                  return No_Fault;
8212855Sgabeblack@google.com              case TSDEV_CC_DIR0:
8312855Sgabeblack@google.com                  *(uint64_t*)data = dir[0];
8412855Sgabeblack@google.com                  return No_Fault;
8512855Sgabeblack@google.com              case TSDEV_CC_DIR1:
8612855Sgabeblack@google.com                  *(uint64_t*)data = dir[1];
8712855Sgabeblack@google.com                  return No_Fault;
8812855Sgabeblack@google.com              case TSDEV_CC_DIR2:
8912855Sgabeblack@google.com                  *(uint64_t*)data = dir[2];
9012855Sgabeblack@google.com                  return No_Fault;
9112855Sgabeblack@google.com              case TSDEV_CC_DIR3:
9212855Sgabeblack@google.com                  *(uint64_t*)data = dir[3];
9312855Sgabeblack@google.com                  return No_Fault;
9412855Sgabeblack@google.com              case TSDEV_CC_DRIR:
9512855Sgabeblack@google.com                  *(uint64_t*)data = drir;
9612855Sgabeblack@google.com                  return No_Fault;
9712855Sgabeblack@google.com              case TSDEV_CC_PRBEN:
9812855Sgabeblack@google.com                  panic("TSDEV_CC_PRBEN not implemented\n");
9912855Sgabeblack@google.com                  return No_Fault;
10012855Sgabeblack@google.com              case TSDEV_CC_IIC0:
10112855Sgabeblack@google.com              case TSDEV_CC_IIC1:
10212855Sgabeblack@google.com              case TSDEV_CC_IIC2:
10312855Sgabeblack@google.com              case TSDEV_CC_IIC3:
10412855Sgabeblack@google.com                  panic("TSDEV_CC_IICx not implemented\n");
10512855Sgabeblack@google.com                  return No_Fault;
10612855Sgabeblack@google.com              case TSDEV_CC_MPR0:
10712855Sgabeblack@google.com              case TSDEV_CC_MPR1:
10812855Sgabeblack@google.com              case TSDEV_CC_MPR2:
10912855Sgabeblack@google.com              case TSDEV_CC_MPR3:
11012855Sgabeblack@google.com                  panic("TSDEV_CC_MPRx not implemented\n");
11112855Sgabeblack@google.com                  return No_Fault;
11212855Sgabeblack@google.com              default:
11312855Sgabeblack@google.com                  panic("default in cchip read reached, accessing 0x%x\n");
11412855Sgabeblack@google.com           } // 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