interrupts.hh revision 11566
12686Sksewell@umich.edu/* 22686Sksewell@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 35254Sksewell@umich.edu * All rights reserved. 45254Sksewell@umich.edu * 55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145254Sksewell@umich.edu * this software without specific prior written permission. 155254Sksewell@umich.edu * 165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275254Sksewell@umich.edu * 285254Sksewell@umich.edu * Authors: Ali Saidi 295254Sksewell@umich.edu * Lisa Hsu 305254Sksewell@umich.edu */ 312706Sksewell@umich.edu 322023SN/A#ifndef __ARCH_SPARC_INTERRUPT_HH__ 332023SN/A#define __ARCH_SPARC_INTERRUPT_HH__ 342023SN/A 352124SN/A#include "arch/sparc/faults.hh" 362124SN/A#include "arch/sparc/isa_traits.hh" 372023SN/A#include "arch/sparc/registers.hh" 382023SN/A#include "cpu/thread_context.hh" 392084SN/A#include "debug/Interrupt.hh" 402084SN/A#include "params/SparcInterrupts.hh" 412023SN/A#include "sim/sim_object.hh" 422023SN/A 432023SN/Anamespace SparcISA 442023SN/A{ 452023SN/A 462616SN/Aclass Interrupts : public SimObject 472077SN/A{ 482077SN/A private: 492077SN/A BaseCPU * cpu; 502616SN/A 514661Sksewell@umich.edu uint64_t interrupts[NumInterruptTypes]; 524661Sksewell@umich.edu uint64_t intStatus; 534661Sksewell@umich.edu 542616SN/A public: 552616SN/A 562562SN/A void 572041SN/A setCPU(BaseCPU * _cpu) 582616SN/A { 594661Sksewell@umich.edu cpu = _cpu; 604661Sksewell@umich.edu } 612616SN/A 624661Sksewell@umich.edu typedef SparcInterruptsParams Params; 634661Sksewell@umich.edu 644661Sksewell@umich.edu const Params * 654661Sksewell@umich.edu params() const 664661Sksewell@umich.edu { 674661Sksewell@umich.edu return dynamic_cast<const Params *>(_params); 684661Sksewell@umich.edu } 694661Sksewell@umich.edu 704661Sksewell@umich.edu Interrupts(Params * p) : SimObject(p), cpu(NULL) 714661Sksewell@umich.edu { 724661Sksewell@umich.edu clearAll(); 734661Sksewell@umich.edu } 744661Sksewell@umich.edu 754661Sksewell@umich.edu int 764661Sksewell@umich.edu InterruptLevel(uint64_t softint) 774661Sksewell@umich.edu { 784661Sksewell@umich.edu if (softint & 0x10000 || softint & 0x1) 794661Sksewell@umich.edu return 14; 804661Sksewell@umich.edu 814661Sksewell@umich.edu int level = 15; 822041SN/A while (level > 0 && !(1 << level & softint)) 832616SN/A level--; 842077SN/A if (1 << level & softint) 852077SN/A return level; 862077SN/A return 0; 872239SN/A } 882041SN/A 894661Sksewell@umich.edu void 902754Sksewell@umich.edu post(int int_num, int index) 912754Sksewell@umich.edu { 922754Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 932754Sksewell@umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 942754Sksewell@umich.edu assert(index >= 0 && index < 64); 952616SN/A 964661Sksewell@umich.edu interrupts[int_num] |= ULL(1) << index; 972607SN/A intStatus |= ULL(1) << int_num; 982607SN/A } 992607SN/A 1002607SN/A void 1012607SN/A clear(int int_num, int index) 1022607SN/A { 1032607SN/A DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1042607SN/A assert(int_num >= 0 && int_num < NumInterruptTypes); 1052607SN/A assert(index >= 0 && index < 64); 1064661Sksewell@umich.edu 1074661Sksewell@umich.edu interrupts[int_num] &= ~(ULL(1) << index); 1084661Sksewell@umich.edu if (!interrupts[int_num]) 1095222Sksewell@umich.edu intStatus &= ~(ULL(1) << int_num); 1105222Sksewell@umich.edu } 1115222Sksewell@umich.edu 1125222Sksewell@umich.edu void 1135222Sksewell@umich.edu clearAll() 1145222Sksewell@umich.edu { 1155222Sksewell@umich.edu for (int i = 0; i < NumInterruptTypes; ++i) { 1166338Sgblack@eecs.umich.edu interrupts[i] = 0; 1174661Sksewell@umich.edu } 1184661Sksewell@umich.edu intStatus = 0; 1194661Sksewell@umich.edu } 1204661Sksewell@umich.edu 1214661Sksewell@umich.edu bool 1224661Sksewell@umich.edu checkInterrupts(ThreadContext *tc) const 1234661Sksewell@umich.edu { 1244661Sksewell@umich.edu if (!intStatus) 1254661Sksewell@umich.edu return false; 1264661Sksewell@umich.edu 1274661Sksewell@umich.edu HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 1285222Sksewell@umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 1295222Sksewell@umich.edu 1305222Sksewell@umich.edu // THESE ARE IN ORDER OF PRIORITY 1315222Sksewell@umich.edu // since there are early returns, and the highest 1325222Sksewell@umich.edu // priority interrupts should get serviced, 1335222Sksewell@umich.edu // it is v. important that new interrupts are inserted 1345222Sksewell@umich.edu // in the right order of processing 1355222Sksewell@umich.edu if (hpstate.hpriv) { 1365222Sksewell@umich.edu if (pstate.ie) { 1375222Sksewell@umich.edu if (interrupts[IT_HINTP]) { 1385222Sksewell@umich.edu // This will be cleaned by a HINTP write 1395222Sksewell@umich.edu return true; 1405222Sksewell@umich.edu } 1415222Sksewell@umich.edu if (interrupts[IT_INT_VEC]) { 1425222Sksewell@umich.edu // this will be cleared by an ASI read (or write) 1435222Sksewell@umich.edu return true; 1445222Sksewell@umich.edu } 1454661Sksewell@umich.edu } 1464661Sksewell@umich.edu } else { 1474661Sksewell@umich.edu if (interrupts[IT_TRAP_LEVEL_ZERO]) { 1484661Sksewell@umich.edu // this is cleared by deasserting HPSTATE::tlz 1495222Sksewell@umich.edu return true; 1504661Sksewell@umich.edu } 1514661Sksewell@umich.edu // HStick matches always happen in priv mode (ie doesn't matter) 1524661Sksewell@umich.edu if (interrupts[IT_HINTP]) { 1534661Sksewell@umich.edu return true; 1544661Sksewell@umich.edu } 1554661Sksewell@umich.edu if (interrupts[IT_INT_VEC]) { 1564661Sksewell@umich.edu // this will be cleared by an ASI read (or write) 1574661Sksewell@umich.edu return true; 1585222Sksewell@umich.edu } 1595222Sksewell@umich.edu if (pstate.ie) { 1605222Sksewell@umich.edu if (interrupts[IT_CPU_MONDO]) { 1615222Sksewell@umich.edu return true; 1625222Sksewell@umich.edu } 1635222Sksewell@umich.edu if (interrupts[IT_DEV_MONDO]) { 1645222Sksewell@umich.edu return true; 1655222Sksewell@umich.edu } 1665222Sksewell@umich.edu if (interrupts[IT_SOFT_INT]) { 1675222Sksewell@umich.edu return true; 1685222Sksewell@umich.edu } 1695222Sksewell@umich.edu 1705222Sksewell@umich.edu if (interrupts[IT_RES_ERROR]) { 1715222Sksewell@umich.edu return true; 1725222Sksewell@umich.edu } 1735222Sksewell@umich.edu } // !hpriv && pstate.ie 1745222Sksewell@umich.edu } // !hpriv 1755222Sksewell@umich.edu 1764661Sksewell@umich.edu return false; 1774661Sksewell@umich.edu } 1784661Sksewell@umich.edu 1794661Sksewell@umich.edu Fault 1804661Sksewell@umich.edu getInterrupt(ThreadContext *tc) 1812616SN/A { 1822495SN/A assert(checkInterrupts(tc)); 1832041SN/A 1842616SN/A HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 1854661Sksewell@umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 1864661Sksewell@umich.edu 1872023SN/A // THESE ARE IN ORDER OF PRIORITY 188 // since there are early returns, and the highest 189 // priority interrupts should get serviced, 190 // it is v. important that new interrupts are inserted 191 // in the right order of processing 192 if (hpstate.hpriv) { 193 if (pstate.ie) { 194 if (interrupts[IT_HINTP]) { 195 // This will be cleaned by a HINTP write 196 return std::make_shared<HstickMatch>(); 197 } 198 if (interrupts[IT_INT_VEC]) { 199 // this will be cleared by an ASI read (or write) 200 return std::make_shared<InterruptVector>(); 201 } 202 } 203 } else { 204 if (interrupts[IT_TRAP_LEVEL_ZERO]) { 205 // this is cleared by deasserting HPSTATE::tlz 206 return std::make_shared<TrapLevelZero>(); 207 } 208 // HStick matches always happen in priv mode (ie doesn't matter) 209 if (interrupts[IT_HINTP]) { 210 return std::make_shared<HstickMatch>(); 211 } 212 if (interrupts[IT_INT_VEC]) { 213 // this will be cleared by an ASI read (or write) 214 return std::make_shared<InterruptVector>(); 215 } 216 if (pstate.ie) { 217 if (interrupts[IT_CPU_MONDO]) { 218 return std::make_shared<CpuMondo>(); 219 } 220 if (interrupts[IT_DEV_MONDO]) { 221 return std::make_shared<DevMondo>(); 222 } 223 if (interrupts[IT_SOFT_INT]) { 224 int level = InterruptLevel(interrupts[IT_SOFT_INT]); 225 return std::make_shared<InterruptLevelN>(level); 226 } 227 228 if (interrupts[IT_RES_ERROR]) { 229 return std::make_shared<ResumableError>(); 230 } 231 } // !hpriv && pstate.ie 232 } // !hpriv 233 return NoFault; 234 } 235 236 void 237 updateIntrInfo(ThreadContext *tc) 238 {} 239 240 uint64_t 241 get_vec(int int_num) 242 { 243 assert(int_num >= 0 && int_num < NumInterruptTypes); 244 return interrupts[int_num]; 245 } 246 247 void 248 serialize(CheckpointOut &cp) const override 249 { 250 SERIALIZE_ARRAY(interrupts,NumInterruptTypes); 251 SERIALIZE_SCALAR(intStatus); 252 } 253 254 void 255 unserialize(CheckpointIn &cp) override 256 { 257 UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); 258 UNSERIALIZE_SCALAR(intStatus); 259 } 260}; 261} // namespace SPARC_ISA 262 263#endif // __ARCH_SPARC_INTERRUPT_HH__ 264