interrupts.hh revision 6335:a08470cb53e5
12501SN/A/* 22501SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32501SN/A * All rights reserved. 42501SN/A * 52501SN/A * Redistribution and use in source and binary forms, with or without 62501SN/A * modification, are permitted provided that the following conditions are 72501SN/A * met: redistributions of source code must retain the above copyright 82501SN/A * notice, this list of conditions and the following disclaimer; 92501SN/A * redistributions in binary form must reproduce the above copyright 102501SN/A * notice, this list of conditions and the following disclaimer in the 112501SN/A * documentation and/or other materials provided with the distribution; 122501SN/A * neither the name of the copyright holders nor the names of its 132501SN/A * contributors may be used to endorse or promote products derived from 142501SN/A * this software without specific prior written permission. 152501SN/A * 162501SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172501SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182501SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192501SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202501SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212501SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222501SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232501SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242501SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252501SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262501SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 292501SN/A * Lisa Hsu 302501SN/A */ 312501SN/A 322501SN/A#ifndef __ARCH_SPARC_INTERRUPT_HH__ 332501SN/A#define __ARCH_SPARC_INTERRUPT_HH__ 343532Sgblack@eecs.umich.edu 352501SN/A#include "arch/sparc/faults.hh" 363603Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh" 372501SN/A#include "arch/sparc/registers.hh" 383278Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 393272Sgblack@eecs.umich.edu#include "params/SparcInterrupts.hh" 402501SN/A#include "sim/sim_object.hh" 412501SN/A 422501SN/Anamespace SparcISA 433577Sgblack@eecs.umich.edu{ 443577Sgblack@eecs.umich.edu 453577Sgblack@eecs.umich.educlass Interrupts : public SimObject 463577Sgblack@eecs.umich.edu{ 474172Ssaidi@eecs.umich.edu private: 484172Ssaidi@eecs.umich.edu BaseCPU * cpu; 493577Sgblack@eecs.umich.edu 503577Sgblack@eecs.umich.edu uint64_t interrupts[NumInterruptTypes]; 512501SN/A uint64_t intStatus; 523272Sgblack@eecs.umich.edu 533918Ssaidi@eecs.umich.edu public: 543272Sgblack@eecs.umich.edu 553272Sgblack@eecs.umich.edu void 563272Sgblack@eecs.umich.edu setCPU(BaseCPU * _cpu) 573272Sgblack@eecs.umich.edu { 583272Sgblack@eecs.umich.edu cpu = _cpu; 594172Ssaidi@eecs.umich.edu } 603272Sgblack@eecs.umich.edu 613278Sgblack@eecs.umich.edu typedef SparcInterruptsParams Params; 623278Sgblack@eecs.umich.edu 633278Sgblack@eecs.umich.edu const Params * 643272Sgblack@eecs.umich.edu params() const 652501SN/A { 662501SN/A return dynamic_cast<const Params *>(_params); 672501SN/A } 682501SN/A 692501SN/A Interrupts(Params * p) : SimObject(p), cpu(NULL) 702501SN/A { 712501SN/A clearAll(); 722501SN/A } 732501SN/A 742501SN/A int 752501SN/A InterruptLevel(uint64_t softint) 762501SN/A { 772501SN/A if (softint & 0x10000 || softint & 0x1) 782501SN/A return 14; 792501SN/A 802501SN/A int level = 15; 812501SN/A while (level > 0 && !(1 << level & softint)) 822501SN/A level--; 832501SN/A if (1 << level & softint) 842501SN/A return level; 852501SN/A return 0; 862501SN/A } 872501SN/A 882501SN/A void 892501SN/A post(int int_num, int index) 902501SN/A { 912501SN/A DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 922501SN/A assert(int_num >= 0 && int_num < NumInterruptTypes); 932501SN/A assert(index >= 0 && index < 64); 942501SN/A 952501SN/A interrupts[int_num] |= ULL(1) << index; 962501SN/A intStatus |= ULL(1) << int_num; 972501SN/A } 982501SN/A 992501SN/A void 1002501SN/A clear(int int_num, int index) 1012501SN/A { 1022501SN/A DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1032501SN/A assert(int_num >= 0 && int_num < NumInterruptTypes); 1042501SN/A assert(index >= 0 && index < 64); 1052501SN/A 1062501SN/A interrupts[int_num] &= ~(ULL(1) << index); 1072680Sktlim@umich.edu if (!interrupts[int_num]) 1082501SN/A intStatus &= ~(ULL(1) << int_num); 1092680Sktlim@umich.edu } 1102680Sktlim@umich.edu 1112501SN/A void 1123532Sgblack@eecs.umich.edu clearAll() 1133528Sgblack@eecs.umich.edu { 1143532Sgblack@eecs.umich.edu for (int i = 0; i < NumInterruptTypes; ++i) { 1154194Ssaidi@eecs.umich.edu interrupts[i] = 0; 1164194Ssaidi@eecs.umich.edu } 1174194Ssaidi@eecs.umich.edu intStatus = 0; 1184194Ssaidi@eecs.umich.edu } 1194194Ssaidi@eecs.umich.edu 1204194Ssaidi@eecs.umich.edu bool 1214194Ssaidi@eecs.umich.edu checkInterrupts(ThreadContext *tc) const 1224194Ssaidi@eecs.umich.edu { 1234194Ssaidi@eecs.umich.edu return intStatus; 1244194Ssaidi@eecs.umich.edu } 1254194Ssaidi@eecs.umich.edu 1264194Ssaidi@eecs.umich.edu Fault 1274194Ssaidi@eecs.umich.edu getInterrupt(ThreadContext *tc) 1284194Ssaidi@eecs.umich.edu { 1293528Sgblack@eecs.umich.edu int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 1303528Sgblack@eecs.umich.edu int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 1312501SN/A bool ie = pstate & PSTATE::ie; 1322501SN/A 1332501SN/A // THESE ARE IN ORDER OF PRIORITY 134 // since there are early returns, and the highest 135 // priority interrupts should get serviced, 136 // it is v. important that new interrupts are inserted 137 // in the right order of processing 138 if (hpstate & HPSTATE::hpriv) { 139 if (ie) { 140 if (interrupts[IT_HINTP]) { 141 // This will be cleaned by a HINTP write 142 return new HstickMatch; 143 } 144 if (interrupts[IT_INT_VEC]) { 145 // this will be cleared by an ASI read (or write) 146 return new InterruptVector; 147 } 148 } 149 } else { 150 if (interrupts[IT_TRAP_LEVEL_ZERO]) { 151 // this is cleared by deasserting HPSTATE::tlz 152 return new TrapLevelZero; 153 } 154 // HStick matches always happen in priv mode (ie doesn't matter) 155 if (interrupts[IT_HINTP]) { 156 return new HstickMatch; 157 } 158 if (interrupts[IT_INT_VEC]) { 159 // this will be cleared by an ASI read (or write) 160 return new InterruptVector; 161 } 162 if (ie) { 163 if (interrupts[IT_CPU_MONDO]) { 164 return new CpuMondo; 165 } 166 if (interrupts[IT_DEV_MONDO]) { 167 return new DevMondo; 168 } 169 if (interrupts[IT_SOFT_INT]) { 170 int level = InterruptLevel(interrupts[IT_SOFT_INT]); 171 return new InterruptLevelN(level); 172 } 173 174 if (interrupts[IT_RES_ERROR]) { 175 return new ResumableError; 176 } 177 } // !hpriv && ie 178 } // !hpriv 179 return NoFault; 180 } 181 182 void 183 updateIntrInfo(ThreadContext *tc) 184 { 185 186 } 187 188 uint64_t 189 get_vec(int int_num) 190 { 191 assert(int_num >= 0 && int_num < NumInterruptTypes); 192 return interrupts[int_num]; 193 } 194 195 void 196 serialize(std::ostream &os) 197 { 198 SERIALIZE_ARRAY(interrupts,NumInterruptTypes); 199 SERIALIZE_SCALAR(intStatus); 200 } 201 202 void 203 unserialize(Checkpoint *cp, const std::string §ion) 204 { 205 UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); 206 UNSERIALIZE_SCALAR(intStatus); 207 } 208}; 209} // namespace SPARC_ISA 210 211#endif // __ARCH_SPARC_INTERRUPT_HH__ 212