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 §ion) 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