1892SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
3892SN/A * All rights reserved.
4892SN/A *
5892SN/A * Redistribution and use in source and binary forms, with or without
6892SN/A * modification, are permitted provided that the following conditions are
7892SN/A * met: redistributions of source code must retain the above copyright
8892SN/A * notice, this list of conditions and the following disclaimer;
9892SN/A * redistributions in binary form must reproduce the above copyright
10892SN/A * notice, this list of conditions and the following disclaimer in the
11892SN/A * documentation and/or other materials provided with the distribution;
12892SN/A * neither the name of the copyright holders nor the names of its
13892SN/A * contributors may be used to endorse or promote products derived from
14892SN/A * this software without specific prior written permission.
15892SN/A *
16892SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17892SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18892SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19892SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20892SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21892SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22892SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23892SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24892SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25892SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26892SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Ali Saidi
292665SN/A *          Ron Dreslinski
30892SN/A */
31767SN/A
321730SN/A/** @file
33798SN/A * Emulation of the Tsunami CChip CSRs
34767SN/A */
35767SN/A
3611793Sbrandon.potter@amd.com#include "dev/alpha/tsunami_cchip.hh"
3711793Sbrandon.potter@amd.com
38767SN/A#include <deque>
39767SN/A#include <string>
40767SN/A#include <vector>
41767SN/A
422432SN/A#include "arch/alpha/ev5.hh"
43767SN/A#include "base/trace.hh"
446658Snate@binkert.org#include "config/the_isa.hh"
453348SN/A#include "cpu/intr_control.hh"
463348SN/A#include "cpu/thread_context.hh"
478232Snate@binkert.org#include "debug/IPI.hh"
488232Snate@binkert.org#include "debug/Tsunami.hh"
493540Sgblack@eecs.umich.edu#include "dev/alpha/tsunami.hh"
503540Sgblack@eecs.umich.edu#include "dev/alpha/tsunamireg.h"
513348SN/A#include "mem/packet.hh"
523348SN/A#include "mem/packet_access.hh"
532523SN/A#include "mem/port.hh"
544762Snate@binkert.org#include "params/TsunamiCChip.hh"
55767SN/A#include "sim/system.hh"
56767SN/A
572107SN/A//Should this be AlphaISA?
582107SN/Ausing namespace TheISA;
59767SN/A
604762Snate@binkert.orgTsunamiCChip::TsunamiCChip(const Params *p)
619808Sstever@gmail.com    : BasicPioDevice(p, 0x10000000), tsunami(p->tsunami)
62767SN/A{
63767SN/A    drir = 0;
641290SN/A    ipint = 0;
651290SN/A    itint = 0;
661290SN/A
671290SN/A    for (int x = 0; x < Tsunami::Max_CPUs; x++)
681290SN/A    {
691290SN/A        dim[x] = 0;
701290SN/A        dir[x] = 0;
711290SN/A    }
72775SN/A
73775SN/A    //Put back pointer in tsunami
74775SN/A    tsunami->cchip = this;
75767SN/A}
76767SN/A
772523SN/ATick
783349SN/ATsunamiCChip::read(PacketPtr pkt)
79767SN/A{
802641SN/A    DPRINTF(Tsunami, "read  va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
81767SN/A
822641SN/A    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
831290SN/A
842641SN/A    Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
852641SN/A    Addr daddr = (pkt->getAddr() - pioAddr);
86767SN/A
872641SN/A    switch (pkt->getSize()) {
88767SN/A
89767SN/A      case sizeof(uint64_t):
9013232Sgabeblack@google.com          pkt->setLE<uint64_t>(0);
913875Sbinkertn@umich.edu
921290SN/A          if (daddr & TSDEV_CC_BDIMS)
931290SN/A          {
9413232Sgabeblack@google.com              pkt->setLE(dim[(daddr >> 4) & 0x3F]);
952523SN/A              break;
961290SN/A          }
971290SN/A
981290SN/A          if (daddr & TSDEV_CC_BDIRS)
991290SN/A          {
10013232Sgabeblack@google.com              pkt->setLE(dir[(daddr >> 4) & 0x3F]);
1012523SN/A              break;
1021290SN/A          }
1031290SN/A
1041290SN/A          switch(regnum) {
105767SN/A              case TSDEV_CC_CSR:
10613232Sgabeblack@google.com                  pkt->setLE(0x0);
1072523SN/A                  break;
108767SN/A              case TSDEV_CC_MTR:
109767SN/A                  panic("TSDEV_CC_MTR not implemeted\n");
1102523SN/A                   break;
111767SN/A              case TSDEV_CC_MISC:
11213232Sgabeblack@google.com                  pkt->setLE(((ipint << 8) & 0xF) | ((itint << 4) & 0xF) |
1135714Shsul@eecs.umich.edu                                     (pkt->req->contextId() & 0x3));
1145714Shsul@eecs.umich.edu                  // currently, FS cannot handle MT so contextId and
1155714Shsul@eecs.umich.edu                  // cpuId are effectively the same, don't know if it will
1165714Shsul@eecs.umich.edu                  // matter if FS becomes MT enabled.  I suspect no because
1175714Shsul@eecs.umich.edu                  // we are currently able to boot up to 64 procs anyway
1185714Shsul@eecs.umich.edu                  // which would render the CPUID of this register useless
1195714Shsul@eecs.umich.edu                  // anyway
1202523SN/A                  break;
121767SN/A              case TSDEV_CC_AAR0:
122767SN/A              case TSDEV_CC_AAR1:
123767SN/A              case TSDEV_CC_AAR2:
124767SN/A              case TSDEV_CC_AAR3:
12513232Sgabeblack@google.com                  pkt->setLE(0);
1262523SN/A                  break;
127767SN/A              case TSDEV_CC_DIM0:
12813232Sgabeblack@google.com                  pkt->setLE(dim[0]);
1292523SN/A                  break;
130767SN/A              case TSDEV_CC_DIM1:
13113232Sgabeblack@google.com                  pkt->setLE(dim[1]);
1322523SN/A                  break;
133767SN/A              case TSDEV_CC_DIM2:
13413232Sgabeblack@google.com                  pkt->setLE(dim[2]);
1352523SN/A                  break;
136767SN/A              case TSDEV_CC_DIM3:
13713232Sgabeblack@google.com                  pkt->setLE(dim[3]);
1382523SN/A                  break;
139767SN/A              case TSDEV_CC_DIR0:
14013232Sgabeblack@google.com                  pkt->setLE(dir[0]);
1412523SN/A                  break;
142767SN/A              case TSDEV_CC_DIR1:
14313232Sgabeblack@google.com                  pkt->setLE(dir[1]);
1442523SN/A                  break;
145767SN/A              case TSDEV_CC_DIR2:
14613232Sgabeblack@google.com                  pkt->setLE(dir[2]);
1472523SN/A                  break;
148767SN/A              case TSDEV_CC_DIR3:
14913232Sgabeblack@google.com                  pkt->setLE(dir[3]);
1502523SN/A                  break;
151767SN/A              case TSDEV_CC_DRIR:
15213232Sgabeblack@google.com                  pkt->setLE(drir);
1532523SN/A                  break;
154767SN/A              case TSDEV_CC_PRBEN:
155767SN/A                  panic("TSDEV_CC_PRBEN not implemented\n");
1562523SN/A                  break;
157767SN/A              case TSDEV_CC_IIC0:
158767SN/A              case TSDEV_CC_IIC1:
159767SN/A              case TSDEV_CC_IIC2:
160767SN/A              case TSDEV_CC_IIC3:
161767SN/A                  panic("TSDEV_CC_IICx not implemented\n");
1622523SN/A                  break;
163767SN/A              case TSDEV_CC_MPR0:
164767SN/A              case TSDEV_CC_MPR1:
165767SN/A              case TSDEV_CC_MPR2:
166767SN/A              case TSDEV_CC_MPR3:
167767SN/A                  panic("TSDEV_CC_MPRx not implemented\n");
1682523SN/A                  break;
1691290SN/A              case TSDEV_CC_IPIR:
17013232Sgabeblack@google.com                  pkt->setLE(ipint);
1712523SN/A                  break;
1721290SN/A              case TSDEV_CC_ITIR:
17313232Sgabeblack@google.com                  pkt->setLE(itint);
1742523SN/A                  break;
175768SN/A              default:
176768SN/A                  panic("default in cchip read reached, accessing 0x%x\n");
177767SN/A           } // uint64_t
178767SN/A
179767SN/A      break;
180767SN/A      case sizeof(uint32_t):
181767SN/A      case sizeof(uint16_t):
182767SN/A      case sizeof(uint8_t):
183767SN/A      default:
184768SN/A        panic("invalid access size(?) for tsunami register!\n");
185767SN/A    }
1862549SN/A    DPRINTF(Tsunami, "Tsunami CChip: read  regnum=%#x size=%d data=%lld\n",
18713232Sgabeblack@google.com            regnum, pkt->getSize(), pkt->getLE<uint64_t>());
188767SN/A
1894870Sstever@eecs.umich.edu    pkt->makeAtomicResponse();
1902523SN/A    return pioDelay;
191767SN/A}
192767SN/A
1932523SN/ATick
1943349SN/ATsunamiCChip::write(PacketPtr pkt)
195767SN/A{
1962641SN/A    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
1972641SN/A    Addr daddr = pkt->getAddr() - pioAddr;
1982641SN/A    Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
1992539SN/A
2002523SN/A
2012641SN/A    assert(pkt->getSize() == sizeof(uint64_t));
2022523SN/A
20313232Sgabeblack@google.com    DPRINTF(Tsunami, "write - addr=%#x value=%#x\n",
20413232Sgabeblack@google.com            pkt->getAddr(), pkt->getLE<uint64_t>());
205767SN/A
206830SN/A    bool supportedWrite = false;
207830SN/A
208767SN/A
2092539SN/A    if (daddr & TSDEV_CC_BDIMS)
2102539SN/A    {
2112539SN/A        int number = (daddr >> 4) & 0x3F;
2121290SN/A
2132539SN/A        uint64_t bitvector;
2142539SN/A        uint64_t olddim;
2152539SN/A        uint64_t olddir;
2161290SN/A
2172539SN/A        olddim = dim[number];
2182539SN/A        olddir = dir[number];
21913232Sgabeblack@google.com        dim[number] = pkt->getLE<uint64_t>();
2202539SN/A        dir[number] = dim[number] & drir;
22111321Ssteve.reinhardt@amd.com        for (int x = 0; x < Tsunami::Max_CPUs; x++)
2222539SN/A        {
2232539SN/A            bitvector = ULL(1) << x;
2242539SN/A            // Figure out which bits have changed
2252539SN/A            if ((dim[number] & bitvector) != (olddim & bitvector))
2262539SN/A            {
2272539SN/A                // The bit is now set and it wasn't before (set)
22811321Ssteve.reinhardt@amd.com                if ((dim[number] & bitvector) && (dir[number] & bitvector))
2292539SN/A                {
2302539SN/A                    tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
2312539SN/A                    DPRINTF(Tsunami, "dim write resulting in posting dir"
2322539SN/A                            " interrupt to cpu %d\n", number);
2332539SN/A                }
2342539SN/A                else if ((olddir & bitvector) &&
2352539SN/A                        !(dir[number] & bitvector))
2362539SN/A                {
2372539SN/A                    // The bit was set and now its now clear and
2382539SN/A                    // we were interrupting on that bit before
2392539SN/A                    tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
2402539SN/A                    DPRINTF(Tsunami, "dim write resulting in clear"
2412539SN/A                            " dir interrupt to cpu %d\n", number);
2421290SN/A
2431074SN/A                }
2441074SN/A
2452539SN/A
2462539SN/A            }
2472539SN/A        }
2482539SN/A    } else {
2492539SN/A        switch(regnum) {
2502539SN/A          case TSDEV_CC_CSR:
2512539SN/A              panic("TSDEV_CC_CSR write\n");
2522539SN/A          case TSDEV_CC_MTR:
2532539SN/A              panic("TSDEV_CC_MTR write not implemented\n");
2542539SN/A          case TSDEV_CC_MISC:
2552539SN/A            uint64_t ipreq;
25613232Sgabeblack@google.com            ipreq = (pkt->getLE<uint64_t>() >> 12) & 0xF;
2572539SN/A            //If it is bit 12-15, this is an IPI post
2582539SN/A            if (ipreq) {
2592539SN/A                reqIPI(ipreq);
2602539SN/A                supportedWrite = true;
2612539SN/A            }
2622539SN/A
2632539SN/A            //If it is bit 8-11, this is an IPI clear
2642539SN/A            uint64_t ipintr;
26513232Sgabeblack@google.com            ipintr = (pkt->getLE<uint64_t>() >> 8) & 0xF;
2662539SN/A            if (ipintr) {
2672539SN/A                clearIPI(ipintr);
2682539SN/A                supportedWrite = true;
2692539SN/A            }
2702539SN/A
2712539SN/A            //If it is the 4-7th bit, clear the RTC interrupt
2722539SN/A            uint64_t itintr;
27313232Sgabeblack@google.com              itintr = (pkt->getLE<uint64_t>() >> 4) & 0xF;
2742539SN/A            if (itintr) {
2752539SN/A                  clearITI(itintr);
2762539SN/A                supportedWrite = true;
2772539SN/A            }
2782539SN/A
2792539SN/A              // ignore NXMs
28013232Sgabeblack@google.com              if (pkt->getLE<uint64_t>() & 0x10000000)
2812539SN/A                  supportedWrite = true;
2822539SN/A
28311321Ssteve.reinhardt@amd.com            if (!supportedWrite)
2842539SN/A                  panic("TSDEV_CC_MISC write not implemented\n");
2852539SN/A
2862549SN/A            break;
2872539SN/A            case TSDEV_CC_AAR0:
2882539SN/A            case TSDEV_CC_AAR1:
2892539SN/A            case TSDEV_CC_AAR2:
2902539SN/A            case TSDEV_CC_AAR3:
2912539SN/A                panic("TSDEV_CC_AARx write not implemeted\n");
2922539SN/A            case TSDEV_CC_DIM0:
2932539SN/A            case TSDEV_CC_DIM1:
2942539SN/A            case TSDEV_CC_DIM2:
2952539SN/A            case TSDEV_CC_DIM3:
2962539SN/A                int number;
29711321Ssteve.reinhardt@amd.com                if (regnum == TSDEV_CC_DIM0)
2982539SN/A                    number = 0;
29911321Ssteve.reinhardt@amd.com                else if (regnum == TSDEV_CC_DIM1)
3002539SN/A                    number = 1;
30111321Ssteve.reinhardt@amd.com                else if (regnum == TSDEV_CC_DIM2)
3022539SN/A                    number = 2;
3032539SN/A                else
3042539SN/A                    number = 3;
3052539SN/A
3062539SN/A                uint64_t bitvector;
3072539SN/A                uint64_t olddim;
3082539SN/A                uint64_t olddir;
3092539SN/A
3102539SN/A                olddim = dim[number];
3112539SN/A                olddir = dir[number];
31213232Sgabeblack@google.com                dim[number] = pkt->getLE<uint64_t>();
3132539SN/A                dir[number] = dim[number] & drir;
31411321Ssteve.reinhardt@amd.com                for (int x = 0; x < 64; x++)
3152539SN/A                {
3162539SN/A                    bitvector = ULL(1) << x;
3172539SN/A                    // Figure out which bits have changed
3182539SN/A                    if ((dim[number] & bitvector) != (olddim & bitvector))
3192539SN/A                    {
3202539SN/A                        // The bit is now set and it wasn't before (set)
32111321Ssteve.reinhardt@amd.com                        if ((dim[number] & bitvector) && (dir[number] & bitvector))
3222539SN/A                        {
3232539SN/A                          tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);
3242539SN/A                          DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
3252539SN/A                        }
3262539SN/A                        else if ((olddir & bitvector) &&
3272539SN/A                                !(dir[number] & bitvector))
3282539SN/A                        {
3292539SN/A                            // The bit was set and now its now clear and
3302539SN/A                            // we were interrupting on that bit before
3312539SN/A                            tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);
3322539SN/A                          DPRINTF(Tsunami, "dim write resulting in clear"
3332539SN/A                                    " dir interrupt to cpu %d\n",
3342539SN/A                                    x);
3352539SN/A
3362539SN/A                        }
3372539SN/A
3382539SN/A
3392539SN/A                    }
3401074SN/A                }
3412539SN/A                break;
3422539SN/A            case TSDEV_CC_DIR0:
3432539SN/A            case TSDEV_CC_DIR1:
3442539SN/A            case TSDEV_CC_DIR2:
3452539SN/A            case TSDEV_CC_DIR3:
3462539SN/A                panic("TSDEV_CC_DIR write not implemented\n");
3472539SN/A            case TSDEV_CC_DRIR:
3482539SN/A                panic("TSDEV_CC_DRIR write not implemented\n");
3492539SN/A            case TSDEV_CC_PRBEN:
3502539SN/A                panic("TSDEV_CC_PRBEN write not implemented\n");
3512539SN/A            case TSDEV_CC_IIC0:
3522539SN/A            case TSDEV_CC_IIC1:
3532539SN/A            case TSDEV_CC_IIC2:
3542539SN/A            case TSDEV_CC_IIC3:
3552539SN/A                panic("TSDEV_CC_IICx write not implemented\n");
3562539SN/A            case TSDEV_CC_MPR0:
3572539SN/A            case TSDEV_CC_MPR1:
3582539SN/A            case TSDEV_CC_MPR2:
3592539SN/A            case TSDEV_CC_MPR3:
3602539SN/A                panic("TSDEV_CC_MPRx write not implemented\n");
3612539SN/A            case TSDEV_CC_IPIR:
36213232Sgabeblack@google.com                clearIPI(pkt->getLE<uint64_t>());
3632539SN/A                break;
3642539SN/A            case TSDEV_CC_ITIR:
36513232Sgabeblack@google.com                clearITI(pkt->getLE<uint64_t>());
3662539SN/A                break;
3672539SN/A            case TSDEV_CC_IPIQ:
36813232Sgabeblack@google.com                reqIPI(pkt->getLE<uint64_t>());
3692539SN/A                break;
3702539SN/A            default:
3712539SN/A              panic("default in cchip read reached, accessing 0x%x\n");
3722539SN/A        }  // swtich(regnum)
3732539SN/A    } // not BIG_TSUNAMI write
3744870Sstever@eecs.umich.edu    pkt->makeAtomicResponse();
3752539SN/A    return pioDelay;
376767SN/A}
377767SN/A
378767SN/Avoid
3791290SN/ATsunamiCChip::clearIPI(uint64_t ipintr)
3801290SN/A{
3814103Ssaidi@eecs.umich.edu    int numcpus = sys->threadContexts.size();
3821290SN/A    assert(numcpus <= Tsunami::Max_CPUs);
3831290SN/A
3841290SN/A    if (ipintr) {
3851290SN/A        for (int cpunum=0; cpunum < numcpus; cpunum++) {
3861290SN/A            // Check each cpu bit
3871290SN/A            uint64_t cpumask = ULL(1) << cpunum;
3881290SN/A            if (ipintr & cpumask) {
3891290SN/A                // Check if there is a pending ipi
3901290SN/A                if (ipint & cpumask) {
3911290SN/A                    ipint &= ~cpumask;
3921290SN/A                    tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0);
3931290SN/A                    DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum);
3941290SN/A                }
3951290SN/A                else
3961290SN/A                    warn("clear IPI for CPU=%d, but NO IPI\n", cpunum);
3971290SN/A            }
3981290SN/A        }
3991290SN/A    }
4001290SN/A    else
4011290SN/A        panic("Big IPI Clear, but not processors indicated\n");
4021290SN/A}
4031290SN/A
4041290SN/Avoid
4051290SN/ATsunamiCChip::clearITI(uint64_t itintr)
4061290SN/A{
4074103Ssaidi@eecs.umich.edu    int numcpus = sys->threadContexts.size();
4081290SN/A    assert(numcpus <= Tsunami::Max_CPUs);
4091290SN/A
4101290SN/A    if (itintr) {
4111290SN/A        for (int i=0; i < numcpus; i++) {
4121290SN/A            uint64_t cpumask = ULL(1) << i;
4131290SN/A            if (itintr & cpumask & itint) {
4141290SN/A                tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0);
4151290SN/A                itint &= ~cpumask;
4161290SN/A                DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
4171290SN/A            }
4181290SN/A        }
4191290SN/A    }
4201290SN/A    else
4211290SN/A        panic("Big ITI Clear, but not processors indicated\n");
4221290SN/A}
4231290SN/A
4241290SN/Avoid
4251290SN/ATsunamiCChip::reqIPI(uint64_t ipreq)
4261290SN/A{
4274103Ssaidi@eecs.umich.edu    int numcpus = sys->threadContexts.size();
4281290SN/A    assert(numcpus <= Tsunami::Max_CPUs);
4291290SN/A
4301290SN/A    if (ipreq) {
4311290SN/A        for (int cpunum=0; cpunum < numcpus; cpunum++) {
4321290SN/A            // Check each cpu bit
4331290SN/A            uint64_t cpumask = ULL(1) << cpunum;
4341290SN/A            if (ipreq & cpumask) {
4351290SN/A                // Check if there is already an ipi (bits 8:11)
4361290SN/A                if (!(ipint & cpumask)) {
4371290SN/A                    ipint  |= cpumask;
4381290SN/A                    tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0);
4391290SN/A                    DPRINTF(IPI, "send IPI cpu=%d\n", cpunum);
4401290SN/A                }
4411290SN/A                else
4421290SN/A                    warn("post IPI for CPU=%d, but IPI already\n", cpunum);
4431290SN/A            }
4441290SN/A        }
4451290SN/A    }
4461290SN/A    else
4471290SN/A        panic("Big IPI Request, but not processors indicated\n");
4481290SN/A}
4491290SN/A
4501290SN/A
4511290SN/Avoid
452831SN/ATsunamiCChip::postRTC()
453831SN/A{
4544103Ssaidi@eecs.umich.edu    int size = sys->threadContexts.size();
4551290SN/A    assert(size <= Tsunami::Max_CPUs);
456831SN/A
457831SN/A    for (int i = 0; i < size; i++) {
4581290SN/A        uint64_t cpumask = ULL(1) << i;
4592539SN/A       if (!(cpumask & itint)) {
4602539SN/A           itint |= cpumask;
4612539SN/A           tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0);
4624739Sstever@eecs.umich.edu           DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d\n", i);
4632539SN/A       }
464831SN/A    }
465831SN/A
466831SN/A}
467831SN/A
468831SN/Avoid
469817SN/ATsunamiCChip::postDRIR(uint32_t interrupt)
470777SN/A{
4711290SN/A    uint64_t bitvector = ULL(1) << interrupt;
4724103Ssaidi@eecs.umich.edu    uint64_t size = sys->threadContexts.size();
4731290SN/A    assert(size <= Tsunami::Max_CPUs);
474777SN/A    drir |= bitvector;
4751290SN/A
47611321Ssteve.reinhardt@amd.com    for (int i=0; i < size; i++) {
477817SN/A        dir[i] = dim[i] & drir;
4782539SN/A       if (dim[i] & bitvector) {
4792539SN/A              tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt);
4802539SN/A              DPRINTF(Tsunami, "posting dir interrupt to cpu %d,"
481817SN/A                        "interrupt %d\n",i, interrupt);
4822539SN/A       }
483777SN/A    }
484777SN/A}
485777SN/A
486777SN/Avoid
487817SN/ATsunamiCChip::clearDRIR(uint32_t interrupt)
488777SN/A{
4891290SN/A    uint64_t bitvector = ULL(1) << interrupt;
4904103Ssaidi@eecs.umich.edu    uint64_t size = sys->threadContexts.size();
4911290SN/A    assert(size <= Tsunami::Max_CPUs);
4921290SN/A
493817SN/A    if (drir & bitvector)
494817SN/A    {
495817SN/A        drir &= ~bitvector;
49611321Ssteve.reinhardt@amd.com        for (int i=0; i < size; i++) {
4972539SN/A           if (dir[i] & bitvector) {
4982539SN/A               tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt);
4992539SN/A               DPRINTF(Tsunami, "clearing dir interrupt to cpu %d,"
500817SN/A                    "interrupt %d\n",i, interrupt);
501777SN/A
5022539SN/A           }
5032539SN/A           dir[i] = dim[i] & drir;
504777SN/A        }
505777SN/A    }
506817SN/A    else
507817SN/A        DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt);
508777SN/A}
509777SN/A
510909SN/A
511777SN/Avoid
51210905Sandreas.sandberg@arm.comTsunamiCChip::serialize(CheckpointOut &cp) const
513767SN/A{
514811SN/A    SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
515811SN/A    SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
5161290SN/A    SERIALIZE_SCALAR(ipint);
5171290SN/A    SERIALIZE_SCALAR(itint);
518811SN/A    SERIALIZE_SCALAR(drir);
519767SN/A}
520767SN/A
521767SN/Avoid
52210905Sandreas.sandberg@arm.comTsunamiCChip::unserialize(CheckpointIn &cp)
523767SN/A{
524811SN/A    UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs);
525811SN/A    UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs);
5261290SN/A    UNSERIALIZE_SCALAR(ipint);
5271290SN/A    UNSERIALIZE_SCALAR(itint);
528811SN/A    UNSERIALIZE_SCALAR(drir);
529767SN/A}
530767SN/A
5314762Snate@binkert.orgTsunamiCChip *
5324762Snate@binkert.orgTsunamiCChipParams::create()
533767SN/A{
5344762Snate@binkert.org    return new TsunamiCChip(this);
535767SN/A}
536