tsunami_cchip.cc revision 3846
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1411308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1511308Santhony.gutierrez@amd.com * 1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711308Santhony.gutierrez@amd.com * 2811308Santhony.gutierrez@amd.com * Authors: Ali Saidi 2911308Santhony.gutierrez@amd.com * Ron Dreslinski 3011308Santhony.gutierrez@amd.com */ 3111308Santhony.gutierrez@amd.com 3211308Santhony.gutierrez@amd.com/** @file 3311308Santhony.gutierrez@amd.com * Emulation of the Tsunami CChip CSRs 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#include <deque> 3711308Santhony.gutierrez@amd.com#include <string> 3811308Santhony.gutierrez@amd.com#include <vector> 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com#include "arch/alpha/ev5.hh" 4111308Santhony.gutierrez@amd.com#include "base/trace.hh" 4211308Santhony.gutierrez@amd.com#include "cpu/intr_control.hh" 4311670Sandreas.hansson@arm.com#include "cpu/thread_context.hh" 4411670Sandreas.hansson@arm.com#include "dev/alpha/tsunami.hh" 4511308Santhony.gutierrez@amd.com#include "dev/alpha/tsunami_cchip.hh" 4611308Santhony.gutierrez@amd.com#include "dev/alpha/tsunamireg.h" 4711308Santhony.gutierrez@amd.com#include "mem/packet.hh" 4811308Santhony.gutierrez@amd.com#include "mem/packet_access.hh" 4911308Santhony.gutierrez@amd.com#include "mem/port.hh" 5011308Santhony.gutierrez@amd.com#include "sim/builder.hh" 5111308Santhony.gutierrez@amd.com#include "sim/system.hh" 5211308Santhony.gutierrez@amd.com 5311308Santhony.gutierrez@amd.comusing namespace std; 5411308Santhony.gutierrez@amd.com//Should this be AlphaISA? 5511308Santhony.gutierrez@amd.comusing namespace TheISA; 5611308Santhony.gutierrez@amd.com 5711308Santhony.gutierrez@amd.comTsunamiCChip::TsunamiCChip(Params *p) 5811308Santhony.gutierrez@amd.com : BasicPioDevice(p), tsunami(p->tsunami) 5911308Santhony.gutierrez@amd.com{ 6011308Santhony.gutierrez@amd.com pioSize = 0x10000000; 6111308Santhony.gutierrez@amd.com 6211308Santhony.gutierrez@amd.com drir = 0; 6311308Santhony.gutierrez@amd.com ipint = 0; 6411308Santhony.gutierrez@amd.com itint = 0; 6511308Santhony.gutierrez@amd.com 6611308Santhony.gutierrez@amd.com for (int x = 0; x < Tsunami::Max_CPUs; x++) 6711308Santhony.gutierrez@amd.com { 6811308Santhony.gutierrez@amd.com dim[x] = 0; 6911308Santhony.gutierrez@amd.com dir[x] = 0; 7011308Santhony.gutierrez@amd.com } 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com //Put back pointer in tsunami 7311308Santhony.gutierrez@amd.com tsunami->cchip = this; 7411308Santhony.gutierrez@amd.com} 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.comTick 7711308Santhony.gutierrez@amd.comTsunamiCChip::read(PacketPtr pkt) 7811308Santhony.gutierrez@amd.com{ 7911308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com assert(pkt->result == Packet::Unknown); 8211308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.com Addr regnum = (pkt->getAddr() - pioAddr) >> 6; 8511308Santhony.gutierrez@amd.com Addr daddr = (pkt->getAddr() - pioAddr); 8611308Santhony.gutierrez@amd.com 8711308Santhony.gutierrez@amd.com pkt->allocate(); 8811308Santhony.gutierrez@amd.com switch (pkt->getSize()) { 8911308Santhony.gutierrez@amd.com 9011308Santhony.gutierrez@amd.com case sizeof(uint64_t): 9111308Santhony.gutierrez@amd.com if (daddr & TSDEV_CC_BDIMS) 9211308Santhony.gutierrez@amd.com { 9311308Santhony.gutierrez@amd.com pkt->set(dim[(daddr >> 4) & 0x3F]); 9411308Santhony.gutierrez@amd.com break; 9511308Santhony.gutierrez@amd.com } 9611308Santhony.gutierrez@amd.com 9711308Santhony.gutierrez@amd.com if (daddr & TSDEV_CC_BDIRS) 9811308Santhony.gutierrez@amd.com { 9911308Santhony.gutierrez@amd.com pkt->set(dir[(daddr >> 4) & 0x3F]); 10011308Santhony.gutierrez@amd.com break; 10111308Santhony.gutierrez@amd.com } 10211308Santhony.gutierrez@amd.com 10311308Santhony.gutierrez@amd.com switch(regnum) { 10411308Santhony.gutierrez@amd.com case TSDEV_CC_CSR: 10511308Santhony.gutierrez@amd.com pkt->set(0x0); 10611308Santhony.gutierrez@amd.com break; 10711308Santhony.gutierrez@amd.com case TSDEV_CC_MTR: 10811308Santhony.gutierrez@amd.com panic("TSDEV_CC_MTR not implemeted\n"); 10911308Santhony.gutierrez@amd.com break; 11011308Santhony.gutierrez@amd.com case TSDEV_CC_MISC: 11111308Santhony.gutierrez@amd.com pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF | 11211308Santhony.gutierrez@amd.com (pkt->req->getCpuNum() & 0x3)); 11311308Santhony.gutierrez@amd.com break; 11411308Santhony.gutierrez@amd.com case TSDEV_CC_AAR0: 11511308Santhony.gutierrez@amd.com case TSDEV_CC_AAR1: 11611308Santhony.gutierrez@amd.com case TSDEV_CC_AAR2: 11711308Santhony.gutierrez@amd.com case TSDEV_CC_AAR3: 11811308Santhony.gutierrez@amd.com pkt->set(0); 11911308Santhony.gutierrez@amd.com break; 12011308Santhony.gutierrez@amd.com case TSDEV_CC_DIM0: 12111308Santhony.gutierrez@amd.com pkt->set(dim[0]); 12211308Santhony.gutierrez@amd.com break; 12311308Santhony.gutierrez@amd.com case TSDEV_CC_DIM1: 12411308Santhony.gutierrez@amd.com pkt->set(dim[1]); 12511308Santhony.gutierrez@amd.com break; 12611308Santhony.gutierrez@amd.com case TSDEV_CC_DIM2: 12711308Santhony.gutierrez@amd.com pkt->set(dim[2]); 12811308Santhony.gutierrez@amd.com break; 12911308Santhony.gutierrez@amd.com case TSDEV_CC_DIM3: 13011308Santhony.gutierrez@amd.com pkt->set(dim[3]); 13111308Santhony.gutierrez@amd.com break; 13211308Santhony.gutierrez@amd.com case TSDEV_CC_DIR0: 13311308Santhony.gutierrez@amd.com pkt->set(dir[0]); 13411308Santhony.gutierrez@amd.com break; 13511308Santhony.gutierrez@amd.com case TSDEV_CC_DIR1: 13611308Santhony.gutierrez@amd.com pkt->set(dir[1]); 13711308Santhony.gutierrez@amd.com break; 13811308Santhony.gutierrez@amd.com case TSDEV_CC_DIR2: 13911308Santhony.gutierrez@amd.com pkt->set(dir[2]); 14011308Santhony.gutierrez@amd.com break; 14111308Santhony.gutierrez@amd.com case TSDEV_CC_DIR3: 14211308Santhony.gutierrez@amd.com pkt->set(dir[3]); 14311308Santhony.gutierrez@amd.com break; 14411308Santhony.gutierrez@amd.com case TSDEV_CC_DRIR: 14511308Santhony.gutierrez@amd.com pkt->set(drir); 14611308Santhony.gutierrez@amd.com break; 14711308Santhony.gutierrez@amd.com case TSDEV_CC_PRBEN: 14811308Santhony.gutierrez@amd.com panic("TSDEV_CC_PRBEN not implemented\n"); 14911308Santhony.gutierrez@amd.com break; 15011308Santhony.gutierrez@amd.com case TSDEV_CC_IIC0: 15111308Santhony.gutierrez@amd.com case TSDEV_CC_IIC1: 15211308Santhony.gutierrez@amd.com case TSDEV_CC_IIC2: 15311308Santhony.gutierrez@amd.com case TSDEV_CC_IIC3: 15411308Santhony.gutierrez@amd.com panic("TSDEV_CC_IICx not implemented\n"); 15511308Santhony.gutierrez@amd.com break; 15611308Santhony.gutierrez@amd.com case TSDEV_CC_MPR0: 15711308Santhony.gutierrez@amd.com case TSDEV_CC_MPR1: 15811308Santhony.gutierrez@amd.com case TSDEV_CC_MPR2: 15911308Santhony.gutierrez@amd.com case TSDEV_CC_MPR3: 16011308Santhony.gutierrez@amd.com panic("TSDEV_CC_MPRx not implemented\n"); 16111308Santhony.gutierrez@amd.com break; 16211308Santhony.gutierrez@amd.com case TSDEV_CC_IPIR: 16311308Santhony.gutierrez@amd.com pkt->set(ipint); 16411308Santhony.gutierrez@amd.com break; 16511308Santhony.gutierrez@amd.com case TSDEV_CC_ITIR: 16611308Santhony.gutierrez@amd.com pkt->set(itint); 16711308Santhony.gutierrez@amd.com break; 16811308Santhony.gutierrez@amd.com default: 16911308Santhony.gutierrez@amd.com panic("default in cchip read reached, accessing 0x%x\n"); 17012065Snikos.nikoleris@arm.com } // uint64_t 17111308Santhony.gutierrez@amd.com 17211308Santhony.gutierrez@amd.com break; 17311308Santhony.gutierrez@amd.com case sizeof(uint32_t): 17411308Santhony.gutierrez@amd.com case sizeof(uint16_t): 17512065Snikos.nikoleris@arm.com case sizeof(uint8_t): 17612065Snikos.nikoleris@arm.com default: 17711308Santhony.gutierrez@amd.com panic("invalid access size(?) for tsunami register!\n"); 17811308Santhony.gutierrez@amd.com } 17911308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", 18011308Santhony.gutierrez@amd.com regnum, pkt->getSize(), pkt->get<uint64_t>()); 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com pkt->result = Packet::Success; 18311308Santhony.gutierrez@amd.com return pioDelay; 18411308Santhony.gutierrez@amd.com} 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.comTick 18711308Santhony.gutierrez@amd.comTsunamiCChip::write(PacketPtr pkt) 18811308Santhony.gutierrez@amd.com{ 18911308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 19011308Santhony.gutierrez@amd.com Addr daddr = pkt->getAddr() - pioAddr; 19111308Santhony.gutierrez@amd.com Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.com 19411308Santhony.gutierrez@amd.com assert(pkt->getSize() == sizeof(uint64_t)); 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>()); 19711308Santhony.gutierrez@amd.com 19811308Santhony.gutierrez@amd.com bool supportedWrite = false; 19911308Santhony.gutierrez@amd.com 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com if (daddr & TSDEV_CC_BDIMS) 20211308Santhony.gutierrez@amd.com { 20311308Santhony.gutierrez@amd.com int number = (daddr >> 4) & 0x3F; 20411308Santhony.gutierrez@amd.com 20511308Santhony.gutierrez@amd.com uint64_t bitvector; 20611308Santhony.gutierrez@amd.com uint64_t olddim; 20711308Santhony.gutierrez@amd.com uint64_t olddir; 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com olddim = dim[number]; 21011308Santhony.gutierrez@amd.com olddir = dir[number]; 21111308Santhony.gutierrez@amd.com dim[number] = pkt->get<uint64_t>(); 21211308Santhony.gutierrez@amd.com dir[number] = dim[number] & drir; 21311308Santhony.gutierrez@amd.com for(int x = 0; x < Tsunami::Max_CPUs; x++) 21411308Santhony.gutierrez@amd.com { 21511308Santhony.gutierrez@amd.com bitvector = ULL(1) << x; 21611308Santhony.gutierrez@amd.com // Figure out which bits have changed 21711308Santhony.gutierrez@amd.com if ((dim[number] & bitvector) != (olddim & bitvector)) 21811308Santhony.gutierrez@amd.com { 21911308Santhony.gutierrez@amd.com // The bit is now set and it wasn't before (set) 22011308Santhony.gutierrez@amd.com if((dim[number] & bitvector) && (dir[number] & bitvector)) 22111308Santhony.gutierrez@amd.com { 22211308Santhony.gutierrez@amd.com tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 22311308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "dim write resulting in posting dir" 22411308Santhony.gutierrez@amd.com " interrupt to cpu %d\n", number); 22511308Santhony.gutierrez@amd.com } 22611308Santhony.gutierrez@amd.com else if ((olddir & bitvector) && 22711308Santhony.gutierrez@amd.com !(dir[number] & bitvector)) 22811308Santhony.gutierrez@amd.com { 22911308Santhony.gutierrez@amd.com // The bit was set and now its now clear and 23011308Santhony.gutierrez@amd.com // we were interrupting on that bit before 23111308Santhony.gutierrez@amd.com tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 23211308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "dim write resulting in clear" 23311308Santhony.gutierrez@amd.com " dir interrupt to cpu %d\n", number); 23411308Santhony.gutierrez@amd.com 23511308Santhony.gutierrez@amd.com } 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.com 23812065Snikos.nikoleris@arm.com } 23912065Snikos.nikoleris@arm.com } 24012065Snikos.nikoleris@arm.com } else { 24112065Snikos.nikoleris@arm.com switch(regnum) { 24212065Snikos.nikoleris@arm.com case TSDEV_CC_CSR: 24312065Snikos.nikoleris@arm.com panic("TSDEV_CC_CSR write\n"); 24412065Snikos.nikoleris@arm.com case TSDEV_CC_MTR: 24512065Snikos.nikoleris@arm.com panic("TSDEV_CC_MTR write not implemented\n"); 24612065Snikos.nikoleris@arm.com case TSDEV_CC_MISC: 24712065Snikos.nikoleris@arm.com uint64_t ipreq; 24812065Snikos.nikoleris@arm.com ipreq = (pkt->get<uint64_t>() >> 12) & 0xF; 24911308Santhony.gutierrez@amd.com //If it is bit 12-15, this is an IPI post 25012065Snikos.nikoleris@arm.com if (ipreq) { 25112065Snikos.nikoleris@arm.com reqIPI(ipreq); 25212065Snikos.nikoleris@arm.com supportedWrite = true; 25312065Snikos.nikoleris@arm.com } 25412065Snikos.nikoleris@arm.com 25512065Snikos.nikoleris@arm.com //If it is bit 8-11, this is an IPI clear 25612065Snikos.nikoleris@arm.com uint64_t ipintr; 25712065Snikos.nikoleris@arm.com ipintr = (pkt->get<uint64_t>() >> 8) & 0xF; 25811308Santhony.gutierrez@amd.com if (ipintr) { 25911308Santhony.gutierrez@amd.com clearIPI(ipintr); 26012065Snikos.nikoleris@arm.com supportedWrite = true; 26111308Santhony.gutierrez@amd.com } 26211308Santhony.gutierrez@amd.com 26311308Santhony.gutierrez@amd.com //If it is the 4-7th bit, clear the RTC interrupt 26411308Santhony.gutierrez@amd.com uint64_t itintr; 26511308Santhony.gutierrez@amd.com itintr = (pkt->get<uint64_t>() >> 4) & 0xF; 26611308Santhony.gutierrez@amd.com if (itintr) { 26711308Santhony.gutierrez@amd.com clearITI(itintr); 26811308Santhony.gutierrez@amd.com supportedWrite = true; 26911308Santhony.gutierrez@amd.com } 27011308Santhony.gutierrez@amd.com 27111308Santhony.gutierrez@amd.com // ignore NXMs 27211308Santhony.gutierrez@amd.com if (pkt->get<uint64_t>() & 0x10000000) 27311308Santhony.gutierrez@amd.com supportedWrite = true; 27411308Santhony.gutierrez@amd.com 27511308Santhony.gutierrez@amd.com if(!supportedWrite) 27611308Santhony.gutierrez@amd.com panic("TSDEV_CC_MISC write not implemented\n"); 27711308Santhony.gutierrez@amd.com 27811308Santhony.gutierrez@amd.com break; 27911308Santhony.gutierrez@amd.com case TSDEV_CC_AAR0: 28011308Santhony.gutierrez@amd.com case TSDEV_CC_AAR1: 28111308Santhony.gutierrez@amd.com case TSDEV_CC_AAR2: 28211308Santhony.gutierrez@amd.com case TSDEV_CC_AAR3: 28311308Santhony.gutierrez@amd.com panic("TSDEV_CC_AARx write not implemeted\n"); 28411308Santhony.gutierrez@amd.com case TSDEV_CC_DIM0: 28511308Santhony.gutierrez@amd.com case TSDEV_CC_DIM1: 28611308Santhony.gutierrez@amd.com case TSDEV_CC_DIM2: 28711308Santhony.gutierrez@amd.com case TSDEV_CC_DIM3: 28811308Santhony.gutierrez@amd.com int number; 28911308Santhony.gutierrez@amd.com if(regnum == TSDEV_CC_DIM0) 29011308Santhony.gutierrez@amd.com number = 0; 29111308Santhony.gutierrez@amd.com else if(regnum == TSDEV_CC_DIM1) 29211308Santhony.gutierrez@amd.com number = 1; 29311308Santhony.gutierrez@amd.com else if(regnum == TSDEV_CC_DIM2) 29411308Santhony.gutierrez@amd.com number = 2; 29511308Santhony.gutierrez@amd.com else 29611308Santhony.gutierrez@amd.com number = 3; 29711308Santhony.gutierrez@amd.com 29811308Santhony.gutierrez@amd.com uint64_t bitvector; 29911308Santhony.gutierrez@amd.com uint64_t olddim; 30011308Santhony.gutierrez@amd.com uint64_t olddir; 30111308Santhony.gutierrez@amd.com 30211308Santhony.gutierrez@amd.com olddim = dim[number]; 30311308Santhony.gutierrez@amd.com olddir = dir[number]; 30411308Santhony.gutierrez@amd.com dim[number] = pkt->get<uint64_t>(); 30511308Santhony.gutierrez@amd.com dir[number] = dim[number] & drir; 30611308Santhony.gutierrez@amd.com for(int x = 0; x < 64; x++) 30711308Santhony.gutierrez@amd.com { 30811308Santhony.gutierrez@amd.com bitvector = ULL(1) << x; 30911308Santhony.gutierrez@amd.com // Figure out which bits have changed 31011308Santhony.gutierrez@amd.com if ((dim[number] & bitvector) != (olddim & bitvector)) 31111308Santhony.gutierrez@amd.com { 31211308Santhony.gutierrez@amd.com // The bit is now set and it wasn't before (set) 31311308Santhony.gutierrez@amd.com if((dim[number] & bitvector) && (dir[number] & bitvector)) 31411308Santhony.gutierrez@amd.com { 31511308Santhony.gutierrez@amd.com tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 31611308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 31711308Santhony.gutierrez@amd.com } 31811308Santhony.gutierrez@amd.com else if ((olddir & bitvector) && 31911308Santhony.gutierrez@amd.com !(dir[number] & bitvector)) 32011308Santhony.gutierrez@amd.com { 32111308Santhony.gutierrez@amd.com // The bit was set and now its now clear and 32211308Santhony.gutierrez@amd.com // we were interrupting on that bit before 32311308Santhony.gutierrez@amd.com tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 32411308Santhony.gutierrez@amd.com DPRINTF(Tsunami, "dim write resulting in clear" 32511308Santhony.gutierrez@amd.com " dir interrupt to cpu %d\n", 32611308Santhony.gutierrez@amd.com x); 32711308Santhony.gutierrez@amd.com 32811308Santhony.gutierrez@amd.com } 32911308Santhony.gutierrez@amd.com 33011308Santhony.gutierrez@amd.com 33111308Santhony.gutierrez@amd.com } 33211308Santhony.gutierrez@amd.com } 33311308Santhony.gutierrez@amd.com break; 33411308Santhony.gutierrez@amd.com case TSDEV_CC_DIR0: 33511308Santhony.gutierrez@amd.com case TSDEV_CC_DIR1: 336 case TSDEV_CC_DIR2: 337 case TSDEV_CC_DIR3: 338 panic("TSDEV_CC_DIR write not implemented\n"); 339 case TSDEV_CC_DRIR: 340 panic("TSDEV_CC_DRIR write not implemented\n"); 341 case TSDEV_CC_PRBEN: 342 panic("TSDEV_CC_PRBEN write not implemented\n"); 343 case TSDEV_CC_IIC0: 344 case TSDEV_CC_IIC1: 345 case TSDEV_CC_IIC2: 346 case TSDEV_CC_IIC3: 347 panic("TSDEV_CC_IICx write not implemented\n"); 348 case TSDEV_CC_MPR0: 349 case TSDEV_CC_MPR1: 350 case TSDEV_CC_MPR2: 351 case TSDEV_CC_MPR3: 352 panic("TSDEV_CC_MPRx write not implemented\n"); 353 case TSDEV_CC_IPIR: 354 clearIPI(pkt->get<uint64_t>()); 355 break; 356 case TSDEV_CC_ITIR: 357 clearITI(pkt->get<uint64_t>()); 358 break; 359 case TSDEV_CC_IPIQ: 360 reqIPI(pkt->get<uint64_t>()); 361 break; 362 default: 363 panic("default in cchip read reached, accessing 0x%x\n"); 364 } // swtich(regnum) 365 } // not BIG_TSUNAMI write 366 pkt->result = Packet::Success; 367 return pioDelay; 368} 369 370void 371TsunamiCChip::clearIPI(uint64_t ipintr) 372{ 373 int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); 374 assert(numcpus <= Tsunami::Max_CPUs); 375 376 if (ipintr) { 377 for (int cpunum=0; cpunum < numcpus; cpunum++) { 378 // Check each cpu bit 379 uint64_t cpumask = ULL(1) << cpunum; 380 if (ipintr & cpumask) { 381 // Check if there is a pending ipi 382 if (ipint & cpumask) { 383 ipint &= ~cpumask; 384 tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); 385 DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); 386 } 387 else 388 warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); 389 } 390 } 391 } 392 else 393 panic("Big IPI Clear, but not processors indicated\n"); 394} 395 396void 397TsunamiCChip::clearITI(uint64_t itintr) 398{ 399 int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); 400 assert(numcpus <= Tsunami::Max_CPUs); 401 402 if (itintr) { 403 for (int i=0; i < numcpus; i++) { 404 uint64_t cpumask = ULL(1) << i; 405 if (itintr & cpumask & itint) { 406 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); 407 itint &= ~cpumask; 408 DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i); 409 } 410 } 411 } 412 else 413 panic("Big ITI Clear, but not processors indicated\n"); 414} 415 416void 417TsunamiCChip::reqIPI(uint64_t ipreq) 418{ 419 int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); 420 assert(numcpus <= Tsunami::Max_CPUs); 421 422 if (ipreq) { 423 for (int cpunum=0; cpunum < numcpus; cpunum++) { 424 // Check each cpu bit 425 uint64_t cpumask = ULL(1) << cpunum; 426 if (ipreq & cpumask) { 427 // Check if there is already an ipi (bits 8:11) 428 if (!(ipint & cpumask)) { 429 ipint |= cpumask; 430 tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); 431 DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); 432 } 433 else 434 warn("post IPI for CPU=%d, but IPI already\n", cpunum); 435 } 436 } 437 } 438 else 439 panic("Big IPI Request, but not processors indicated\n"); 440} 441 442 443void 444TsunamiCChip::postRTC() 445{ 446 int size = tsunami->intrctrl->cpu->system->threadContexts.size(); 447 assert(size <= Tsunami::Max_CPUs); 448 449 for (int i = 0; i < size; i++) { 450 uint64_t cpumask = ULL(1) << i; 451 if (!(cpumask & itint)) { 452 itint |= cpumask; 453 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); 454 DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); 455 } 456 } 457 458} 459 460void 461TsunamiCChip::postDRIR(uint32_t interrupt) 462{ 463 uint64_t bitvector = ULL(1) << interrupt; 464 uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); 465 assert(size <= Tsunami::Max_CPUs); 466 drir |= bitvector; 467 468 for(int i=0; i < size; i++) { 469 dir[i] = dim[i] & drir; 470 if (dim[i] & bitvector) { 471 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); 472 DPRINTF(Tsunami, "posting dir interrupt to cpu %d," 473 "interrupt %d\n",i, interrupt); 474 } 475 } 476} 477 478void 479TsunamiCChip::clearDRIR(uint32_t interrupt) 480{ 481 uint64_t bitvector = ULL(1) << interrupt; 482 uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); 483 assert(size <= Tsunami::Max_CPUs); 484 485 if (drir & bitvector) 486 { 487 drir &= ~bitvector; 488 for(int i=0; i < size; i++) { 489 if (dir[i] & bitvector) { 490 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); 491 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," 492 "interrupt %d\n",i, interrupt); 493 494 } 495 dir[i] = dim[i] & drir; 496 } 497 } 498 else 499 DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); 500} 501 502 503void 504TsunamiCChip::serialize(std::ostream &os) 505{ 506 SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 507 SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 508 SERIALIZE_SCALAR(ipint); 509 SERIALIZE_SCALAR(itint); 510 SERIALIZE_SCALAR(drir); 511} 512 513void 514TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 515{ 516 UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 517 UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 518 UNSERIALIZE_SCALAR(ipint); 519 UNSERIALIZE_SCALAR(itint); 520 UNSERIALIZE_SCALAR(drir); 521} 522 523BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 524 525 Param<Addr> pio_addr; 526 Param<Tick> pio_latency; 527 SimObjectParam<Platform *> platform; 528 SimObjectParam<System *> system; 529 SimObjectParam<Tsunami *> tsunami; 530 531END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 532 533BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 534 535 INIT_PARAM(pio_addr, "Device Address"), 536 INIT_PARAM(pio_latency, "Programmed IO latency"), 537 INIT_PARAM(platform, "platform"), 538 INIT_PARAM(system, "system object"), 539 INIT_PARAM(tsunami, "Tsunami") 540 541END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 542 543CREATE_SIM_OBJECT(TsunamiCChip) 544{ 545 TsunamiCChip::Params *p = new TsunamiCChip::Params; 546 p->name = getInstanceName(); 547 p->pio_addr = pio_addr; 548 p->pio_delay = pio_latency; 549 p->platform = platform; 550 p->system = system; 551 p->tsunami = tsunami; 552 return new TsunamiCChip(p); 553} 554 555REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 556