tsunami_cchip.cc revision 4870
18012Ssaidi@eecs.umich.edu/*
28013Sbinkertn@umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
38013Sbinkertn@umich.edu * All rights reserved.
48013Sbinkertn@umich.edu *
58013Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
68013Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
78013Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
88013Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
98013Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
108013Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
118013Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
128013Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
138013Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
148013Sbinkertn@umich.edu * this software without specific prior written permission.
158013Sbinkertn@umich.edu *
168013Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178013Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188013Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198013Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208013Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218013Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228013Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238013Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248013Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258013Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268013Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278013Sbinkertn@umich.edu *
288013Sbinkertn@umich.edu * Authors: Ali Saidi
298013Sbinkertn@umich.edu *          Ron Dreslinski
307977Shsul@eecs.umich.edu */
318013Sbinkertn@umich.edu
328013Sbinkertn@umich.edu/** @file
338013Sbinkertn@umich.edu * Emulation of the Tsunami CChip CSRs
348013Sbinkertn@umich.edu */
358013Sbinkertn@umich.edu
368013Sbinkertn@umich.edu#include <deque>
378013Sbinkertn@umich.edu#include <string>
388013Sbinkertn@umich.edu#include <vector>
398013Sbinkertn@umich.edu
408013Sbinkertn@umich.edu#include "arch/alpha/ev5.hh"
418013Sbinkertn@umich.edu#include "base/trace.hh"
428013Sbinkertn@umich.edu#include "cpu/intr_control.hh"
438013Sbinkertn@umich.edu#include "cpu/thread_context.hh"
448013Sbinkertn@umich.edu#include "dev/alpha/tsunami.hh"
458013Sbinkertn@umich.edu#include "dev/alpha/tsunami_cchip.hh"
468013Sbinkertn@umich.edu#include "dev/alpha/tsunamireg.h"
478013Sbinkertn@umich.edu#include "mem/packet.hh"
488013Sbinkertn@umich.edu#include "mem/packet_access.hh"
498013Sbinkertn@umich.edu#include "mem/port.hh"
508013Sbinkertn@umich.edu#include "sim/builder.hh"
518013Sbinkertn@umich.edu#include "sim/system.hh"
528013Sbinkertn@umich.edu
538013Sbinkertn@umich.eduusing namespace std;
547977Shsul@eecs.umich.edu//Should this be AlphaISA?
557977Shsul@eecs.umich.eduusing namespace TheISA;
568013Sbinkertn@umich.edu
577977Shsul@eecs.umich.eduTsunamiCChip::TsunamiCChip(Params *p)
587977Shsul@eecs.umich.edu    : BasicPioDevice(p), tsunami(p->tsunami)
598013Sbinkertn@umich.edu{
608013Sbinkertn@umich.edu    pioSize = 0x10000000;
617978Sbinkertn@umich.edu
627978Sbinkertn@umich.edu    drir = 0;
637978Sbinkertn@umich.edu    ipint = 0;
648013Sbinkertn@umich.edu    itint = 0;
657977Shsul@eecs.umich.edu
667977Shsul@eecs.umich.edu    for (int x = 0; x < Tsunami::Max_CPUs; x++)
677977Shsul@eecs.umich.edu    {
687977Shsul@eecs.umich.edu        dim[x] = 0;
697977Shsul@eecs.umich.edu        dir[x] = 0;
708013Sbinkertn@umich.edu    }
718013Sbinkertn@umich.edu
728018Smserrano@umich.edu    //Put back pointer in tsunami
738018Smserrano@umich.edu    tsunami->cchip = this;
747977Shsul@eecs.umich.edu}
757977Shsul@eecs.umich.edu
768013Sbinkertn@umich.eduTick
777977Shsul@eecs.umich.eduTsunamiCChip::read(PacketPtr pkt)
788013Sbinkertn@umich.edu{
798013Sbinkertn@umich.edu    DPRINTF(Tsunami, "read  va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
808013Sbinkertn@umich.edu
817977Shsul@eecs.umich.edu    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
828013Sbinkertn@umich.edu
838013Sbinkertn@umich.edu    Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
848013Sbinkertn@umich.edu    Addr daddr = (pkt->getAddr() - pioAddr);
858013Sbinkertn@umich.edu
868013Sbinkertn@umich.edu    pkt->allocate();
877977Shsul@eecs.umich.edu    switch (pkt->getSize()) {
887977Shsul@eecs.umich.edu
898013Sbinkertn@umich.edu      case sizeof(uint64_t):
907977Shsul@eecs.umich.edu          pkt->set<uint64_t>(0);
918010Ssaidi@eecs.umich.edu
927977Shsul@eecs.umich.edu          if (daddr & TSDEV_CC_BDIMS)
937977Shsul@eecs.umich.edu          {
947977Shsul@eecs.umich.edu              pkt->set(dim[(daddr >> 4) & 0x3F]);
957977Shsul@eecs.umich.edu              break;
968013Sbinkertn@umich.edu          }
978013Sbinkertn@umich.edu
988013Sbinkertn@umich.edu          if (daddr & TSDEV_CC_BDIRS)
998013Sbinkertn@umich.edu          {
1008013Sbinkertn@umich.edu              pkt->set(dir[(daddr >> 4) & 0x3F]);
1018009Ssaidi@eecs.umich.edu              break;
1028009Ssaidi@eecs.umich.edu          }
1037977Shsul@eecs.umich.edu
1048016Sbinkertn@umich.edu          switch(regnum) {
1058013Sbinkertn@umich.edu              case TSDEV_CC_CSR:
1068013Sbinkertn@umich.edu                  pkt->set(0x0);
1078013Sbinkertn@umich.edu                  break;
1087977Shsul@eecs.umich.edu              case TSDEV_CC_MTR:
1097977Shsul@eecs.umich.edu                  panic("TSDEV_CC_MTR not implemeted\n");
1108015Sbinkertn@umich.edu                   break;
1118013Sbinkertn@umich.edu              case TSDEV_CC_MISC:
1127977Shsul@eecs.umich.edu                  pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF |
1138013Sbinkertn@umich.edu                                     (pkt->req->getCpuNum() & 0x3));
1147977Shsul@eecs.umich.edu                  break;
1158013Sbinkertn@umich.edu              case TSDEV_CC_AAR0:
1167977Shsul@eecs.umich.edu              case TSDEV_CC_AAR1:
1177977Shsul@eecs.umich.edu              case TSDEV_CC_AAR2:
1187977Shsul@eecs.umich.edu              case TSDEV_CC_AAR3:
1198013Sbinkertn@umich.edu                  pkt->set(0);
1208013Sbinkertn@umich.edu                  break;
1218013Sbinkertn@umich.edu              case TSDEV_CC_DIM0:
1228013Sbinkertn@umich.edu                  pkt->set(dim[0]);
1238013Sbinkertn@umich.edu                  break;
1248013Sbinkertn@umich.edu              case TSDEV_CC_DIM1:
1257977Shsul@eecs.umich.edu                  pkt->set(dim[1]);
1267977Shsul@eecs.umich.edu                  break;
1277977Shsul@eecs.umich.edu              case TSDEV_CC_DIM2:
1287977Shsul@eecs.umich.edu                  pkt->set(dim[2]);
1297977Shsul@eecs.umich.edu                  break;
1307977Shsul@eecs.umich.edu              case TSDEV_CC_DIM3:
1317977Shsul@eecs.umich.edu                  pkt->set(dim[3]);
1327977Shsul@eecs.umich.edu                  break;
1338013Sbinkertn@umich.edu              case TSDEV_CC_DIR0:
1347977Shsul@eecs.umich.edu                  pkt->set(dir[0]);
1357977Shsul@eecs.umich.edu                  break;
1368013Sbinkertn@umich.edu              case TSDEV_CC_DIR1:
1378013Sbinkertn@umich.edu                  pkt->set(dir[1]);
1387977Shsul@eecs.umich.edu                  break;
1397977Shsul@eecs.umich.edu              case TSDEV_CC_DIR2:
1407977Shsul@eecs.umich.edu                  pkt->set(dir[2]);
1418013Sbinkertn@umich.edu                  break;
1428013Sbinkertn@umich.edu              case TSDEV_CC_DIR3:
1437978Sbinkertn@umich.edu                  pkt->set(dir[3]);
1448015Sbinkertn@umich.edu                  break;
1457978Sbinkertn@umich.edu              case TSDEV_CC_DRIR:
1467978Sbinkertn@umich.edu                  pkt->set(drir);
1478013Sbinkertn@umich.edu                  break;
1488013Sbinkertn@umich.edu              case TSDEV_CC_PRBEN:
1497977Shsul@eecs.umich.edu                  panic("TSDEV_CC_PRBEN not implemented\n");
1508015Sbinkertn@umich.edu                  break;
1517977Shsul@eecs.umich.edu              case TSDEV_CC_IIC0:
1527977Shsul@eecs.umich.edu              case TSDEV_CC_IIC1:
1537978Sbinkertn@umich.edu              case TSDEV_CC_IIC2:
1547978Sbinkertn@umich.edu              case TSDEV_CC_IIC3:
1558013Sbinkertn@umich.edu                  panic("TSDEV_CC_IICx not implemented\n");
1568013Sbinkertn@umich.edu                  break;
1578013Sbinkertn@umich.edu              case TSDEV_CC_MPR0:
1587977Shsul@eecs.umich.edu              case TSDEV_CC_MPR1:
1597978Sbinkertn@umich.edu              case TSDEV_CC_MPR2:
1607977Shsul@eecs.umich.edu              case TSDEV_CC_MPR3:
1617977Shsul@eecs.umich.edu                  panic("TSDEV_CC_MPRx not implemented\n");
1628013Sbinkertn@umich.edu                  break;
1638013Sbinkertn@umich.edu              case TSDEV_CC_IPIR:
1647977Shsul@eecs.umich.edu                  pkt->set(ipint);
1658013Sbinkertn@umich.edu                  break;
1668015Sbinkertn@umich.edu              case TSDEV_CC_ITIR:
1677977Shsul@eecs.umich.edu                  pkt->set(itint);
1688013Sbinkertn@umich.edu                  break;
1698013Sbinkertn@umich.edu              default:
1708013Sbinkertn@umich.edu                  panic("default in cchip read reached, accessing 0x%x\n");
1718015Sbinkertn@umich.edu           } // uint64_t
1728013Sbinkertn@umich.edu
1738001Ssaidi@eecs.umich.edu      break;
1748015Sbinkertn@umich.edu      case sizeof(uint32_t):
1758015Sbinkertn@umich.edu      case sizeof(uint16_t):
1768015Sbinkertn@umich.edu      case sizeof(uint8_t):
1778015Sbinkertn@umich.edu      default:
1788015Sbinkertn@umich.edu        panic("invalid access size(?) for tsunami register!\n");
1798015Sbinkertn@umich.edu    }
1808015Sbinkertn@umich.edu    DPRINTF(Tsunami, "Tsunami CChip: read  regnum=%#x size=%d data=%lld\n",
1818015Sbinkertn@umich.edu            regnum, pkt->getSize(), pkt->get<uint64_t>());
1828015Sbinkertn@umich.edu
1838015Sbinkertn@umich.edu    pkt->makeAtomicResponse();
1848015Sbinkertn@umich.edu    return pioDelay;
1858015Sbinkertn@umich.edu}
1868015Sbinkertn@umich.edu
1878015Sbinkertn@umich.eduTick
1888015Sbinkertn@umich.eduTsunamiCChip::write(PacketPtr pkt)
1898015Sbinkertn@umich.edu{
1907977Shsul@eecs.umich.edu    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
1918013Sbinkertn@umich.edu    Addr daddr = pkt->getAddr() - pioAddr;
1928013Sbinkertn@umich.edu    Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
1938013Sbinkertn@umich.edu
1948013Sbinkertn@umich.edu
1957977Shsul@eecs.umich.edu    assert(pkt->getSize() == sizeof(uint64_t));
1968013Sbinkertn@umich.edu
1978013Sbinkertn@umich.edu    DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>());
1988013Sbinkertn@umich.edu
1998016Sbinkertn@umich.edu    bool supportedWrite = false;
2007977Shsul@eecs.umich.edu
2018016Sbinkertn@umich.edu
2028016Sbinkertn@umich.edu    if (daddr & TSDEV_CC_BDIMS)
2037977Shsul@eecs.umich.edu    {
2047977Shsul@eecs.umich.edu        int number = (daddr >> 4) & 0x3F;
2057977Shsul@eecs.umich.edu
2067977Shsul@eecs.umich.edu        uint64_t bitvector;
2077977Shsul@eecs.umich.edu        uint64_t olddim;
2088013Sbinkertn@umich.edu        uint64_t olddir;
2098013Sbinkertn@umich.edu
2108013Sbinkertn@umich.edu        olddim = dim[number];
2118013Sbinkertn@umich.edu        olddir = dir[number];
2128013Sbinkertn@umich.edu        dim[number] = pkt->get<uint64_t>();
2138013Sbinkertn@umich.edu        dir[number] = dim[number] & drir;
2148013Sbinkertn@umich.edu        for(int x = 0; x < Tsunami::Max_CPUs; x++)
2158013Sbinkertn@umich.edu        {
2168013Sbinkertn@umich.edu            bitvector = ULL(1) << x;
2178013Sbinkertn@umich.edu            // Figure out which bits have changed
2188013Sbinkertn@umich.edu            if ((dim[number] & bitvector) != (olddim & bitvector))
2198013Sbinkertn@umich.edu            {
2208013Sbinkertn@umich.edu                // The bit is now set and it wasn't before (set)
2218013Sbinkertn@umich.edu                if((dim[number] & bitvector) && (dir[number] & bitvector))
2228013Sbinkertn@umich.edu                {
2238013Sbinkertn@umich.edu                    tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
2248013Sbinkertn@umich.edu                    DPRINTF(Tsunami, "dim write resulting in posting dir"
2258013Sbinkertn@umich.edu                            " interrupt to cpu %d\n", number);
2268013Sbinkertn@umich.edu                }
2278013Sbinkertn@umich.edu                else if ((olddir & bitvector) &&
2288013Sbinkertn@umich.edu                        !(dir[number] & bitvector))
2298013Sbinkertn@umich.edu                {
2308013Sbinkertn@umich.edu                    // The bit was set and now its now clear and
2318013Sbinkertn@umich.edu                    // we were interrupting on that bit before
2328013Sbinkertn@umich.edu                    tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
2338013Sbinkertn@umich.edu                    DPRINTF(Tsunami, "dim write resulting in clear"
2348013Sbinkertn@umich.edu                            " dir interrupt to cpu %d\n", number);
2358013Sbinkertn@umich.edu
2368013Sbinkertn@umich.edu                }
2378013Sbinkertn@umich.edu
2388013Sbinkertn@umich.edu
2398013Sbinkertn@umich.edu            }
2408013Sbinkertn@umich.edu        }
2418013Sbinkertn@umich.edu    } else {
2428013Sbinkertn@umich.edu        switch(regnum) {
2438013Sbinkertn@umich.edu          case TSDEV_CC_CSR:
2448013Sbinkertn@umich.edu              panic("TSDEV_CC_CSR write\n");
2458013Sbinkertn@umich.edu          case TSDEV_CC_MTR:
2468013Sbinkertn@umich.edu              panic("TSDEV_CC_MTR write not implemented\n");
2477977Shsul@eecs.umich.edu          case TSDEV_CC_MISC:
2488013Sbinkertn@umich.edu            uint64_t ipreq;
2498013Sbinkertn@umich.edu            ipreq = (pkt->get<uint64_t>() >> 12) & 0xF;
2508013Sbinkertn@umich.edu            //If it is bit 12-15, this is an IPI post
2518013Sbinkertn@umich.edu            if (ipreq) {
2527977Shsul@eecs.umich.edu                reqIPI(ipreq);
2537977Shsul@eecs.umich.edu                supportedWrite = true;
2548013Sbinkertn@umich.edu            }
2558013Sbinkertn@umich.edu
2568013Sbinkertn@umich.edu            //If it is bit 8-11, this is an IPI clear
2578013Sbinkertn@umich.edu            uint64_t ipintr;
2587977Shsul@eecs.umich.edu            ipintr = (pkt->get<uint64_t>() >> 8) & 0xF;
2598013Sbinkertn@umich.edu            if (ipintr) {
2608013Sbinkertn@umich.edu                clearIPI(ipintr);
2618013Sbinkertn@umich.edu                supportedWrite = true;
2628013Sbinkertn@umich.edu            }
2638013Sbinkertn@umich.edu
2648013Sbinkertn@umich.edu            //If it is the 4-7th bit, clear the RTC interrupt
2658013Sbinkertn@umich.edu            uint64_t itintr;
2668013Sbinkertn@umich.edu              itintr = (pkt->get<uint64_t>() >> 4) & 0xF;
2678013Sbinkertn@umich.edu            if (itintr) {
2688013Sbinkertn@umich.edu                  clearITI(itintr);
2698013Sbinkertn@umich.edu                supportedWrite = true;
2708013Sbinkertn@umich.edu            }
2718013Sbinkertn@umich.edu
2728013Sbinkertn@umich.edu              // ignore NXMs
2738013Sbinkertn@umich.edu              if (pkt->get<uint64_t>() & 0x10000000)
2748013Sbinkertn@umich.edu                  supportedWrite = true;
2758013Sbinkertn@umich.edu
2768013Sbinkertn@umich.edu            if(!supportedWrite)
2778013Sbinkertn@umich.edu                  panic("TSDEV_CC_MISC write not implemented\n");
2788013Sbinkertn@umich.edu
2798013Sbinkertn@umich.edu            break;
2808013Sbinkertn@umich.edu            case TSDEV_CC_AAR0:
2818013Sbinkertn@umich.edu            case TSDEV_CC_AAR1:
2828013Sbinkertn@umich.edu            case TSDEV_CC_AAR2:
2838013Sbinkertn@umich.edu            case TSDEV_CC_AAR3:
2848013Sbinkertn@umich.edu                panic("TSDEV_CC_AARx write not implemeted\n");
2858013Sbinkertn@umich.edu            case TSDEV_CC_DIM0:
2867977Shsul@eecs.umich.edu            case TSDEV_CC_DIM1:
2877977Shsul@eecs.umich.edu            case TSDEV_CC_DIM2:
2887977Shsul@eecs.umich.edu            case TSDEV_CC_DIM3:
2898013Sbinkertn@umich.edu                int number;
2908013Sbinkertn@umich.edu                if(regnum == TSDEV_CC_DIM0)
2918013Sbinkertn@umich.edu                    number = 0;
2928013Sbinkertn@umich.edu                else if(regnum == TSDEV_CC_DIM1)
2938013Sbinkertn@umich.edu                    number = 1;
2947977Shsul@eecs.umich.edu                else if(regnum == TSDEV_CC_DIM2)
2957977Shsul@eecs.umich.edu                    number = 2;
2968013Sbinkertn@umich.edu                else
2978013Sbinkertn@umich.edu                    number = 3;
2988013Sbinkertn@umich.edu
2998013Sbinkertn@umich.edu                uint64_t bitvector;
3008013Sbinkertn@umich.edu                uint64_t olddim;
3017977Shsul@eecs.umich.edu                uint64_t olddir;
3027977Shsul@eecs.umich.edu
3037977Shsul@eecs.umich.edu                olddim = dim[number];
3047977Shsul@eecs.umich.edu                olddir = dir[number];
3057977Shsul@eecs.umich.edu                dim[number] = pkt->get<uint64_t>();
3067977Shsul@eecs.umich.edu                dir[number] = dim[number] & drir;
3078013Sbinkertn@umich.edu                for(int x = 0; x < 64; x++)
3088013Sbinkertn@umich.edu                {
3098013Sbinkertn@umich.edu                    bitvector = ULL(1) << x;
3108013Sbinkertn@umich.edu                    // Figure out which bits have changed
3118013Sbinkertn@umich.edu                    if ((dim[number] & bitvector) != (olddim & bitvector))
3128013Sbinkertn@umich.edu                    {
3138013Sbinkertn@umich.edu                        // The bit is now set and it wasn't before (set)
3148013Sbinkertn@umich.edu                        if((dim[number] & bitvector) && (dir[number] & bitvector))
3158013Sbinkertn@umich.edu                        {
3168013Sbinkertn@umich.edu                          tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
3178013Sbinkertn@umich.edu                          DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
3188013Sbinkertn@umich.edu                        }
3198013Sbinkertn@umich.edu                        else if ((olddir & bitvector) &&
3208013Sbinkertn@umich.edu                                !(dir[number] & bitvector))
3218013Sbinkertn@umich.edu                        {
3228013Sbinkertn@umich.edu                            // The bit was set and now its now clear and
3238013Sbinkertn@umich.edu                            // we were interrupting on that bit before
3247977Shsul@eecs.umich.edu                            tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
3257977Shsul@eecs.umich.edu                          DPRINTF(Tsunami, "dim write resulting in clear"
3267977Shsul@eecs.umich.edu                                    " dir interrupt to cpu %d\n",
3277977Shsul@eecs.umich.edu                                    x);
3287977Shsul@eecs.umich.edu
3297977Shsul@eecs.umich.edu                        }
3307977Shsul@eecs.umich.edu
3317977Shsul@eecs.umich.edu
3328013Sbinkertn@umich.edu                    }
3338013Sbinkertn@umich.edu                }
3348013Sbinkertn@umich.edu                break;
3358013Sbinkertn@umich.edu            case TSDEV_CC_DIR0:
3368013Sbinkertn@umich.edu            case TSDEV_CC_DIR1:
3377977Shsul@eecs.umich.edu            case TSDEV_CC_DIR2:
3387977Shsul@eecs.umich.edu            case TSDEV_CC_DIR3:
3397977Shsul@eecs.umich.edu                panic("TSDEV_CC_DIR write not implemented\n");
3408013Sbinkertn@umich.edu            case TSDEV_CC_DRIR:
3418013Sbinkertn@umich.edu                panic("TSDEV_CC_DRIR write not implemented\n");
3428013Sbinkertn@umich.edu            case TSDEV_CC_PRBEN:
3438013Sbinkertn@umich.edu                panic("TSDEV_CC_PRBEN write not implemented\n");
3448013Sbinkertn@umich.edu            case TSDEV_CC_IIC0:
3458013Sbinkertn@umich.edu            case TSDEV_CC_IIC1:
3468013Sbinkertn@umich.edu            case TSDEV_CC_IIC2:
3477977Shsul@eecs.umich.edu            case TSDEV_CC_IIC3:
3487977Shsul@eecs.umich.edu                panic("TSDEV_CC_IICx write not implemented\n");
3497977Shsul@eecs.umich.edu            case TSDEV_CC_MPR0:
3508013Sbinkertn@umich.edu            case TSDEV_CC_MPR1:
3518013Sbinkertn@umich.edu            case TSDEV_CC_MPR2:
3527977Shsul@eecs.umich.edu            case TSDEV_CC_MPR3:
3537977Shsul@eecs.umich.edu                panic("TSDEV_CC_MPRx write not implemented\n");
3548013Sbinkertn@umich.edu            case TSDEV_CC_IPIR:
3557977Shsul@eecs.umich.edu                clearIPI(pkt->get<uint64_t>());
3568013Sbinkertn@umich.edu                break;
3578013Sbinkertn@umich.edu            case TSDEV_CC_ITIR:
3588013Sbinkertn@umich.edu                clearITI(pkt->get<uint64_t>());
3598013Sbinkertn@umich.edu                break;
3607977Shsul@eecs.umich.edu            case TSDEV_CC_IPIQ:
3617977Shsul@eecs.umich.edu                reqIPI(pkt->get<uint64_t>());
3628013Sbinkertn@umich.edu                break;
3638013Sbinkertn@umich.edu            default:
3648013Sbinkertn@umich.edu              panic("default in cchip read reached, accessing 0x%x\n");
3657977Shsul@eecs.umich.edu        }  // swtich(regnum)
3667977Shsul@eecs.umich.edu    } // not BIG_TSUNAMI write
3678013Sbinkertn@umich.edu    pkt->makeAtomicResponse();
3688013Sbinkertn@umich.edu    return pioDelay;
3698013Sbinkertn@umich.edu}
3708013Sbinkertn@umich.edu
3718013Sbinkertn@umich.eduvoid
3728013Sbinkertn@umich.eduTsunamiCChip::clearIPI(uint64_t ipintr)
3737977Shsul@eecs.umich.edu{
3748013Sbinkertn@umich.edu    int numcpus = sys->threadContexts.size();
3758013Sbinkertn@umich.edu    assert(numcpus <= Tsunami::Max_CPUs);
3768013Sbinkertn@umich.edu
3777977Shsul@eecs.umich.edu    if (ipintr) {
3787977Shsul@eecs.umich.edu        for (int cpunum=0; cpunum < numcpus; cpunum++) {
3798013Sbinkertn@umich.edu            // Check each cpu bit
3807977Shsul@eecs.umich.edu            uint64_t cpumask = ULL(1) << cpunum;
3817977Shsul@eecs.umich.edu            if (ipintr & cpumask) {
3828013Sbinkertn@umich.edu                // Check if there is a pending ipi
3838013Sbinkertn@umich.edu                if (ipint & cpumask) {
3847977Shsul@eecs.umich.edu                    ipint &= ~cpumask;
3858016Sbinkertn@umich.edu                    tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0);
3868013Sbinkertn@umich.edu                    DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum);
3878013Sbinkertn@umich.edu                }
3887977Shsul@eecs.umich.edu                else
3897977Shsul@eecs.umich.edu                    warn("clear IPI for CPU=%d, but NO IPI\n", cpunum);
3908013Sbinkertn@umich.edu            }
3918013Sbinkertn@umich.edu        }
3928013Sbinkertn@umich.edu    }
3937977Shsul@eecs.umich.edu    else
3947978Sbinkertn@umich.edu        panic("Big IPI Clear, but not processors indicated\n");
3957978Sbinkertn@umich.edu}
3967977Shsul@eecs.umich.edu
3978013Sbinkertn@umich.eduvoid
3987977Shsul@eecs.umich.eduTsunamiCChip::clearITI(uint64_t itintr)
3998013Sbinkertn@umich.edu{
4008016Sbinkertn@umich.edu    int numcpus = sys->threadContexts.size();
4017977Shsul@eecs.umich.edu    assert(numcpus <= Tsunami::Max_CPUs);
4028013Sbinkertn@umich.edu
4038013Sbinkertn@umich.edu    if (itintr) {
4048013Sbinkertn@umich.edu        for (int i=0; i < numcpus; i++) {
4058013Sbinkertn@umich.edu            uint64_t cpumask = ULL(1) << i;
4068013Sbinkertn@umich.edu            if (itintr & cpumask & itint) {
4078013Sbinkertn@umich.edu                tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0);
4087977Shsul@eecs.umich.edu                itint &= ~cpumask;
4098013Sbinkertn@umich.edu                DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
4108013Sbinkertn@umich.edu            }
4118013Sbinkertn@umich.edu        }
4128013Sbinkertn@umich.edu    }
4138013Sbinkertn@umich.edu    else
4148013Sbinkertn@umich.edu        panic("Big ITI Clear, but not processors indicated\n");
4158013Sbinkertn@umich.edu}
4168013Sbinkertn@umich.edu
4178013Sbinkertn@umich.eduvoid
4188013Sbinkertn@umich.eduTsunamiCChip::reqIPI(uint64_t ipreq)
4198013Sbinkertn@umich.edu{
4207977Shsul@eecs.umich.edu    int numcpus = sys->threadContexts.size();
4218013Sbinkertn@umich.edu    assert(numcpus <= Tsunami::Max_CPUs);
4227977Shsul@eecs.umich.edu
4238013Sbinkertn@umich.edu    if (ipreq) {
4248013Sbinkertn@umich.edu        for (int cpunum=0; cpunum < numcpus; cpunum++) {
4258013Sbinkertn@umich.edu            // Check each cpu bit
4268013Sbinkertn@umich.edu            uint64_t cpumask = ULL(1) << cpunum;
4278013Sbinkertn@umich.edu            if (ipreq & cpumask) {
4288013Sbinkertn@umich.edu                // Check if there is already an ipi (bits 8:11)
4298013Sbinkertn@umich.edu                if (!(ipint & cpumask)) {
4308013Sbinkertn@umich.edu                    ipint  |= cpumask;
4318013Sbinkertn@umich.edu                    tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0);
4328013Sbinkertn@umich.edu                    DPRINTF(IPI, "send IPI cpu=%d\n", cpunum);
4338013Sbinkertn@umich.edu                }
4348013Sbinkertn@umich.edu                else
4358013Sbinkertn@umich.edu                    warn("post IPI for CPU=%d, but IPI already\n", cpunum);
4368013Sbinkertn@umich.edu            }
4378013Sbinkertn@umich.edu        }
4388013Sbinkertn@umich.edu    }
4397977Shsul@eecs.umich.edu    else
4408013Sbinkertn@umich.edu        panic("Big IPI Request, but not processors indicated\n");
4417977Shsul@eecs.umich.edu}
4428013Sbinkertn@umich.edu
4437977Shsul@eecs.umich.edu
4448016Sbinkertn@umich.eduvoid
4457977Shsul@eecs.umich.eduTsunamiCChip::postRTC()
4468016Sbinkertn@umich.edu{
4478013Sbinkertn@umich.edu    int size = sys->threadContexts.size();
4488013Sbinkertn@umich.edu    assert(size <= Tsunami::Max_CPUs);
4498013Sbinkertn@umich.edu
4508013Sbinkertn@umich.edu    for (int i = 0; i < size; i++) {
4518013Sbinkertn@umich.edu        uint64_t cpumask = ULL(1) << i;
4528013Sbinkertn@umich.edu       if (!(cpumask & itint)) {
4537977Shsul@eecs.umich.edu           itint |= cpumask;
4548013Sbinkertn@umich.edu           tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0);
4557977Shsul@eecs.umich.edu           DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i);
4568013Sbinkertn@umich.edu       }
4578013Sbinkertn@umich.edu    }
4588013Sbinkertn@umich.edu
4598013Sbinkertn@umich.edu}
4608013Sbinkertn@umich.edu
4618013Sbinkertn@umich.eduvoid
4627977Shsul@eecs.umich.eduTsunamiCChip::postDRIR(uint32_t interrupt)
4638013Sbinkertn@umich.edu{
4648013Sbinkertn@umich.edu    uint64_t bitvector = ULL(1) << interrupt;
4657977Shsul@eecs.umich.edu    uint64_t size = sys->threadContexts.size();
4668013Sbinkertn@umich.edu    assert(size <= Tsunami::Max_CPUs);
4678013Sbinkertn@umich.edu    drir |= bitvector;
4687977Shsul@eecs.umich.edu
4698013Sbinkertn@umich.edu    for(int i=0; i < size; i++) {
4708013Sbinkertn@umich.edu        dir[i] = dim[i] & drir;
4718013Sbinkertn@umich.edu       if (dim[i] & bitvector) {
4728013Sbinkertn@umich.edu              tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt);
4738018Smserrano@umich.edu              DPRINTF(Tsunami, "posting dir interrupt to cpu %d,"
4748013Sbinkertn@umich.edu                        "interrupt %d\n",i, interrupt);
4758013Sbinkertn@umich.edu       }
4767977Shsul@eecs.umich.edu    }
4777977Shsul@eecs.umich.edu}
4788013Sbinkertn@umich.edu
4798013Sbinkertn@umich.eduvoid
4808013Sbinkertn@umich.eduTsunamiCChip::clearDRIR(uint32_t interrupt)
4818013Sbinkertn@umich.edu{
4828013Sbinkertn@umich.edu    uint64_t bitvector = ULL(1) << interrupt;
4838013Sbinkertn@umich.edu    uint64_t size = sys->threadContexts.size();
4848013Sbinkertn@umich.edu    assert(size <= Tsunami::Max_CPUs);
4858013Sbinkertn@umich.edu
4868013Sbinkertn@umich.edu    if (drir & bitvector)
4878013Sbinkertn@umich.edu    {
4887977Shsul@eecs.umich.edu        drir &= ~bitvector;
4897977Shsul@eecs.umich.edu        for(int i=0; i < size; i++) {
4907977Shsul@eecs.umich.edu           if (dir[i] & bitvector) {
4917977Shsul@eecs.umich.edu               tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt);
4928013Sbinkertn@umich.edu               DPRINTF(Tsunami, "clearing dir interrupt to cpu %d,"
4938018Smserrano@umich.edu                    "interrupt %d\n",i, interrupt);
4948013Sbinkertn@umich.edu
4958018Smserrano@umich.edu           }
4968013Sbinkertn@umich.edu           dir[i] = dim[i] & drir;
4978013Sbinkertn@umich.edu        }
4988013Sbinkertn@umich.edu    }
4997977Shsul@eecs.umich.edu    else
5008013Sbinkertn@umich.edu        DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt);
5018013Sbinkertn@umich.edu}
5028013Sbinkertn@umich.edu
5038013Sbinkertn@umich.edu
5047977Shsul@eecs.umich.eduvoid
5058013Sbinkertn@umich.eduTsunamiCChip::serialize(std::ostream &os)
5068013Sbinkertn@umich.edu{
5078013Sbinkertn@umich.edu    SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
5088013Sbinkertn@umich.edu    SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
5097977Shsul@eecs.umich.edu    SERIALIZE_SCALAR(ipint);
5108013Sbinkertn@umich.edu    SERIALIZE_SCALAR(itint);
5118013Sbinkertn@umich.edu    SERIALIZE_SCALAR(drir);
5128013Sbinkertn@umich.edu}
5137977Shsul@eecs.umich.edu
5147977Shsul@eecs.umich.eduvoid
5158013Sbinkertn@umich.eduTsunamiCChip::unserialize(Checkpoint *cp, const std::string &section)
5168018Smserrano@umich.edu{
5178013Sbinkertn@umich.edu    UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
5187977Shsul@eecs.umich.edu    UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
5198013Sbinkertn@umich.edu    UNSERIALIZE_SCALAR(ipint);
5208013Sbinkertn@umich.edu    UNSERIALIZE_SCALAR(itint);
5218013Sbinkertn@umich.edu    UNSERIALIZE_SCALAR(drir);
5228013Sbinkertn@umich.edu}
5238013Sbinkertn@umich.edu
5248013Sbinkertn@umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
5258013Sbinkertn@umich.edu
5268013Sbinkertn@umich.edu    Param<Addr> pio_addr;
5278013Sbinkertn@umich.edu    Param<Tick> pio_latency;
5288018Smserrano@umich.edu    SimObjectParam<Platform *> platform;
5298018Smserrano@umich.edu    SimObjectParam<System *> system;
5308018Smserrano@umich.edu    SimObjectParam<Tsunami *> tsunami;
5318018Smserrano@umich.edu
5328018Smserrano@umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
5338018Smserrano@umich.edu
5348018Smserrano@umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
5358018Smserrano@umich.edu
5367977Shsul@eecs.umich.edu    INIT_PARAM(pio_addr, "Device Address"),
5378013Sbinkertn@umich.edu    INIT_PARAM(pio_latency, "Programmed IO latency"),
5388013Sbinkertn@umich.edu    INIT_PARAM(platform, "platform"),
5398013Sbinkertn@umich.edu    INIT_PARAM(system, "system object"),
5408018Smserrano@umich.edu    INIT_PARAM(tsunami, "Tsunami")
5418013Sbinkertn@umich.edu
5428013Sbinkertn@umich.eduEND_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
5438013Sbinkertn@umich.edu
5448013Sbinkertn@umich.eduCREATE_SIM_OBJECT(TsunamiCChip)
5458013Sbinkertn@umich.edu{
5468013Sbinkertn@umich.edu    TsunamiCChip::Params *p = new TsunamiCChip::Params;
5478013Sbinkertn@umich.edu    p->name = getInstanceName();
5488013Sbinkertn@umich.edu    p->pio_addr = pio_addr;
5498013Sbinkertn@umich.edu    p->pio_delay = pio_latency;
5508013Sbinkertn@umich.edu    p->platform = platform;
5517977Shsul@eecs.umich.edu    p->system = system;
5528018Smserrano@umich.edu    p->tsunami = tsunami;
5537977Shsul@eecs.umich.edu    return new TsunamiCChip(p);
5548013Sbinkertn@umich.edu}
5557977Shsul@eecs.umich.edu
5568013Sbinkertn@umich.eduREGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)
5578013Sbinkertn@umich.edu