interrupts.hh revision 4009
12391SN/A/* 28931Sandreas.hansson@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 37733SN/A * All rights reserved. 47733SN/A * 57733SN/A * Redistribution and use in source and binary forms, with or without 67733SN/A * modification, are permitted provided that the following conditions are 77733SN/A * met: redistributions of source code must retain the above copyright 87733SN/A * notice, this list of conditions and the following disclaimer; 97733SN/A * redistributions in binary form must reproduce the above copyright 107733SN/A * notice, this list of conditions and the following disclaimer in the 117733SN/A * documentation and/or other materials provided with the distribution; 127733SN/A * neither the name of the copyright holders nor the names of its 137733SN/A * contributors may be used to endorse or promote products derived from 142391SN/A * this software without specific prior written permission. 152391SN/A * 162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272391SN/A */ 282391SN/A 292391SN/A#ifndef __ARCH_SPARC_INTERRUPT_HH__ 302391SN/A#define __ARCH_SPARC_INTERRUPT_HH__ 312391SN/A 322391SN/A#include "arch/sparc/faults.hh" 332391SN/A#include "cpu/thread_context.hh" 342391SN/A 352391SN/Anamespace SparcISA 362391SN/A{ 372391SN/A 382391SN/Aenum interrupts_t { 392665SN/A trap_level_zero, 402665SN/A hstick_match, 412914SN/A interrupt_vector, 428931Sandreas.hansson@arm.com cpu_mondo, 432391SN/A dev_mondo, 442391SN/A resumable_error, 4510466Sandreas.hansson@arm.com soft_interrupt, 4610466Sandreas.hansson@arm.com num_interrupt_types 4710102Sali.saidi@arm.com}; 4810102Sali.saidi@arm.com 498232SN/Aclass Interrupts 508232SN/A{ 518931Sandreas.hansson@arm.com 523879SN/A private: 539053Sdam.sunwoo@arm.com 542394SN/A bool interrupts[num_interrupt_types]; 552391SN/A int numPosted; 562391SN/A 578931Sandreas.hansson@arm.com public: 588931Sandreas.hansson@arm.com Interrupts() 599053Sdam.sunwoo@arm.com { 609053Sdam.sunwoo@arm.com for (int i = 0; i < num_interrupt_types; ++i) { 612391SN/A interrupts[i] = false; 6210466Sandreas.hansson@arm.com } 6310466Sandreas.hansson@arm.com numPosted = 0; 6410466Sandreas.hansson@arm.com } 6510466Sandreas.hansson@arm.com 6610466Sandreas.hansson@arm.com void post(int int_type) 6710466Sandreas.hansson@arm.com { 6810466Sandreas.hansson@arm.com if (int_type < 0 || int_type >= num_interrupt_types) 6910466Sandreas.hansson@arm.com panic("posting unknown interrupt!\n"); 702391SN/A interrupts[int_type] = true; 712391SN/A ++numPosted; 722391SN/A } 739293Sandreas.hansson@arm.com 749293Sandreas.hansson@arm.com void post(int int_num, int index) 752391SN/A { 769293Sandreas.hansson@arm.com 772391SN/A } 782391SN/A 798719SN/A void clear(int int_num, int index) 808931Sandreas.hansson@arm.com { 818719SN/A 828719SN/A } 838719SN/A 849053Sdam.sunwoo@arm.com void clear_all() 859053Sdam.sunwoo@arm.com { 868719SN/A 879053Sdam.sunwoo@arm.com } 888719SN/A 898719SN/A bool check_interrupts(ThreadContext * tc) const 909053Sdam.sunwoo@arm.com { 918719SN/A if (numPosted) 929053Sdam.sunwoo@arm.com return true; 939053Sdam.sunwoo@arm.com else 949053Sdam.sunwoo@arm.com return false; 958719SN/A } 969053Sdam.sunwoo@arm.com 978719SN/A Fault getInterrupt(ThreadContext * tc) 988719SN/A { 999053Sdam.sunwoo@arm.com int hpstate = tc->readMiscReg(MISCREG_HPSTATE); 1008719SN/A int pstate = tc->readMiscReg(MISCREG_PSTATE); 1019053Sdam.sunwoo@arm.com bool ie = pstate & PSTATE::ie; 1029053Sdam.sunwoo@arm.com 1039053Sdam.sunwoo@arm.com // THESE ARE IN ORDER OF PRIORITY 1048719SN/A // since there are early returns, and the highest 1059053Sdam.sunwoo@arm.com // priority interrupts should get serviced, 1068719SN/A // it is v. important that new interrupts are inserted 1078719SN/A // in the right order of processing 1089053Sdam.sunwoo@arm.com if (hpstate & HPSTATE::hpriv) { 1098719SN/A if (ie) { 1109053Sdam.sunwoo@arm.com if (interrupts[hstick_match]) { 1119053Sdam.sunwoo@arm.com if (tc->readMiscReg(MISCREG_HINTP) & 1) { 1129053Sdam.sunwoo@arm.com interrupts[hstick_match] = false; 1138719SN/A --numPosted; 1149053Sdam.sunwoo@arm.com return new HstickMatch; 1158719SN/A } 1168719SN/A } 1179053Sdam.sunwoo@arm.com if (interrupts[interrupt_vector]) { 1188719SN/A interrupts[interrupt_vector] = false; 1199053Sdam.sunwoo@arm.com --numPosted; 1209053Sdam.sunwoo@arm.com //HAVEN'T IMPLed THIS YET 1219053Sdam.sunwoo@arm.com return NoFault; 1228719SN/A } 1239053Sdam.sunwoo@arm.com } else { 1248719SN/A if (interrupts[hstick_match]) { 1258719SN/A return NoFault; 1269053Sdam.sunwoo@arm.com } 1278719SN/A 1289053Sdam.sunwoo@arm.com } 1299053Sdam.sunwoo@arm.com } else { 1309053Sdam.sunwoo@arm.com if (interrupts[trap_level_zero]) { 1318719SN/A if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { 1329053Sdam.sunwoo@arm.com interrupts[trap_level_zero] = false; 1338719SN/A --numPosted; 1348719SN/A return new TrapLevelZero; 1359053Sdam.sunwoo@arm.com } 1368719SN/A } 1379053Sdam.sunwoo@arm.com if (interrupts[hstick_match]) { 1389053Sdam.sunwoo@arm.com if (tc->readMiscReg(MISCREG_HINTP) & 1) { 1399053Sdam.sunwoo@arm.com interrupts[hstick_match] = false; 1408719SN/A --numPosted; 1418719SN/A return new HstickMatch; 1428719SN/A } 1438719SN/A } 1448719SN/A if (ie) { 1459053Sdam.sunwoo@arm.com if (interrupts[cpu_mondo]) { 1468719SN/A interrupts[cpu_mondo] = false; 1479053Sdam.sunwoo@arm.com --numPosted; 1489053Sdam.sunwoo@arm.com return new CpuMondo; 1499053Sdam.sunwoo@arm.com } 1509053Sdam.sunwoo@arm.com if (interrupts[dev_mondo]) { 1518719SN/A interrupts[dev_mondo] = false; 1528719SN/A --numPosted; 1538719SN/A return new DevMondo; 1548719SN/A } 1558719SN/A if (interrupts[soft_interrupt]) { 1569053Sdam.sunwoo@arm.com int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); 1578719SN/A // it seems that interrupt vectors are right in 1589053Sdam.sunwoo@arm.com // the middle of interrupt levels with regard to 1599053Sdam.sunwoo@arm.com // priority, so have to check 1609053Sdam.sunwoo@arm.com if ((il < 6) && 1618719SN/A interrupts[interrupt_vector]) { 1628719SN/A // may require more details here since there 1638719SN/A // may be lots of interrupts embedded in an 1648719SN/A // platform interrupt vector 1658719SN/A interrupts[interrupt_vector] = false; 1669053Sdam.sunwoo@arm.com --numPosted; 1678719SN/A //HAVEN'T IMPLed YET 1689053Sdam.sunwoo@arm.com return NoFault; 1699053Sdam.sunwoo@arm.com } else { 1709053Sdam.sunwoo@arm.com if (il > tc->readMiscReg(MISCREG_PIL)) { 1718719SN/A uint64_t si = tc->readMiscReg(MISCREG_SOFTINT); 1728719SN/A uint64_t more = si & ~(1 << (il + 1)); 1738719SN/A if (!InterruptLevel(more)) { 1748719SN/A interrupts[soft_interrupt] = false; 1758719SN/A --numPosted; 1769053Sdam.sunwoo@arm.com } 1778719SN/A return new InterruptLevelN(il); 1789053Sdam.sunwoo@arm.com } 1799053Sdam.sunwoo@arm.com } 1809053Sdam.sunwoo@arm.com } 1818719SN/A if (interrupts[resumable_error]) { 1828719SN/A interrupts[resumable_error] = false; 1838719SN/A --numPosted; 1848719SN/A return new ResumableError; 1858719SN/A } 1868719SN/A } 1879235Sandreas.hansson@arm.com } 1889098Sandreas.hansson@arm.com return NoFault; 1892408SN/A } 1908931Sandreas.hansson@arm.com 1912408SN/A void updateIntrInfo(ThreadContext * tc) 1922408SN/A { 1933170SN/A 1946076SN/A } 1953170SN/A 1968931Sandreas.hansson@arm.com void serialize(std::ostream &os) 1973170SN/A { 1984626SN/A SERIALIZE_ARRAY(interrupts,num_interrupt_types); 1993170SN/A SERIALIZE_SCALAR(numPosted); 2003170SN/A } 2013170SN/A 2023170SN/A void unserialize(Checkpoint *cp, const std::string §ion) 2033170SN/A { 2043170SN/A UNSERIALIZE_ARRAY(interrupts,num_interrupt_types); 2053170SN/A UNSERIALIZE_SCALAR(numPosted); 2063170SN/A } 2073170SN/A}; 2085714SN/A} // namespace SPARC_ISA 2095714SN/A 2103170SN/A#endif // __ARCH_SPARC_INTERRUPT_HH__ 2113170SN/A