tsunami_cchip.cc revision 777
14679Sgblack@eecs.umich.edu/* $Id$ */
24679Sgblack@eecs.umich.edu
34679Sgblack@eecs.umich.edu/* @file
44679Sgblack@eecs.umich.edu * Tsunami CChip (processor, memory, or IO)
54679Sgblack@eecs.umich.edu */
64679Sgblack@eecs.umich.edu
74679Sgblack@eecs.umich.edu#include <deque>
84679Sgblack@eecs.umich.edu#include <string>
94679Sgblack@eecs.umich.edu#include <vector>
104679Sgblack@eecs.umich.edu
114679Sgblack@eecs.umich.edu#include "base/trace.hh"
124679Sgblack@eecs.umich.edu#include "cpu/exec_context.hh"
134679Sgblack@eecs.umich.edu#include "dev/console.hh"
144679Sgblack@eecs.umich.edu#include "dev/etherdev.hh"
154679Sgblack@eecs.umich.edu#include "dev/scsi_ctrl.hh"
164679Sgblack@eecs.umich.edu#include "dev/tlaser_clock.hh"
174679Sgblack@eecs.umich.edu#include "dev/tsunami_cchip.hh"
184679Sgblack@eecs.umich.edu#include "dev/tsunamireg.h"
194679Sgblack@eecs.umich.edu#include "dev/tsunami.hh"
204679Sgblack@eecs.umich.edu#include "cpu/intr_control.hh"
214679Sgblack@eecs.umich.edu#include "mem/functional_mem/memory_control.hh"
224679Sgblack@eecs.umich.edu#include "sim/builder.hh"
234679Sgblack@eecs.umich.edu#include "sim/system.hh"
244679Sgblack@eecs.umich.edu
254679Sgblack@eecs.umich.eduusing namespace std;
264679Sgblack@eecs.umich.edu
274679Sgblack@eecs.umich.eduTsunamiCChip::TsunamiCChip(const string &name, Tsunami *t,
284679Sgblack@eecs.umich.edu                       Addr addr, Addr mask, MemoryController *mmu)
294679Sgblack@eecs.umich.edu    : MmapDevice(name, addr, mask, mmu), tsunami(t)
304679Sgblack@eecs.umich.edu{
314679Sgblack@eecs.umich.edu    for(int i=0; i < Tsunami::Max_CPUs; i++) {
324679Sgblack@eecs.umich.edu        dim[i] = 0;
334679Sgblack@eecs.umich.edu        dir[i] = 0;
344679Sgblack@eecs.umich.edu        dirInterrupting[i] = false;
354679Sgblack@eecs.umich.edu    }
364679Sgblack@eecs.umich.edu
374679Sgblack@eecs.umich.edu    drir = 0;
384679Sgblack@eecs.umich.edu    misc = 0;
394679Sgblack@eecs.umich.edu    RTCInterrupting = false;
404679Sgblack@eecs.umich.edu
414679Sgblack@eecs.umich.edu    //Put back pointer in tsunami
424679Sgblack@eecs.umich.edu    tsunami->cchip = this;
434679Sgblack@eecs.umich.edu}
444679Sgblack@eecs.umich.edu
454679Sgblack@eecs.umich.eduFault
464679Sgblack@eecs.umich.eduTsunamiCChip::read(MemReqPtr req, uint8_t *data)
474679Sgblack@eecs.umich.edu{
484679Sgblack@eecs.umich.edu    DPRINTF(Tsunami, "read  va=%#x size=%d\n",
494679Sgblack@eecs.umich.edu            req->vaddr, req->size);
504679Sgblack@eecs.umich.edu
514679Sgblack@eecs.umich.edu    Addr daddr = (req->paddr & addr_mask) >> 6;
524679Sgblack@eecs.umich.edu//    ExecContext *xc = req->xc;
534679Sgblack@eecs.umich.edu//    int cpuid = xc->cpu_id;
544679Sgblack@eecs.umich.edu
554679Sgblack@eecs.umich.edu    switch (req->size) {
564679Sgblack@eecs.umich.edu
574679Sgblack@eecs.umich.edu      case sizeof(uint64_t):
584679Sgblack@eecs.umich.edu          switch(daddr) {
594679Sgblack@eecs.umich.edu              case TSDEV_CC_CSR:
604679Sgblack@eecs.umich.edu                  *(uint64_t*)data = 0x0;
614679Sgblack@eecs.umich.edu                  return No_Fault;
624679Sgblack@eecs.umich.edu              case TSDEV_CC_MTR:
634679Sgblack@eecs.umich.edu                  panic("TSDEV_CC_MTR not implemeted\n");
644679Sgblack@eecs.umich.edu                   return No_Fault;
655083Sgblack@eecs.umich.edu              case TSDEV_CC_MISC:
665083Sgblack@eecs.umich.edu                *(uint64_t*)data = misc;
675083Sgblack@eecs.umich.edu                  return No_Fault;
685083Sgblack@eecs.umich.edu              case TSDEV_CC_AAR0:
695083Sgblack@eecs.umich.edu              case TSDEV_CC_AAR1:
705083Sgblack@eecs.umich.edu              case TSDEV_CC_AAR2:
715083Sgblack@eecs.umich.edu              case TSDEV_CC_AAR3:
725083Sgblack@eecs.umich.edu                  panic("TSDEV_CC_AARx not implemeted\n");
735083Sgblack@eecs.umich.edu                  return No_Fault;
745083Sgblack@eecs.umich.edu              case TSDEV_CC_DIM0:
755083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dim[0];
765083Sgblack@eecs.umich.edu                  return No_Fault;
775083Sgblack@eecs.umich.edu              case TSDEV_CC_DIM1:
785083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dim[1];
795083Sgblack@eecs.umich.edu                  return No_Fault;
805083Sgblack@eecs.umich.edu              case TSDEV_CC_DIM2:
815083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dim[2];
825083Sgblack@eecs.umich.edu                  return No_Fault;
835083Sgblack@eecs.umich.edu              case TSDEV_CC_DIM3:
845083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dim[3];
855083Sgblack@eecs.umich.edu                  return No_Fault;
865083Sgblack@eecs.umich.edu              case TSDEV_CC_DIR0:
875083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dir[0];
885083Sgblack@eecs.umich.edu                  return No_Fault;
895083Sgblack@eecs.umich.edu              case TSDEV_CC_DIR1:
905083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dir[1];
915083Sgblack@eecs.umich.edu                  return No_Fault;
925083Sgblack@eecs.umich.edu              case TSDEV_CC_DIR2:
935083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dir[2];
945083Sgblack@eecs.umich.edu                  return No_Fault;
955083Sgblack@eecs.umich.edu              case TSDEV_CC_DIR3:
965083Sgblack@eecs.umich.edu                  *(uint64_t*)data = dir[3];
975083Sgblack@eecs.umich.edu                  return No_Fault;
985083Sgblack@eecs.umich.edu              case TSDEV_CC_DRIR:
995083Sgblack@eecs.umich.edu                  *(uint64_t*)data = drir;
1005083Sgblack@eecs.umich.edu                  return No_Fault;
1015083Sgblack@eecs.umich.edu              case TSDEV_CC_PRBEN:
1025083Sgblack@eecs.umich.edu                  panic("TSDEV_CC_PRBEN not implemented\n");
1035083Sgblack@eecs.umich.edu                  return No_Fault;
1045083Sgblack@eecs.umich.edu              case TSDEV_CC_IIC0:
1055083Sgblack@eecs.umich.edu              case TSDEV_CC_IIC1:
1064679Sgblack@eecs.umich.edu              case TSDEV_CC_IIC2:
1074679Sgblack@eecs.umich.edu              case TSDEV_CC_IIC3:
1084679Sgblack@eecs.umich.edu                  panic("TSDEV_CC_IICx not implemented\n");
1094679Sgblack@eecs.umich.edu                  return No_Fault;
1104679Sgblack@eecs.umich.edu              case TSDEV_CC_MPR0:
1114679Sgblack@eecs.umich.edu              case TSDEV_CC_MPR1:
1124679Sgblack@eecs.umich.edu              case TSDEV_CC_MPR2:
1134679Sgblack@eecs.umich.edu              case TSDEV_CC_MPR3:
1144679Sgblack@eecs.umich.edu                  panic("TSDEV_CC_MPRx not implemented\n");
1154679Sgblack@eecs.umich.edu                  return No_Fault;
1164679Sgblack@eecs.umich.edu              default:
1174679Sgblack@eecs.umich.edu                  panic("default in cchip read reached, accessing 0x%x\n");
1184679Sgblack@eecs.umich.edu           } // uint64_t
1194679Sgblack@eecs.umich.edu
1204679Sgblack@eecs.umich.edu      break;
1214679Sgblack@eecs.umich.edu      case sizeof(uint32_t):
1224679Sgblack@eecs.umich.edu      case sizeof(uint16_t):
1234679Sgblack@eecs.umich.edu      case sizeof(uint8_t):
1244679Sgblack@eecs.umich.edu      default:
1254679Sgblack@eecs.umich.edu        panic("invalid access size(?) for tsunami register!\n");
1264679Sgblack@eecs.umich.edu    }
1274679Sgblack@eecs.umich.edu    DPRINTFN("Tsunami CChip ERROR: read  daddr=%#x size=%d\n", daddr, req->size);
1284679Sgblack@eecs.umich.edu
1294679Sgblack@eecs.umich.edu    return No_Fault;
1304679Sgblack@eecs.umich.edu}
1314679Sgblack@eecs.umich.edu
1324679Sgblack@eecs.umich.eduFault
1334679Sgblack@eecs.umich.eduTsunamiCChip::write(MemReqPtr req, const uint8_t *data)
1344679Sgblack@eecs.umich.edu{
1354679Sgblack@eecs.umich.edu    DPRINTF(Tsunami, "write - va=%#x size=%d \n",
1364679Sgblack@eecs.umich.edu            req->vaddr, req->size);
1374679Sgblack@eecs.umich.edu
1385083Sgblack@eecs.umich.edu    Addr daddr = (req->paddr & addr_mask) >> 6;
1395083Sgblack@eecs.umich.edu
1404679Sgblack@eecs.umich.edu    switch (req->size) {
1414679Sgblack@eecs.umich.edu
1424679Sgblack@eecs.umich.edu      case sizeof(uint64_t):
1434679Sgblack@eecs.umich.edu          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