interrupts.hh revision 11566
13537Sgblack@eecs.umich.edu/* 23537Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 33537Sgblack@eecs.umich.edu * All rights reserved. 43537Sgblack@eecs.umich.edu * 53537Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 63537Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 73537Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 83537Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 93537Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 103537Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 113537Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 123537Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 133537Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 143537Sgblack@eecs.umich.edu * this software without specific prior written permission. 153537Sgblack@eecs.umich.edu * 163537Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173537Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183537Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193537Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203537Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213537Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223537Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233537Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243537Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253537Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263537Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274103Ssaidi@eecs.umich.edu * 284103Ssaidi@eecs.umich.edu * Authors: Ali Saidi 294103Ssaidi@eecs.umich.edu * Lisa Hsu 303537Sgblack@eecs.umich.edu */ 313537Sgblack@eecs.umich.edu 323537Sgblack@eecs.umich.edu#ifndef __ARCH_SPARC_INTERRUPT_HH__ 333537Sgblack@eecs.umich.edu#define __ARCH_SPARC_INTERRUPT_HH__ 343537Sgblack@eecs.umich.edu 353537Sgblack@eecs.umich.edu#include "arch/sparc/faults.hh" 364103Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh" 376335Sgblack@eecs.umich.edu#include "arch/sparc/registers.hh" 383827Shsul@eecs.umich.edu#include "cpu/thread_context.hh" 398232Snate@binkert.org#include "debug/Interrupt.hh" 405647Sgblack@eecs.umich.edu#include "params/SparcInterrupts.hh" 415647Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 423827Shsul@eecs.umich.edu 433537Sgblack@eecs.umich.edunamespace SparcISA 443537Sgblack@eecs.umich.edu{ 453894Shsul@eecs.umich.edu 465647Sgblack@eecs.umich.educlass Interrupts : public SimObject 474009Ssaidi@eecs.umich.edu{ 485810Sgblack@eecs.umich.edu private: 495810Sgblack@eecs.umich.edu BaseCPU * cpu; 504009Ssaidi@eecs.umich.edu 514103Ssaidi@eecs.umich.edu uint64_t interrupts[NumInterruptTypes]; 524103Ssaidi@eecs.umich.edu uint64_t intStatus; 534009Ssaidi@eecs.umich.edu 544009Ssaidi@eecs.umich.edu public: 555810Sgblack@eecs.umich.edu 565810Sgblack@eecs.umich.edu void 575810Sgblack@eecs.umich.edu setCPU(BaseCPU * _cpu) 585810Sgblack@eecs.umich.edu { 595810Sgblack@eecs.umich.edu cpu = _cpu; 605810Sgblack@eecs.umich.edu } 615810Sgblack@eecs.umich.edu 625647Sgblack@eecs.umich.edu typedef SparcInterruptsParams Params; 635647Sgblack@eecs.umich.edu 645647Sgblack@eecs.umich.edu const Params * 655647Sgblack@eecs.umich.edu params() const 665647Sgblack@eecs.umich.edu { 675647Sgblack@eecs.umich.edu return dynamic_cast<const Params *>(_params); 685647Sgblack@eecs.umich.edu } 695647Sgblack@eecs.umich.edu 705810Sgblack@eecs.umich.edu Interrupts(Params * p) : SimObject(p), cpu(NULL) 714009Ssaidi@eecs.umich.edu { 725704Snate@binkert.org clearAll(); 734009Ssaidi@eecs.umich.edu } 744009Ssaidi@eecs.umich.edu 755704Snate@binkert.org int 765704Snate@binkert.org InterruptLevel(uint64_t softint) 774009Ssaidi@eecs.umich.edu { 784103Ssaidi@eecs.umich.edu if (softint & 0x10000 || softint & 0x1) 794103Ssaidi@eecs.umich.edu return 14; 804103Ssaidi@eecs.umich.edu 814103Ssaidi@eecs.umich.edu int level = 15; 824103Ssaidi@eecs.umich.edu while (level > 0 && !(1 << level & softint)) 834103Ssaidi@eecs.umich.edu level--; 844103Ssaidi@eecs.umich.edu if (1 << level & softint) 854103Ssaidi@eecs.umich.edu return level; 864103Ssaidi@eecs.umich.edu return 0; 874009Ssaidi@eecs.umich.edu } 884009Ssaidi@eecs.umich.edu 895704Snate@binkert.org void 905704Snate@binkert.org post(int int_num, int index) 913537Sgblack@eecs.umich.edu { 924103Ssaidi@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 934103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 944103Ssaidi@eecs.umich.edu assert(index >= 0 && index < 64); 953827Shsul@eecs.umich.edu 964103Ssaidi@eecs.umich.edu interrupts[int_num] |= ULL(1) << index; 974103Ssaidi@eecs.umich.edu intStatus |= ULL(1) << int_num; 984009Ssaidi@eecs.umich.edu } 993894Shsul@eecs.umich.edu 1005704Snate@binkert.org void 1015704Snate@binkert.org clear(int int_num, int index) 1024009Ssaidi@eecs.umich.edu { 1034103Ssaidi@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1044103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 1054103Ssaidi@eecs.umich.edu assert(index >= 0 && index < 64); 1063537Sgblack@eecs.umich.edu 1074103Ssaidi@eecs.umich.edu interrupts[int_num] &= ~(ULL(1) << index); 1084103Ssaidi@eecs.umich.edu if (!interrupts[int_num]) 1094103Ssaidi@eecs.umich.edu intStatus &= ~(ULL(1) << int_num); 1104009Ssaidi@eecs.umich.edu } 1113827Shsul@eecs.umich.edu 1125704Snate@binkert.org void 1135704Snate@binkert.org clearAll() 1144009Ssaidi@eecs.umich.edu { 1154103Ssaidi@eecs.umich.edu for (int i = 0; i < NumInterruptTypes; ++i) { 1164103Ssaidi@eecs.umich.edu interrupts[i] = 0; 1174103Ssaidi@eecs.umich.edu } 1184103Ssaidi@eecs.umich.edu intStatus = 0; 1194009Ssaidi@eecs.umich.edu } 1203537Sgblack@eecs.umich.edu 1215704Snate@binkert.org bool 1225704Snate@binkert.org checkInterrupts(ThreadContext *tc) const 1234009Ssaidi@eecs.umich.edu { 12411566Smitch.hayenga@arm.com if (!intStatus) 12511566Smitch.hayenga@arm.com return false; 12611566Smitch.hayenga@arm.com 12711566Smitch.hayenga@arm.com HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 12811566Smitch.hayenga@arm.com PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 12911566Smitch.hayenga@arm.com 13011566Smitch.hayenga@arm.com // THESE ARE IN ORDER OF PRIORITY 13111566Smitch.hayenga@arm.com // since there are early returns, and the highest 13211566Smitch.hayenga@arm.com // priority interrupts should get serviced, 13311566Smitch.hayenga@arm.com // it is v. important that new interrupts are inserted 13411566Smitch.hayenga@arm.com // in the right order of processing 13511566Smitch.hayenga@arm.com if (hpstate.hpriv) { 13611566Smitch.hayenga@arm.com if (pstate.ie) { 13711566Smitch.hayenga@arm.com if (interrupts[IT_HINTP]) { 13811566Smitch.hayenga@arm.com // This will be cleaned by a HINTP write 13911566Smitch.hayenga@arm.com return true; 14011566Smitch.hayenga@arm.com } 14111566Smitch.hayenga@arm.com if (interrupts[IT_INT_VEC]) { 14211566Smitch.hayenga@arm.com // this will be cleared by an ASI read (or write) 14311566Smitch.hayenga@arm.com return true; 14411566Smitch.hayenga@arm.com } 14511566Smitch.hayenga@arm.com } 14611566Smitch.hayenga@arm.com } else { 14711566Smitch.hayenga@arm.com if (interrupts[IT_TRAP_LEVEL_ZERO]) { 14811566Smitch.hayenga@arm.com // this is cleared by deasserting HPSTATE::tlz 14911566Smitch.hayenga@arm.com return true; 15011566Smitch.hayenga@arm.com } 15111566Smitch.hayenga@arm.com // HStick matches always happen in priv mode (ie doesn't matter) 15211566Smitch.hayenga@arm.com if (interrupts[IT_HINTP]) { 15311566Smitch.hayenga@arm.com return true; 15411566Smitch.hayenga@arm.com } 15511566Smitch.hayenga@arm.com if (interrupts[IT_INT_VEC]) { 15611566Smitch.hayenga@arm.com // this will be cleared by an ASI read (or write) 15711566Smitch.hayenga@arm.com return true; 15811566Smitch.hayenga@arm.com } 15911566Smitch.hayenga@arm.com if (pstate.ie) { 16011566Smitch.hayenga@arm.com if (interrupts[IT_CPU_MONDO]) { 16111566Smitch.hayenga@arm.com return true; 16211566Smitch.hayenga@arm.com } 16311566Smitch.hayenga@arm.com if (interrupts[IT_DEV_MONDO]) { 16411566Smitch.hayenga@arm.com return true; 16511566Smitch.hayenga@arm.com } 16611566Smitch.hayenga@arm.com if (interrupts[IT_SOFT_INT]) { 16711566Smitch.hayenga@arm.com return true; 16811566Smitch.hayenga@arm.com } 16911566Smitch.hayenga@arm.com 17011566Smitch.hayenga@arm.com if (interrupts[IT_RES_ERROR]) { 17111566Smitch.hayenga@arm.com return true; 17211566Smitch.hayenga@arm.com } 17311566Smitch.hayenga@arm.com } // !hpriv && pstate.ie 17411566Smitch.hayenga@arm.com } // !hpriv 17511566Smitch.hayenga@arm.com 17611566Smitch.hayenga@arm.com return false; 1774009Ssaidi@eecs.umich.edu } 1783537Sgblack@eecs.umich.edu 1795704Snate@binkert.org Fault 1805704Snate@binkert.org getInterrupt(ThreadContext *tc) 1814009Ssaidi@eecs.umich.edu { 18211566Smitch.hayenga@arm.com assert(checkInterrupts(tc)); 18311566Smitch.hayenga@arm.com 1848829Sgblack@eecs.umich.edu HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 1858829Sgblack@eecs.umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 1863827Shsul@eecs.umich.edu 1874009Ssaidi@eecs.umich.edu // THESE ARE IN ORDER OF PRIORITY 1884009Ssaidi@eecs.umich.edu // since there are early returns, and the highest 1894009Ssaidi@eecs.umich.edu // priority interrupts should get serviced, 1904009Ssaidi@eecs.umich.edu // it is v. important that new interrupts are inserted 1914009Ssaidi@eecs.umich.edu // in the right order of processing 1928829Sgblack@eecs.umich.edu if (hpstate.hpriv) { 1938829Sgblack@eecs.umich.edu if (pstate.ie) { 1944103Ssaidi@eecs.umich.edu if (interrupts[IT_HINTP]) { 1954103Ssaidi@eecs.umich.edu // This will be cleaned by a HINTP write 19610474Sandreas.hansson@arm.com return std::make_shared<HstickMatch>(); 1973894Shsul@eecs.umich.edu } 1984103Ssaidi@eecs.umich.edu if (interrupts[IT_INT_VEC]) { 1994103Ssaidi@eecs.umich.edu // this will be cleared by an ASI read (or write) 20010474Sandreas.hansson@arm.com return std::make_shared<InterruptVector>(); 2014009Ssaidi@eecs.umich.edu } 2024103Ssaidi@eecs.umich.edu } 2034103Ssaidi@eecs.umich.edu } else { 2044103Ssaidi@eecs.umich.edu if (interrupts[IT_TRAP_LEVEL_ZERO]) { 2054103Ssaidi@eecs.umich.edu // this is cleared by deasserting HPSTATE::tlz 20610474Sandreas.hansson@arm.com return std::make_shared<TrapLevelZero>(); 2074103Ssaidi@eecs.umich.edu } 2084103Ssaidi@eecs.umich.edu // HStick matches always happen in priv mode (ie doesn't matter) 2094103Ssaidi@eecs.umich.edu if (interrupts[IT_HINTP]) { 21010474Sandreas.hansson@arm.com return std::make_shared<HstickMatch>(); 2114103Ssaidi@eecs.umich.edu } 2124103Ssaidi@eecs.umich.edu if (interrupts[IT_INT_VEC]) { 2134103Ssaidi@eecs.umich.edu // this will be cleared by an ASI read (or write) 21410474Sandreas.hansson@arm.com return std::make_shared<InterruptVector>(); 2154103Ssaidi@eecs.umich.edu } 2168829Sgblack@eecs.umich.edu if (pstate.ie) { 2174103Ssaidi@eecs.umich.edu if (interrupts[IT_CPU_MONDO]) { 21810474Sandreas.hansson@arm.com return std::make_shared<CpuMondo>(); 2194103Ssaidi@eecs.umich.edu } 2204103Ssaidi@eecs.umich.edu if (interrupts[IT_DEV_MONDO]) { 22110474Sandreas.hansson@arm.com return std::make_shared<DevMondo>(); 2224103Ssaidi@eecs.umich.edu } 2234103Ssaidi@eecs.umich.edu if (interrupts[IT_SOFT_INT]) { 2245704Snate@binkert.org int level = InterruptLevel(interrupts[IT_SOFT_INT]); 22510474Sandreas.hansson@arm.com return std::make_shared<InterruptLevelN>(level); 2264009Ssaidi@eecs.umich.edu } 2274009Ssaidi@eecs.umich.edu 2284103Ssaidi@eecs.umich.edu if (interrupts[IT_RES_ERROR]) { 22910474Sandreas.hansson@arm.com return std::make_shared<ResumableError>(); 2303894Shsul@eecs.umich.edu } 2318829Sgblack@eecs.umich.edu } // !hpriv && pstate.ie 2324103Ssaidi@eecs.umich.edu } // !hpriv 2334009Ssaidi@eecs.umich.edu return NoFault; 2344009Ssaidi@eecs.umich.edu } 2353537Sgblack@eecs.umich.edu 2365704Snate@binkert.org void 2375704Snate@binkert.org updateIntrInfo(ThreadContext *tc) 2387741Sgblack@eecs.umich.edu {} 2393654Shsul@eecs.umich.edu 2405704Snate@binkert.org uint64_t 2415704Snate@binkert.org get_vec(int int_num) 2424103Ssaidi@eecs.umich.edu { 2434103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 2444103Ssaidi@eecs.umich.edu return interrupts[int_num]; 2454103Ssaidi@eecs.umich.edu } 2464103Ssaidi@eecs.umich.edu 2475704Snate@binkert.org void 24811168Sandreas.hansson@arm.com serialize(CheckpointOut &cp) const override 2494009Ssaidi@eecs.umich.edu { 2504103Ssaidi@eecs.umich.edu SERIALIZE_ARRAY(interrupts,NumInterruptTypes); 2514103Ssaidi@eecs.umich.edu SERIALIZE_SCALAR(intStatus); 2524009Ssaidi@eecs.umich.edu } 2533537Sgblack@eecs.umich.edu 2545704Snate@binkert.org void 25511168Sandreas.hansson@arm.com unserialize(CheckpointIn &cp) override 2564009Ssaidi@eecs.umich.edu { 2574103Ssaidi@eecs.umich.edu UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); 2584103Ssaidi@eecs.umich.edu UNSERIALIZE_SCALAR(intStatus); 2594009Ssaidi@eecs.umich.edu } 2604009Ssaidi@eecs.umich.edu}; 2614009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA 2623537Sgblack@eecs.umich.edu 2633537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__ 264