interrupts.hh revision 5810
112810Sandreas.sandberg@arm.com/* 212810Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 312810Sandreas.sandberg@arm.com * All rights reserved. 412810Sandreas.sandberg@arm.com * 512810Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 612810Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 712810Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 812810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 912810Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1012810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1112810Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1212810Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1312810Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1412810Sandreas.sandberg@arm.com * this software without specific prior written permission. 1512810Sandreas.sandberg@arm.com * 1612810Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712810Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812810Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912810Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012810Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112810Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212810Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312810Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412810Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512810Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612810Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712810Sandreas.sandberg@arm.com * 2812810Sandreas.sandberg@arm.com * Authors: Ali Saidi 2912810Sandreas.sandberg@arm.com * Lisa Hsu 3012810Sandreas.sandberg@arm.com */ 3112810Sandreas.sandberg@arm.com 3212810Sandreas.sandberg@arm.com#ifndef __ARCH_SPARC_INTERRUPT_HH__ 3312810Sandreas.sandberg@arm.com#define __ARCH_SPARC_INTERRUPT_HH__ 3412810Sandreas.sandberg@arm.com 3512810Sandreas.sandberg@arm.com#include "arch/sparc/faults.hh" 3612810Sandreas.sandberg@arm.com#include "arch/sparc/isa_traits.hh" 3712810Sandreas.sandberg@arm.com#include "cpu/thread_context.hh" 3812810Sandreas.sandberg@arm.com#include "params/SparcInterrupts.hh" 3912810Sandreas.sandberg@arm.com#include "sim/sim_object.hh" 4012810Sandreas.sandberg@arm.com 4112810Sandreas.sandberg@arm.comnamespace SparcISA 4212810Sandreas.sandberg@arm.com{ 4312810Sandreas.sandberg@arm.com 4412810Sandreas.sandberg@arm.comclass Interrupts : public SimObject 4512810Sandreas.sandberg@arm.com{ 4612810Sandreas.sandberg@arm.com private: 4712810Sandreas.sandberg@arm.com BaseCPU * cpu; 4812810Sandreas.sandberg@arm.com 4912810Sandreas.sandberg@arm.com uint64_t interrupts[NumInterruptTypes]; 5012810Sandreas.sandberg@arm.com uint64_t intStatus; 5112810Sandreas.sandberg@arm.com 5212810Sandreas.sandberg@arm.com public: 5312919Sgiacomo.travaglini@arm.com 5412810Sandreas.sandberg@arm.com void 5512810Sandreas.sandberg@arm.com setCPU(BaseCPU * _cpu) 5612810Sandreas.sandberg@arm.com { 5712810Sandreas.sandberg@arm.com cpu = _cpu; 5812810Sandreas.sandberg@arm.com } 5912810Sandreas.sandberg@arm.com 6012810Sandreas.sandberg@arm.com typedef SparcInterruptsParams Params; 6112810Sandreas.sandberg@arm.com 6212810Sandreas.sandberg@arm.com const Params * 6312810Sandreas.sandberg@arm.com params() const 6412810Sandreas.sandberg@arm.com { 6512810Sandreas.sandberg@arm.com return dynamic_cast<const Params *>(_params); 6612810Sandreas.sandberg@arm.com } 6712810Sandreas.sandberg@arm.com 6812811Sandreas.sandberg@arm.com Interrupts(Params * p) : SimObject(p), cpu(NULL) 6912811Sandreas.sandberg@arm.com { 7012810Sandreas.sandberg@arm.com clearAll(); 7112810Sandreas.sandberg@arm.com } 7212810Sandreas.sandberg@arm.com 7312810Sandreas.sandberg@arm.com int 7412810Sandreas.sandberg@arm.com InterruptLevel(uint64_t softint) 7512810Sandreas.sandberg@arm.com { 7612810Sandreas.sandberg@arm.com if (softint & 0x10000 || softint & 0x1) 7712810Sandreas.sandberg@arm.com return 14; 7812810Sandreas.sandberg@arm.com 7912810Sandreas.sandberg@arm.com int level = 15; 8012810Sandreas.sandberg@arm.com while (level > 0 && !(1 << level & softint)) 8112810Sandreas.sandberg@arm.com level--; 8212810Sandreas.sandberg@arm.com if (1 << level & softint) 8312810Sandreas.sandberg@arm.com return level; 8412810Sandreas.sandberg@arm.com return 0; 8512810Sandreas.sandberg@arm.com } 8612810Sandreas.sandberg@arm.com 8712810Sandreas.sandberg@arm.com void 8812810Sandreas.sandberg@arm.com post(int int_num, int index) 8912810Sandreas.sandberg@arm.com { 9012810Sandreas.sandberg@arm.com DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 9112810Sandreas.sandberg@arm.com assert(int_num >= 0 && int_num < NumInterruptTypes); 9212810Sandreas.sandberg@arm.com assert(index >= 0 && index < 64); 9312810Sandreas.sandberg@arm.com 9412810Sandreas.sandberg@arm.com interrupts[int_num] |= ULL(1) << index; 9512810Sandreas.sandberg@arm.com intStatus |= ULL(1) << int_num; 9612810Sandreas.sandberg@arm.com } 9712810Sandreas.sandberg@arm.com 9812810Sandreas.sandberg@arm.com void 9912810Sandreas.sandberg@arm.com clear(int int_num, int index) 10012810Sandreas.sandberg@arm.com { 10112810Sandreas.sandberg@arm.com DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 10212810Sandreas.sandberg@arm.com assert(int_num >= 0 && int_num < NumInterruptTypes); 10312810Sandreas.sandberg@arm.com assert(index >= 0 && index < 64); 10412810Sandreas.sandberg@arm.com 10512810Sandreas.sandberg@arm.com interrupts[int_num] &= ~(ULL(1) << index); 10612810Sandreas.sandberg@arm.com if (!interrupts[int_num]) 10712810Sandreas.sandberg@arm.com intStatus &= ~(ULL(1) << int_num); 10812810Sandreas.sandberg@arm.com } 10912810Sandreas.sandberg@arm.com 11012810Sandreas.sandberg@arm.com void 11112810Sandreas.sandberg@arm.com clearAll() 11212810Sandreas.sandberg@arm.com { 11312810Sandreas.sandberg@arm.com for (int i = 0; i < NumInterruptTypes; ++i) { 11412810Sandreas.sandberg@arm.com interrupts[i] = 0; 11512810Sandreas.sandberg@arm.com } 11612810Sandreas.sandberg@arm.com intStatus = 0; 11712810Sandreas.sandberg@arm.com } 11812810Sandreas.sandberg@arm.com 11912810Sandreas.sandberg@arm.com bool 12012810Sandreas.sandberg@arm.com checkInterrupts(ThreadContext *tc) const 12112810Sandreas.sandberg@arm.com { 12212810Sandreas.sandberg@arm.com return intStatus; 12312810Sandreas.sandberg@arm.com } 12412810Sandreas.sandberg@arm.com 12512810Sandreas.sandberg@arm.com Fault 12612810Sandreas.sandberg@arm.com getInterrupt(ThreadContext *tc) 12712810Sandreas.sandberg@arm.com { 12812810Sandreas.sandberg@arm.com int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 12912810Sandreas.sandberg@arm.com int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 13012810Sandreas.sandberg@arm.com bool ie = pstate & PSTATE::ie; 13112810Sandreas.sandberg@arm.com 13212810Sandreas.sandberg@arm.com // THESE ARE IN ORDER OF PRIORITY 13312810Sandreas.sandberg@arm.com // since there are early returns, and the highest 13412810Sandreas.sandberg@arm.com // priority interrupts should get serviced, 13512810Sandreas.sandberg@arm.com // it is v. important that new interrupts are inserted 13612810Sandreas.sandberg@arm.com // in the right order of processing 13712810Sandreas.sandberg@arm.com if (hpstate & HPSTATE::hpriv) { 13812810Sandreas.sandberg@arm.com if (ie) { 13912810Sandreas.sandberg@arm.com if (interrupts[IT_HINTP]) { 14012810Sandreas.sandberg@arm.com // This will be cleaned by a HINTP write 14112810Sandreas.sandberg@arm.com return new HstickMatch; 14212810Sandreas.sandberg@arm.com } 14312810Sandreas.sandberg@arm.com if (interrupts[IT_INT_VEC]) { 14412810Sandreas.sandberg@arm.com // this will be cleared by an ASI read (or write) 14512810Sandreas.sandberg@arm.com return new InterruptVector; 14612810Sandreas.sandberg@arm.com } 14712810Sandreas.sandberg@arm.com } 14812810Sandreas.sandberg@arm.com } else { 14912810Sandreas.sandberg@arm.com if (interrupts[IT_TRAP_LEVEL_ZERO]) { 15012810Sandreas.sandberg@arm.com // this is cleared by deasserting HPSTATE::tlz 15112810Sandreas.sandberg@arm.com return new TrapLevelZero; 15212810Sandreas.sandberg@arm.com } 15312810Sandreas.sandberg@arm.com // HStick matches always happen in priv mode (ie doesn't matter) 15412810Sandreas.sandberg@arm.com if (interrupts[IT_HINTP]) { 15512810Sandreas.sandberg@arm.com return new HstickMatch; 15612810Sandreas.sandberg@arm.com } 15712810Sandreas.sandberg@arm.com if (interrupts[IT_INT_VEC]) { 15812810Sandreas.sandberg@arm.com // this will be cleared by an ASI read (or write) 15912810Sandreas.sandberg@arm.com return new InterruptVector; 16012810Sandreas.sandberg@arm.com } 16112810Sandreas.sandberg@arm.com if (ie) { 16212810Sandreas.sandberg@arm.com if (interrupts[IT_CPU_MONDO]) { 16312810Sandreas.sandberg@arm.com return new CpuMondo; 16412810Sandreas.sandberg@arm.com } 16512810Sandreas.sandberg@arm.com if (interrupts[IT_DEV_MONDO]) { 16612810Sandreas.sandberg@arm.com return new DevMondo; 16712918SMichiel.VanTol@arm.com } 16812918SMichiel.VanTol@arm.com if (interrupts[IT_SOFT_INT]) { 16912810Sandreas.sandberg@arm.com int level = InterruptLevel(interrupts[IT_SOFT_INT]); 17012810Sandreas.sandberg@arm.com return new InterruptLevelN(level); 17112810Sandreas.sandberg@arm.com } 17212810Sandreas.sandberg@arm.com 17312810Sandreas.sandberg@arm.com if (interrupts[IT_RES_ERROR]) { 17412810Sandreas.sandberg@arm.com return new ResumableError; 17512810Sandreas.sandberg@arm.com } 17612810Sandreas.sandberg@arm.com } // !hpriv && ie 17712810Sandreas.sandberg@arm.com } // !hpriv 17812810Sandreas.sandberg@arm.com return NoFault; 17912810Sandreas.sandberg@arm.com } 18012810Sandreas.sandberg@arm.com 18112810Sandreas.sandberg@arm.com void 18212810Sandreas.sandberg@arm.com updateIntrInfo(ThreadContext *tc) 18312919Sgiacomo.travaglini@arm.com { 18412810Sandreas.sandberg@arm.com 18512810Sandreas.sandberg@arm.com } 18612810Sandreas.sandberg@arm.com 18712810Sandreas.sandberg@arm.com uint64_t 18812810Sandreas.sandberg@arm.com get_vec(int int_num) 18912810Sandreas.sandberg@arm.com { 19012810Sandreas.sandberg@arm.com assert(int_num >= 0 && int_num < NumInterruptTypes); 19112810Sandreas.sandberg@arm.com return interrupts[int_num]; 19212810Sandreas.sandberg@arm.com } 19312810Sandreas.sandberg@arm.com 19412810Sandreas.sandberg@arm.com void 19512810Sandreas.sandberg@arm.com serialize(std::ostream &os) 19612810Sandreas.sandberg@arm.com { 19712810Sandreas.sandberg@arm.com SERIALIZE_ARRAY(interrupts,NumInterruptTypes); 19812811Sandreas.sandberg@arm.com SERIALIZE_SCALAR(intStatus); 19912811Sandreas.sandberg@arm.com } 20012811Sandreas.sandberg@arm.com 20112811Sandreas.sandberg@arm.com void 20212811Sandreas.sandberg@arm.com unserialize(Checkpoint *cp, const std::string §ion) 20312811Sandreas.sandberg@arm.com { 20412811Sandreas.sandberg@arm.com UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); 20512811Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(intStatus); 20612811Sandreas.sandberg@arm.com } 20712811Sandreas.sandberg@arm.com}; 20812811Sandreas.sandberg@arm.com} // namespace SPARC_ISA 20912811Sandreas.sandberg@arm.com 21012811Sandreas.sandberg@arm.com#endif // __ARCH_SPARC_INTERRUPT_HH__ 21112811Sandreas.sandberg@arm.com