tsunami_cchip.cc revision 2107
12SN/A/* 22190SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 292SN/A/** @file 302SN/A * Emulation of the Tsunami CChip CSRs 312680Sktlim@umich.edu */ 322680Sktlim@umich.edu 332SN/A#include <deque> 342972Sgblack@eecs.umich.edu#include <string> 353453Sgblack@eecs.umich.edu#include <vector> 366216Snate@binkert.org 371858SN/A#include "base/trace.hh" 382423SN/A#include "dev/tsunami_cchip.hh" 396216Snate@binkert.org#include "dev/tsunamireg.h" 402190SN/A#include "dev/tsunami.hh" 41217SN/A#include "mem/bus/bus.hh" 422SN/A#include "mem/bus/pio_interface.hh" 432190SN/A#include "mem/bus/pio_interface_impl.hh" 442190SN/A#include "mem/functional/memory_control.hh" 453453Sgblack@eecs.umich.edu#include "cpu/intr_control.hh" 463453Sgblack@eecs.umich.edu#include "sim/builder.hh" 476022Sgblack@eecs.umich.edu#include "sim/system.hh" 483453Sgblack@eecs.umich.edu 492190SN/Ausing namespace std; 502313SN/A//Should this be AlphaISA? 512235SN/Ausing namespace TheISA; 522423SN/A 532521SN/ATsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, 542521SN/A MemoryController *mmu, HierParams *hier, 552190SN/A Bus* pio_bus, Tick pio_latency) 562190SN/A : PioDevice(name, t), addr(a), tsunami(t) 573548Sgblack@eecs.umich.edu{ 583548Sgblack@eecs.umich.edu mmu->add_child(this, RangeSize(addr, size)); 593548Sgblack@eecs.umich.edu 603548Sgblack@eecs.umich.edu if (pio_bus) { 612330SN/A pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, 622SN/A &TsunamiCChip::cacheAccess); 632680Sktlim@umich.edu pioInterface->addAddrRange(RangeSize(addr, size)); 642680Sktlim@umich.edu pioLatency = pio_latency * pio_bus->clockRate; 652680Sktlim@umich.edu } 662680Sktlim@umich.edu 672680Sktlim@umich.edu drir = 0; 682680Sktlim@umich.edu ipint = 0; 692680Sktlim@umich.edu itint = 0; 702680Sktlim@umich.edu 712680Sktlim@umich.edu for (int x = 0; x < Tsunami::Max_CPUs; x++) 722680Sktlim@umich.edu { 732680Sktlim@umich.edu dim[x] = 0; 742682Sktlim@umich.edu dir[x] = 0; 752680Sktlim@umich.edu } 762680Sktlim@umich.edu 772680Sktlim@umich.edu //Put back pointer in tsunami 782680Sktlim@umich.edu tsunami->cchip = this; 792680Sktlim@umich.edu} 802SN/A 812107SN/AFault * 822107SN/ATsunamiCChip::read(MemReqPtr &req, uint8_t *data) 832107SN/A{ 842190SN/A DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); 852455SN/A 862455SN/A Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 872107SN/A Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); 882159SN/A 892SN/A ExecContext *xc = req->xc; 906029Ssteve.reinhardt@amd.com 91246SN/A switch (req->size) { 92246SN/A 93246SN/A case sizeof(uint64_t): 94246SN/A if (daddr & TSDEV_CC_BDIMS) 95246SN/A { 96246SN/A *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; 97246SN/A return NoFault; 982190SN/A } 99246SN/A 100246SN/A if (daddr & TSDEV_CC_BDIRS) 101246SN/A { 102246SN/A *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; 103246SN/A return NoFault; 104246SN/A } 105246SN/A 1062SN/A switch(regnum) { 1072680Sktlim@umich.edu case TSDEV_CC_CSR: 1082423SN/A *(uint64_t*)data = 0x0; 1092190SN/A return NoFault; 110180SN/A case TSDEV_CC_MTR: 1115712Shsul@eecs.umich.edu panic("TSDEV_CC_MTR not implemeted\n"); 1122190SN/A return NoFault; 1135715Shsul@eecs.umich.edu case TSDEV_CC_MISC: 1145715Shsul@eecs.umich.edu *(uint64_t*)data = (ipint << 8) & 0xF | 1155715Shsul@eecs.umich.edu (itint << 4) & 0xF | 1165714Shsul@eecs.umich.edu (xc->cpu_id & 0x3); 1175714Shsul@eecs.umich.edu return NoFault; 1185714Shsul@eecs.umich.edu case TSDEV_CC_AAR0: 1195714Shsul@eecs.umich.edu case TSDEV_CC_AAR1: 1205714Shsul@eecs.umich.edu case TSDEV_CC_AAR2: 1216022Sgblack@eecs.umich.edu case TSDEV_CC_AAR3: 1222190SN/A *(uint64_t*)data = 0; 1236022Sgblack@eecs.umich.edu return NoFault; 1242521SN/A case TSDEV_CC_DIM0: 1254997Sgblack@eecs.umich.edu *(uint64_t*)data = dim[0]; 1264997Sgblack@eecs.umich.edu return NoFault; 1275803Snate@binkert.org case TSDEV_CC_DIM1: 1283548Sgblack@eecs.umich.edu *(uint64_t*)data = dim[1]; 1292654SN/A return NoFault; 1302521SN/A case TSDEV_CC_DIM2: 1312521SN/A *(uint64_t*)data = dim[2]; 1325499Ssaidi@eecs.umich.edu return NoFault; 1333673Srdreslin@umich.edu case TSDEV_CC_DIM3: 1345497Ssaidi@eecs.umich.edu *(uint64_t*)data = dim[3]; 1352190SN/A return NoFault; 1362518SN/A case TSDEV_CC_DIR0: 1372518SN/A *(uint64_t*)data = dir[0]; 1382190SN/A return NoFault; 1392190SN/A case TSDEV_CC_DIR1: 1402190SN/A *(uint64_t*)data = dir[1]; 1412190SN/A return NoFault; 1422159SN/A case TSDEV_CC_DIR2: 1432235SN/A *(uint64_t*)data = dir[2]; 1442103SN/A return NoFault; 145393SN/A case TSDEV_CC_DIR3: 146393SN/A *(uint64_t*)data = dir[3]; 1472190SN/A return NoFault; 148393SN/A case TSDEV_CC_DRIR: 149393SN/A *(uint64_t*)data = drir; 1505250Sksewell@umich.edu return NoFault; 151393SN/A case TSDEV_CC_PRBEN: 152393SN/A panic("TSDEV_CC_PRBEN not implemented\n"); 1535250Sksewell@umich.edu return NoFault; 1542159SN/A case TSDEV_CC_IIC0: 1552159SN/A case TSDEV_CC_IIC1: 1562190SN/A case TSDEV_CC_IIC2: 1572159SN/A case TSDEV_CC_IIC3: 1582159SN/A panic("TSDEV_CC_IICx not implemented\n"); 1592680Sktlim@umich.edu return NoFault; 1602159SN/A case TSDEV_CC_MPR0: 1612190SN/A case TSDEV_CC_MPR1: 1622159SN/A case TSDEV_CC_MPR2: 1632190SN/A case TSDEV_CC_MPR3: 1642190SN/A panic("TSDEV_CC_MPRx not implemented\n"); 1652159SN/A return NoFault; 1662235SN/A case TSDEV_CC_IPIR: 1672313SN/A *(uint64_t*)data = ipint; 1682235SN/A return NoFault; 1692235SN/A case TSDEV_CC_ITIR: 1702235SN/A *(uint64_t*)data = itint; 1712235SN/A return NoFault; 1722235SN/A default: 1732254SN/A panic("default in cchip read reached, accessing 0x%x\n"); 1742254SN/A } // uint64_t 1752254SN/A 1762235SN/A break; 1772235SN/A case sizeof(uint32_t): 1782235SN/A if (regnum == TSDEV_CC_DRIR) { 1792254SN/A warn("accessing DRIR with 32 bit read, " 1802190SN/A "hopefully your just reading this for timing"); 1812159SN/A *(uint32_t*)data = drir; 1822680Sktlim@umich.edu } else 1832159SN/A panic("invalid access size(?) for tsunami register!\n"); 1842190SN/A return NoFault; 1852159SN/A case sizeof(uint16_t): 1862159SN/A case sizeof(uint8_t): 1872159SN/A default: 1882159SN/A panic("invalid access size(?) for tsunami register!\n"); 1892190SN/A } 1902159SN/A DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); 1912455SN/A 1922159SN/A return NoFault; 1932455SN/A} 1942159SN/A 1952455SN/AFault * 1962455SN/ATsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 1972455SN/A{ 1982159SN/A DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", 1992190SN/A req->vaddr, *(uint64_t*)data, req->size); 2002159SN/A 2012455SN/A Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); 2022159SN/A Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 2032455SN/A 2042159SN/A bool supportedWrite = false; 2052455SN/A 2062455SN/A switch (req->size) { 2072455SN/A 2082159SN/A case sizeof(uint64_t): 2092190SN/A if (daddr & TSDEV_CC_BDIMS) 2102159SN/A { 2112190SN/A int number = (daddr >> 4) & 0x3F; 2122159SN/A 2132190SN/A uint64_t bitvector; 2142159SN/A uint64_t olddim; 2152190SN/A uint64_t olddir; 2162159SN/A 2172447SN/A olddim = dim[number]; 2182447SN/A olddir = dir[number]; 2192447SN/A dim[number] = *(uint64_t*)data; 2202447SN/A dir[number] = dim[number] & drir; 2215260Sksewell@umich.edu for(int x = 0; x < Tsunami::Max_CPUs; x++) 2225260Sksewell@umich.edu { 2235260Sksewell@umich.edu bitvector = ULL(1) << x; 2245260Sksewell@umich.edu // Figure out which bits have changed 2255260Sksewell@umich.edu if ((dim[number] & bitvector) != (olddim & bitvector)) 2265260Sksewell@umich.edu { 2275260Sksewell@umich.edu // The bit is now set and it wasn't before (set) 2285260Sksewell@umich.edu if((dim[number] & bitvector) && (dir[number] & bitvector)) 2294172Ssaidi@eecs.umich.edu { 2304172Ssaidi@eecs.umich.edu tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 2312190SN/A DPRINTF(Tsunami, "dim write resulting in posting dir" 2322159SN/A " interrupt to cpu %d\n", number); 2334172Ssaidi@eecs.umich.edu } 2342190SN/A else if ((olddir & bitvector) && 2353468Sgblack@eecs.umich.edu !(dir[number] & bitvector)) 2362190SN/A { 2374661Sksewell@umich.edu // The bit was set and now its now clear and 2384661Sksewell@umich.edu // we were interrupting on that bit before 2394661Sksewell@umich.edu tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 2404661Sksewell@umich.edu DPRINTF(Tsunami, "dim write resulting in clear" 2412235SN/A " dir interrupt to cpu %d\n", number); 2422235SN/A 2432190SN/A } 2442190SN/A 2452190SN/A 2462159SN/A } 2472235SN/A } 2482190SN/A return NoFault; 2492190SN/A } 2502159SN/A 2512235SN/A switch(regnum) { 2522190SN/A case TSDEV_CC_CSR: 2532834Sksewell@umich.edu panic("TSDEV_CC_CSR write\n"); 2544111Sgblack@eecs.umich.edu return NoFault; 2554111Sgblack@eecs.umich.edu case TSDEV_CC_MTR: 2562834Sksewell@umich.edu panic("TSDEV_CC_MTR write not implemented\n"); 2572834Sksewell@umich.edu return NoFault; 2582834Sksewell@umich.edu case TSDEV_CC_MISC: 2592834Sksewell@umich.edu uint64_t ipreq; 2602159SN/A ipreq = (*(uint64_t*)data >> 12) & 0xF; 2612525SN/A //If it is bit 12-15, this is an IPI post 2625217Ssaidi@eecs.umich.edu if (ipreq) { 2635217Ssaidi@eecs.umich.edu reqIPI(ipreq); 2642159SN/A supportedWrite = true; 2652159SN/A } 2662682Sktlim@umich.edu 2672682Sktlim@umich.edu //If it is bit 8-11, this is an IPI clear 2682682Sktlim@umich.edu uint64_t ipintr; 2692682Sktlim@umich.edu ipintr = (*(uint64_t*)data >> 8) & 0xF; 2702682Sktlim@umich.edu if (ipintr) { 2712682Sktlim@umich.edu clearIPI(ipintr); 2722682Sktlim@umich.edu supportedWrite = true; 2732682Sktlim@umich.edu } 2742682Sktlim@umich.edu 2752682Sktlim@umich.edu //If it is the 4-7th bit, clear the RTC interrupt 2762680Sktlim@umich.edu uint64_t itintr; 2772680Sktlim@umich.edu itintr = (*(uint64_t*)data >> 4) & 0xF; 2782190SN/A if (itintr) { 2792190SN/A clearITI(itintr); 2802680Sktlim@umich.edu supportedWrite = true; 2812680Sktlim@umich.edu } 2822159SN/A 2832190SN/A // ignore NXMs 2842680Sktlim@umich.edu if (*(uint64_t*)data & 0x10000000) 2852SN/A supportedWrite = true; 2862SN/A 2872SN/A if(!supportedWrite) 2882680Sktlim@umich.edu panic("TSDEV_CC_MISC write not implemented\n"); 2892SN/A 2905712Shsul@eecs.umich.edu return NoFault; 2912SN/A case TSDEV_CC_AAR0: 2925715Shsul@eecs.umich.edu case TSDEV_CC_AAR1: 2935715Shsul@eecs.umich.edu case TSDEV_CC_AAR2: 2945715Shsul@eecs.umich.edu case TSDEV_CC_AAR3: 2955714Shsul@eecs.umich.edu panic("TSDEV_CC_AARx write not implemeted\n"); 2965714Shsul@eecs.umich.edu return NoFault; 2975714Shsul@eecs.umich.edu case TSDEV_CC_DIM0: 2985714Shsul@eecs.umich.edu case TSDEV_CC_DIM1: 2995714Shsul@eecs.umich.edu case TSDEV_CC_DIM2: 3006022Sgblack@eecs.umich.edu case TSDEV_CC_DIM3: 3011917SN/A int number; 3026022Sgblack@eecs.umich.edu if(regnum == TSDEV_CC_DIM0) 3032521SN/A number = 0; 3044997Sgblack@eecs.umich.edu else if(regnum == TSDEV_CC_DIM1) 3054997Sgblack@eecs.umich.edu number = 1; 3065803Snate@binkert.org else if(regnum == TSDEV_CC_DIM2) 3073548Sgblack@eecs.umich.edu number = 2; 3083548Sgblack@eecs.umich.edu else 3092654SN/A number = 3; 3102680Sktlim@umich.edu 3112521SN/A uint64_t bitvector; 3125499Ssaidi@eecs.umich.edu uint64_t olddim; 3133673Srdreslin@umich.edu uint64_t olddir; 3145497Ssaidi@eecs.umich.edu 3152SN/A olddim = dim[number]; 3162680Sktlim@umich.edu olddir = dir[number]; 3172518SN/A dim[number] = *(uint64_t*)data; 3182680Sktlim@umich.edu dir[number] = dim[number] & drir; 3192SN/A for(int x = 0; x < 64; x++) 3202SN/A { 3212680Sktlim@umich.edu bitvector = ULL(1) << x; 322595SN/A // Figure out which bits have changed 3232680Sktlim@umich.edu if ((dim[number] & bitvector) != (olddim & bitvector)) 3242SN/A { 3252190SN/A // The bit is now set and it wasn't before (set) 3262190SN/A if((dim[number] & bitvector) && (dir[number] & bitvector)) 3272680Sktlim@umich.edu { 3282SN/A tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 3292190SN/A DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 3305250Sksewell@umich.edu } 3312SN/A else if ((olddir & bitvector) && 3322190SN/A !(dir[number] & bitvector)) 3335250Sksewell@umich.edu { 334217SN/A // The bit was set and now its now clear and 3351858SN/A // we were interrupting on that bit before 3362680Sktlim@umich.edu tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 3372190SN/A DPRINTF(Tsunami, "dim write resulting in clear" 3382190SN/A " dir interrupt to cpu %d\n", 3392680Sktlim@umich.edu x); 3402680Sktlim@umich.edu 3412190SN/A } 3422680Sktlim@umich.edu 3432190SN/A 3442680Sktlim@umich.edu } 3452190SN/A } 3462680Sktlim@umich.edu return NoFault; 3472190SN/A case TSDEV_CC_DIR0: 3482235SN/A case TSDEV_CC_DIR1: 3492680Sktlim@umich.edu case TSDEV_CC_DIR2: 3502235SN/A case TSDEV_CC_DIR3: 3512680Sktlim@umich.edu panic("TSDEV_CC_DIR write not implemented\n"); 3522680Sktlim@umich.edu case TSDEV_CC_DRIR: 3532254SN/A panic("TSDEV_CC_DRIR write not implemented\n"); 3542680Sktlim@umich.edu case TSDEV_CC_PRBEN: 3552680Sktlim@umich.edu panic("TSDEV_CC_PRBEN write not implemented\n"); 3562235SN/A case TSDEV_CC_IIC0: 3572190SN/A case TSDEV_CC_IIC1: 3582680Sktlim@umich.edu case TSDEV_CC_IIC2: 3592SN/A case TSDEV_CC_IIC3: 3602190SN/A panic("TSDEV_CC_IICx write not implemented\n"); 3612680Sktlim@umich.edu case TSDEV_CC_MPR0: 3622SN/A case TSDEV_CC_MPR1: 3632680Sktlim@umich.edu case TSDEV_CC_MPR2: 364716SN/A case TSDEV_CC_MPR3: 3652SN/A panic("TSDEV_CC_MPRx write not implemented\n"); 3662SN/A case TSDEV_CC_IPIR: 3672SN/A clearIPI(*(uint64_t*)data); 3682SN/A return NoFault; 3692680Sktlim@umich.edu case TSDEV_CC_ITIR: 3702SN/A clearITI(*(uint64_t*)data); 3712455SN/A return NoFault; 3722680Sktlim@umich.edu case TSDEV_CC_IPIQ: 3732SN/A reqIPI(*(uint64_t*)data); 3742455SN/A return NoFault; 3752680Sktlim@umich.edu default: 3762SN/A panic("default in cchip read reached, accessing 0x%x\n"); 3772455SN/A } 3782680Sktlim@umich.edu 3792455SN/A break; 3802455SN/A case sizeof(uint32_t): 3812680Sktlim@umich.edu case sizeof(uint16_t): 3822SN/A case sizeof(uint8_t): 3832SN/A default: 3842680Sktlim@umich.edu panic("invalid access size(?) for tsunami register!\n"); 3852SN/A } 3862455SN/A 3872680Sktlim@umich.edu DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 3882SN/A 3892455SN/A return NoFault; 3902680Sktlim@umich.edu} 3912SN/A 3922455SN/Avoid 3932680Sktlim@umich.eduTsunamiCChip::clearIPI(uint64_t ipintr) 3942455SN/A{ 3952455SN/A int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 3962680Sktlim@umich.edu assert(numcpus <= Tsunami::Max_CPUs); 3972SN/A 3982680Sktlim@umich.edu if (ipintr) { 3992SN/A for (int cpunum=0; cpunum < numcpus; cpunum++) { 4002680Sktlim@umich.edu // Check each cpu bit 4012206SN/A uint64_t cpumask = ULL(1) << cpunum; 4022680Sktlim@umich.edu if (ipintr & cpumask) { 4032252SN/A // Check if there is a pending ipi 4042680Sktlim@umich.edu if (ipint & cpumask) { 4052SN/A ipint &= ~cpumask; 4062680Sktlim@umich.edu tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); 4072447SN/A DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); 4082680Sktlim@umich.edu } 4092447SN/A else 4105260Sksewell@umich.edu warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); 4115260Sksewell@umich.edu } 4125260Sksewell@umich.edu } 4135260Sksewell@umich.edu } 4145260Sksewell@umich.edu else 4155260Sksewell@umich.edu panic("Big IPI Clear, but not processors indicated\n"); 4165592Sgblack@eecs.umich.edu} 4175260Sksewell@umich.edu 4184172Ssaidi@eecs.umich.eduvoid 4194172Ssaidi@eecs.umich.eduTsunamiCChip::clearITI(uint64_t itintr) 4204172Ssaidi@eecs.umich.edu{ 4212159SN/A int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 4222680Sktlim@umich.edu assert(numcpus <= Tsunami::Max_CPUs); 4232SN/A 4244172Ssaidi@eecs.umich.edu if (itintr) { 4254172Ssaidi@eecs.umich.edu for (int i=0; i < numcpus; i++) { 4262SN/A uint64_t cpumask = ULL(1) << i; 4273468Sgblack@eecs.umich.edu if (itintr & cpumask & itint) { 4282680Sktlim@umich.edu tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); 4292SN/A itint &= ~cpumask; 4302190SN/A DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i); 4312680Sktlim@umich.edu } 4322190SN/A } 4332190SN/A } 4342680Sktlim@umich.edu else 4352SN/A panic("Big ITI Clear, but not processors indicated\n"); 4362190SN/A} 4372680Sktlim@umich.edu 4382190SN/Avoid 4391858SN/ATsunamiCChip::reqIPI(uint64_t ipreq) 4404111Sgblack@eecs.umich.edu{ 4414111Sgblack@eecs.umich.edu int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 4424111Sgblack@eecs.umich.edu assert(numcpus <= Tsunami::Max_CPUs); 4432680Sktlim@umich.edu 4442SN/A if (ipreq) { 4452SN/A for (int cpunum=0; cpunum < numcpus; cpunum++) { 4462SN/A // Check each cpu bit 4472190SN/A uint64_t cpumask = ULL(1) << cpunum; 448 if (ipreq & cpumask) { 449 // Check if there is already an ipi (bits 8:11) 450 if (!(ipint & cpumask)) { 451 ipint |= cpumask; 452 tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); 453 DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); 454 } 455 else 456 warn("post IPI for CPU=%d, but IPI already\n", cpunum); 457 } 458 } 459 } 460 else 461 panic("Big IPI Request, but not processors indicated\n"); 462} 463 464 465void 466TsunamiCChip::postRTC() 467{ 468 int size = tsunami->intrctrl->cpu->system->execContexts.size(); 469 assert(size <= Tsunami::Max_CPUs); 470 471 for (int i = 0; i < size; i++) { 472 uint64_t cpumask = ULL(1) << i; 473 if (!(cpumask & itint)) { 474 itint |= cpumask; 475 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); 476 DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); 477 } 478 } 479 480} 481 482void 483TsunamiCChip::postDRIR(uint32_t interrupt) 484{ 485 uint64_t bitvector = ULL(1) << interrupt; 486 uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); 487 assert(size <= Tsunami::Max_CPUs); 488 drir |= bitvector; 489 490 for(int i=0; i < size; i++) { 491 dir[i] = dim[i] & drir; 492 if (dim[i] & bitvector) { 493 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); 494 DPRINTF(Tsunami, "posting dir interrupt to cpu %d," 495 "interrupt %d\n",i, interrupt); 496 } 497 } 498} 499 500void 501TsunamiCChip::clearDRIR(uint32_t interrupt) 502{ 503 uint64_t bitvector = ULL(1) << interrupt; 504 uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); 505 assert(size <= Tsunami::Max_CPUs); 506 507 if (drir & bitvector) 508 { 509 drir &= ~bitvector; 510 for(int i=0; i < size; i++) { 511 if (dir[i] & bitvector) { 512 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); 513 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," 514 "interrupt %d\n",i, interrupt); 515 516 } 517 dir[i] = dim[i] & drir; 518 } 519 } 520 else 521 DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); 522} 523 524Tick 525TsunamiCChip::cacheAccess(MemReqPtr &req) 526{ 527 return curTick + pioLatency; 528} 529 530 531void 532TsunamiCChip::serialize(std::ostream &os) 533{ 534 SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 535 SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 536 SERIALIZE_SCALAR(ipint); 537 SERIALIZE_SCALAR(itint); 538 SERIALIZE_SCALAR(drir); 539} 540 541void 542TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 543{ 544 UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 545 UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 546 UNSERIALIZE_SCALAR(ipint); 547 UNSERIALIZE_SCALAR(itint); 548 UNSERIALIZE_SCALAR(drir); 549} 550 551BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 552 553 SimObjectParam<Tsunami *> tsunami; 554 SimObjectParam<MemoryController *> mmu; 555 Param<Addr> addr; 556 SimObjectParam<Bus*> pio_bus; 557 Param<Tick> pio_latency; 558 SimObjectParam<HierParams *> hier; 559 560END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 561 562BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 563 564 INIT_PARAM(tsunami, "Tsunami"), 565 INIT_PARAM(mmu, "Memory Controller"), 566 INIT_PARAM(addr, "Device Address"), 567 INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), 568 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), 569 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 570 571END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 572 573CREATE_SIM_OBJECT(TsunamiCChip) 574{ 575 return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, 576 pio_bus, pio_latency); 577} 578 579REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 580