tsunami_cchip.cc revision 798
12810SN/A/* $Id$ */
22810SN/A
32810SN/A/* @file
42810SN/A * Emulation of the Tsunami CChip CSRs
52810SN/A */
62810SN/A
72810SN/A#include <deque>
82810SN/A#include <string>
92810SN/A#include <vector>
102810SN/A
112810SN/A#include "base/trace.hh"
122810SN/A#include "cpu/exec_context.hh"
132810SN/A#include "dev/console.hh"
142810SN/A#include "dev/tsunami_cchip.hh"
152810SN/A#include "dev/tsunamireg.h"
162810SN/A#include "dev/tsunami.hh"
172810SN/A#include "cpu/intr_control.hh"
182810SN/A#include "mem/functional_mem/memory_control.hh"
192810SN/A#include "sim/builder.hh"
202810SN/A#include "sim/system.hh"
212810SN/A
222810SN/Ausing namespace std;
232810SN/A
242810SN/ATsunamiCChip::TsunamiCChip(const string &name, Tsunami *t,
252810SN/A                       Addr addr, Addr mask, MemoryController *mmu)
262810SN/A    : MmapDevice(name, addr, mask, mmu), tsunami(t)
272810SN/A{
282810SN/A    for(int i=0; i < Tsunami::Max_CPUs; i++) {
294458SN/A        dim[i] = 0;
304458SN/A        dir[i] = 0;
312810SN/A        dirInterrupting[i] = false;
322810SN/A    }
332810SN/A
342810SN/A    drir = 0;
352810SN/A    misc = 0;
362810SN/A    RTCInterrupting = false;
372810SN/A
382810SN/A    //Put back pointer in tsunami
392810SN/A    tsunami->cchip = this;
402810SN/A}
417676Snate@binkert.org
427676Snate@binkert.orgFault
437676Snate@binkert.orgTsunamiCChip::read(MemReqPtr &req, uint8_t *data)
442810SN/A{
452810SN/A    DPRINTF(Tsunami, "read  va=%#x size=%d\n",
462825SN/A            req->vaddr, req->size);
472810SN/A
482810SN/A    Addr daddr = (req->paddr & addr_mask) >> 6;
496215Snate@binkert.org    ExecContext *xc = req->xc;
506978SLisa.Hsu@amd.com
518232Snate@binkert.org    switch (req->size) {
528232Snate@binkert.org
535338Sstever@gmail.com      case sizeof(uint64_t):
542810SN/A          switch(daddr) {
552810SN/A              case TSDEV_CC_CSR:
568229Snate@binkert.org                  *(uint64_t*)data = 0x0;
574626SN/A                  return No_Fault;
585034SN/A              case TSDEV_CC_MTR:
592811SN/A                  panic("TSDEV_CC_MTR not implemeted\n");
608786Sgblack@eecs.umich.edu                   return No_Fault;
614626SN/A              case TSDEV_CC_MISC:
622810SN/A                *(uint64_t*)data = misc | (xc->cpu_id & 0x3);
633194SN/A                  return No_Fault;
642810SN/A              case TSDEV_CC_AAR0:
652810SN/A              case TSDEV_CC_AAR1:
662810SN/A              case TSDEV_CC_AAR2:
672810SN/A              case TSDEV_CC_AAR3:
682810SN/A                  panic("TSDEV_CC_AARx not implemeted\n");
694628SN/A                  return No_Fault;
704628SN/A              case TSDEV_CC_DIM0:
714628SN/A                  *(uint64_t*)data = dim[0];
724628SN/A                  return No_Fault;
734628SN/A              case TSDEV_CC_DIM1:
744628SN/A                  *(uint64_t*)data = dim[1];
754628SN/A                  return No_Fault;
764628SN/A              case TSDEV_CC_DIM2:
774628SN/A                  *(uint64_t*)data = dim[2];
784628SN/A                  return No_Fault;
794628SN/A              case TSDEV_CC_DIM3:
804628SN/A                  *(uint64_t*)data = dim[3];
814628SN/A                  return No_Fault;
824628SN/A              case TSDEV_CC_DIR0:
834628SN/A                  *(uint64_t*)data = dir[0];
844628SN/A                  return No_Fault;
854628SN/A              case TSDEV_CC_DIR1:
864628SN/A                  *(uint64_t*)data = dir[1];
874628SN/A                  return No_Fault;
884628SN/A              case TSDEV_CC_DIR2:
894628SN/A                  *(uint64_t*)data = dir[2];
904628SN/A                  return No_Fault;
914628SN/A              case TSDEV_CC_DIR3:
924628SN/A                  *(uint64_t*)data = dir[3];
934628SN/A                  return No_Fault;
944628SN/A              case TSDEV_CC_DRIR:
954628SN/A                  *(uint64_t*)data = drir;
964628SN/A                  return No_Fault;
974628SN/A              case TSDEV_CC_PRBEN:
984628SN/A                  panic("TSDEV_CC_PRBEN not implemented\n");
994628SN/A                  return No_Fault;
1004626SN/A              case TSDEV_CC_IIC0:
1012810SN/A              case TSDEV_CC_IIC1:
1022844SN/A              case TSDEV_CC_IIC2:
1032810SN/A              case TSDEV_CC_IIC3:
1042810SN/A                  panic("TSDEV_CC_IICx not implemented\n");
1053738SN/A                  return No_Fault;
1064965SN/A              case TSDEV_CC_MPR0:
1076122SSteve.Reinhardt@amd.com              case TSDEV_CC_MPR1:
1084458SN/A              case TSDEV_CC_MPR2:
1092810SN/A              case TSDEV_CC_MPR3:
1102810SN/A                  panic("TSDEV_CC_MPRx not implemented\n");
1116227Snate@binkert.org                  return No_Fault;
1122810SN/A              default:
1134458SN/A                  panic("default in cchip read reached, accessing 0x%x\n");
1143013SN/A           } // uint64_t
1154666SN/A
1164666SN/A      break;
1174666SN/A      case sizeof(uint32_t):
1185314SN/A      case sizeof(uint16_t):
1195314SN/A      case sizeof(uint8_t):
1202811SN/A      default:
1214458SN/A        panic("invalid access size(?) for tsunami register!\n");
1224458SN/A    }
1232810SN/A    DPRINTFN("Tsunami CChip ERROR: read  daddr=%#x size=%d\n", daddr, req->size);
1242810SN/A
1252810SN/A    return No_Fault;
1262810SN/A}
1275314SN/A
1283606SN/AFault
1294458SN/ATsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
1304458SN/A{
1312810SN/A    DPRINTF(Tsunami, "write - va=%#x size=%d \n",
1322810SN/A            req->vaddr, req->size);
1332897SN/A
1342897SN/A    Addr daddr = (req->paddr & addr_mask) >> 6;
1354458SN/A
1364458SN/A    switch (req->size) {
1374888SN/A
1384666SN/A      case sizeof(uint64_t):
1394666SN/A          switch(daddr) {
1404458SN/A              case TSDEV_CC_CSR:
1414458SN/A                  panic("TSDEV_CC_CSR write\n");
1424458SN/A                  return No_Fault;
1434626SN/A              case TSDEV_CC_MTR:
1444626SN/A                  panic("TSDEV_CC_MTR write not implemented\n");
1454626SN/A                   return No_Fault;
1462811SN/A              case TSDEV_CC_MISC:
1472810SN/A                //If it is the seventh bit, clear the RTC interrupt
1483338SN/A                if ((*(uint64_t*) data) & (1<<4)) {
1493338SN/A                    RTCInterrupting = false;
1503738SN/A                    tsunami->intrctrl->clear(0, TheISA::INTLEVEL_IRQ2, 0);
1513338SN/A                    DPRINTF(Tsunami, "clearing rtc interrupt\n");
1524626SN/A                    misc &= ~(1<<4);
1534626SN/A                } else panic("TSDEV_CC_MISC write not implemented\n");
1544626SN/A                  return No_Fault;
1554626SN/A              case TSDEV_CC_AAR0:
1564626SN/A              case TSDEV_CC_AAR1:
1574626SN/A              case TSDEV_CC_AAR2:
1584626SN/A              case TSDEV_CC_AAR3:
1594626SN/A                  panic("TSDEV_CC_AARx write not implemeted\n");
1604628SN/A                  return No_Fault;
1614628SN/A              case TSDEV_CC_DIM0:
1624628SN/A                   dim[0] = *(uint64_t*)data;
1634666SN/A                   if (dim[0] & drir) {
1644628SN/A                       dir[0] = dim[0] & drir;
1654628SN/A                       if (!dirInterrupting[0]) {
1664628SN/A                           dirInterrupting[0] = true;
1674628SN/A                           tsunami->intrctrl->post(0, TheISA::INTLEVEL_IRQ1, 0);
1684628SN/A                           DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
1694628SN/A                       }
1704628SN/A                   }
1714628SN/A                  return No_Fault;
1724628SN/A              case TSDEV_CC_DIM1:
1734628SN/A                  dim[1] = *(uint64_t*)data;
1744628SN/A                  if (dim[1] & drir) {
1754628SN/A                       dir[1] = dim[1] & drir;
1767667Ssteve.reinhardt@amd.com                       if (!dirInterrupting[1]) {
1774628SN/A                           dirInterrupting[1] = true;
1784628SN/A                           tsunami->intrctrl->post(1, TheISA::INTLEVEL_IRQ1, 0);
1794628SN/A                           DPRINTF(Tsunami, "posting dir interrupt to cpu 1\n");
1807667Ssteve.reinhardt@amd.com                       }
1814628SN/A                  }
1824628SN/A                  return No_Fault;
1834628SN/A              case TSDEV_CC_DIM2:
1844628SN/A                  dim[2] = *(uint64_t*)data;
1854628SN/A                  if (dim[2] & drir) {
1864626SN/A                       dir[2] = dim[2] & drir;
1876227Snate@binkert.org                       if (!dirInterrupting[2]) {
1884626SN/A                           dirInterrupting[2] = true;
1894630SN/A                           tsunami->intrctrl->post(2, TheISA::INTLEVEL_IRQ1, 0);
1904630SN/A                           DPRINTF(Tsunami, "posting dir interrupt to cpu 2\n");
1914630SN/A                       }
1924630SN/A                  }
1934630SN/A                  return No_Fault;
1944626SN/A              case TSDEV_CC_DIM3:
1954626SN/A                  dim[3] = *(uint64_t*)data;
1964626SN/A                  if ((dim[3] & drir) /*And Not Already Int*/) {
1976122SSteve.Reinhardt@amd.com                       dir[3] = dim[3] & drir;
1986122SSteve.Reinhardt@amd.com                       if (!dirInterrupting[3]) {
1994626SN/A                           dirInterrupting[3] = true;
2008134SAli.Saidi@ARM.com                           tsunami->intrctrl->post(3, TheISA::INTLEVEL_IRQ1, 0);
2018134SAli.Saidi@ARM.com                           DPRINTF(Tsunami, "posting dir interrupt to cpu 3\n");
2028134SAli.Saidi@ARM.com                       }
2038134SAli.Saidi@ARM.com                  }
2048134SAli.Saidi@ARM.com                  return No_Fault;
2052810SN/A              case TSDEV_CC_DIR0:
2062810SN/A              case TSDEV_CC_DIR1:
2072810SN/A              case TSDEV_CC_DIR2:
2082810SN/A              case TSDEV_CC_DIR3:
2092810SN/A                  panic("TSDEV_CC_DIR write not implemented\n");
2102810SN/A                  return No_Fault;
2116122SSteve.Reinhardt@amd.com              case TSDEV_CC_DRIR:
2126122SSteve.Reinhardt@amd.com                  panic("TSDEV_CC_DRIR write not implemented\n");
2136122SSteve.Reinhardt@amd.com                  return No_Fault;
2142810SN/A              case TSDEV_CC_PRBEN:
2152810SN/A                  panic("TSDEV_CC_PRBEN write not implemented\n");
2162810SN/A                  return No_Fault;
2174626SN/A              case TSDEV_CC_IIC0:
2184626SN/A              case TSDEV_CC_IIC1:
2192810SN/A              case TSDEV_CC_IIC2:
2202810SN/A              case TSDEV_CC_IIC3:
2212810SN/A                  panic("TSDEV_CC_IICx write not implemented\n");
2222810SN/A                  return No_Fault;
2233503SN/A              case TSDEV_CC_MPR0:
2243503SN/A              case TSDEV_CC_MPR1:
2253503SN/A              case TSDEV_CC_MPR2:
2266122SSteve.Reinhardt@amd.com              case TSDEV_CC_MPR3:
2276122SSteve.Reinhardt@amd.com                  panic("TSDEV_CC_MPRx write not implemented\n");
2286122SSteve.Reinhardt@amd.com                  return No_Fault;
2296122SSteve.Reinhardt@amd.com              default:
2306122SSteve.Reinhardt@amd.com                  panic("default in cchip read reached, accessing 0x%x\n");
2316978SLisa.Hsu@amd.com          }
2326978SLisa.Hsu@amd.com
2336978SLisa.Hsu@amd.com      break;
2342810SN/A      case sizeof(uint32_t):
2356978SLisa.Hsu@amd.com      case sizeof(uint16_t):
2362810SN/A      case sizeof(uint8_t):
2372810SN/A      default:
2382810SN/A        panic("invalid access size(?) for tsunami register!\n");
2392810SN/A    }
2402810SN/A
2412810SN/A    DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size);
2422810SN/A
2435999Snate@binkert.org    return No_Fault;
2442810SN/A}
2452810SN/A
2462810SN/Avoid
2472810SN/ATsunamiCChip::postDRIR(uint64_t bitvector)
2482810SN/A{
2492810SN/A    drir |= bitvector;
2505999Snate@binkert.org    for(int i=0; i < Tsunami::Max_CPUs; i++) {
2512810SN/A        if (bitvector & dim[i]) {
2522810SN/A            dir[i] |= bitvector;
2532810SN/A            if (!dirInterrupting[i]) {
2542810SN/A                dirInterrupting[i] = true;
2552810SN/A                tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, 0);
2562810SN/A                DPRINTF(Tsunami, "posting dir interrupt to cpu %d\n",i);
2572810SN/A            }
2582810SN/A        }
2592810SN/A    }
2605999Snate@binkert.org}
2612810SN/A
2622810SN/Avoid
2632810SN/ATsunamiCChip::clearDRIR(uint64_t bitvector)
2642810SN/A{
2652810SN/A    drir &= ~bitvector;
2662810SN/A    for(int i=0; i < Tsunami::Max_CPUs; i++) {
2674022SN/A        dir[i] &= ~bitvector;
2682810SN/A        if (!dir[i]) {
2692810SN/A            dirInterrupting[i] = false;
2702810SN/A            tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, 0);
2712810SN/A            DPRINTF(Tsunami, "clearing dir interrupt to cpu %d\n", i);
2722810SN/A
2732810SN/A        }
2744022SN/A    }
2752810SN/A}
2762810SN/A
2772810SN/Avoid
2782810SN/ATsunamiCChip::serialize(std::ostream &os)
2792810SN/A{
2802810SN/A    // code should be written
2814022SN/A}
2822810SN/A
2832810SN/Avoid
2842810SN/ATsunamiCChip::unserialize(Checkpoint *cp, const std::string &section)
2852810SN/A{
2862810SN/A    //code should be written
2872810SN/A}
2885999Snate@binkert.org
2892810SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
2905999Snate@binkert.org
2912810SN/A    SimObjectParam<Tsunami *> tsunami;
2922810SN/A    SimObjectParam<MemoryController *> mmu;
2932810SN/A    Param<Addr> addr;
2942810SN/A    Param<Addr> mask;
2952810SN/A
2965999Snate@binkert.orgEND_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
2972810SN/A
2982810SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
2995999Snate@binkert.org
3002810SN/A    INIT_PARAM(tsunami, "Tsunami"),
3014626SN/A    INIT_PARAM(mmu, "Memory Controller"),
3025999Snate@binkert.org    INIT_PARAM(addr, "Device Address"),
3034626SN/A    INIT_PARAM(mask, "Address Mask")
3044626SN/A
3055999Snate@binkert.orgEND_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
3064626SN/A
3074626SN/ACREATE_SIM_OBJECT(TsunamiCChip)
3084626SN/A{
3094626SN/A    return new TsunamiCChip(getInstanceName(), tsunami, addr, mask, mmu);
3104626SN/A}
3114626SN/A
3125999Snate@binkert.orgREGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)
3134626SN/A