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 4613912Sgabeblack@google.comenum InterruptTypes 4713912Sgabeblack@google.com{ 4813912Sgabeblack@google.com IT_TRAP_LEVEL_ZERO, 4913912Sgabeblack@google.com IT_HINTP, 5013912Sgabeblack@google.com IT_INT_VEC, 5113912Sgabeblack@google.com IT_CPU_MONDO, 5213912Sgabeblack@google.com IT_DEV_MONDO, 5313912Sgabeblack@google.com IT_RES_ERROR, 5413912Sgabeblack@google.com IT_SOFT_INT, 5513912Sgabeblack@google.com NumInterruptTypes 5613912Sgabeblack@google.com}; 5713912Sgabeblack@google.com 585647Sgblack@eecs.umich.educlass Interrupts : public SimObject 594009Ssaidi@eecs.umich.edu{ 605810Sgblack@eecs.umich.edu private: 615810Sgblack@eecs.umich.edu BaseCPU * cpu; 624009Ssaidi@eecs.umich.edu 634103Ssaidi@eecs.umich.edu uint64_t interrupts[NumInterruptTypes]; 644103Ssaidi@eecs.umich.edu uint64_t intStatus; 654009Ssaidi@eecs.umich.edu 664009Ssaidi@eecs.umich.edu public: 675810Sgblack@eecs.umich.edu 685810Sgblack@eecs.umich.edu void 695810Sgblack@eecs.umich.edu setCPU(BaseCPU * _cpu) 705810Sgblack@eecs.umich.edu { 715810Sgblack@eecs.umich.edu cpu = _cpu; 725810Sgblack@eecs.umich.edu } 735810Sgblack@eecs.umich.edu 745647Sgblack@eecs.umich.edu typedef SparcInterruptsParams Params; 755647Sgblack@eecs.umich.edu 765647Sgblack@eecs.umich.edu const Params * 775647Sgblack@eecs.umich.edu params() const 785647Sgblack@eecs.umich.edu { 795647Sgblack@eecs.umich.edu return dynamic_cast<const Params *>(_params); 805647Sgblack@eecs.umich.edu } 815647Sgblack@eecs.umich.edu 825810Sgblack@eecs.umich.edu Interrupts(Params * p) : SimObject(p), cpu(NULL) 834009Ssaidi@eecs.umich.edu { 845704Snate@binkert.org clearAll(); 854009Ssaidi@eecs.umich.edu } 864009Ssaidi@eecs.umich.edu 875704Snate@binkert.org int 885704Snate@binkert.org InterruptLevel(uint64_t softint) 894009Ssaidi@eecs.umich.edu { 904103Ssaidi@eecs.umich.edu if (softint & 0x10000 || softint & 0x1) 914103Ssaidi@eecs.umich.edu return 14; 924103Ssaidi@eecs.umich.edu 934103Ssaidi@eecs.umich.edu int level = 15; 944103Ssaidi@eecs.umich.edu while (level > 0 && !(1 << level & softint)) 954103Ssaidi@eecs.umich.edu level--; 964103Ssaidi@eecs.umich.edu if (1 << level & softint) 974103Ssaidi@eecs.umich.edu return level; 984103Ssaidi@eecs.umich.edu return 0; 994009Ssaidi@eecs.umich.edu } 1004009Ssaidi@eecs.umich.edu 1015704Snate@binkert.org void 1025704Snate@binkert.org post(int int_num, int index) 1033537Sgblack@eecs.umich.edu { 1044103Ssaidi@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 1054103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 1064103Ssaidi@eecs.umich.edu assert(index >= 0 && index < 64); 1073827Shsul@eecs.umich.edu 1084103Ssaidi@eecs.umich.edu interrupts[int_num] |= ULL(1) << index; 1094103Ssaidi@eecs.umich.edu intStatus |= ULL(1) << int_num; 1104009Ssaidi@eecs.umich.edu } 1113894Shsul@eecs.umich.edu 1125704Snate@binkert.org void 1135704Snate@binkert.org clear(int int_num, int index) 1144009Ssaidi@eecs.umich.edu { 1154103Ssaidi@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1164103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 1174103Ssaidi@eecs.umich.edu assert(index >= 0 && index < 64); 1183537Sgblack@eecs.umich.edu 1194103Ssaidi@eecs.umich.edu interrupts[int_num] &= ~(ULL(1) << index); 1204103Ssaidi@eecs.umich.edu if (!interrupts[int_num]) 1214103Ssaidi@eecs.umich.edu intStatus &= ~(ULL(1) << int_num); 1224009Ssaidi@eecs.umich.edu } 1233827Shsul@eecs.umich.edu 1245704Snate@binkert.org void 1255704Snate@binkert.org clearAll() 1264009Ssaidi@eecs.umich.edu { 1274103Ssaidi@eecs.umich.edu for (int i = 0; i < NumInterruptTypes; ++i) { 1284103Ssaidi@eecs.umich.edu interrupts[i] = 0; 1294103Ssaidi@eecs.umich.edu } 1304103Ssaidi@eecs.umich.edu intStatus = 0; 1314009Ssaidi@eecs.umich.edu } 1323537Sgblack@eecs.umich.edu 1335704Snate@binkert.org bool 1345704Snate@binkert.org checkInterrupts(ThreadContext *tc) const 1354009Ssaidi@eecs.umich.edu { 13611566Smitch.hayenga@arm.com if (!intStatus) 13711566Smitch.hayenga@arm.com return false; 13811566Smitch.hayenga@arm.com 13911566Smitch.hayenga@arm.com HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 14011566Smitch.hayenga@arm.com PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 14111566Smitch.hayenga@arm.com 14211566Smitch.hayenga@arm.com // THESE ARE IN ORDER OF PRIORITY 14311566Smitch.hayenga@arm.com // since there are early returns, and the highest 14411566Smitch.hayenga@arm.com // priority interrupts should get serviced, 14511566Smitch.hayenga@arm.com // it is v. important that new interrupts are inserted 14611566Smitch.hayenga@arm.com // in the right order of processing 14711566Smitch.hayenga@arm.com if (hpstate.hpriv) { 14811566Smitch.hayenga@arm.com if (pstate.ie) { 14911566Smitch.hayenga@arm.com if (interrupts[IT_HINTP]) { 15011566Smitch.hayenga@arm.com // This will be cleaned by a HINTP write 15111566Smitch.hayenga@arm.com return true; 15211566Smitch.hayenga@arm.com } 15311566Smitch.hayenga@arm.com if (interrupts[IT_INT_VEC]) { 15411566Smitch.hayenga@arm.com // this will be cleared by an ASI read (or write) 15511566Smitch.hayenga@arm.com return true; 15611566Smitch.hayenga@arm.com } 15711566Smitch.hayenga@arm.com } 15811566Smitch.hayenga@arm.com } else { 15911566Smitch.hayenga@arm.com if (interrupts[IT_TRAP_LEVEL_ZERO]) { 16011566Smitch.hayenga@arm.com // this is cleared by deasserting HPSTATE::tlz 16111566Smitch.hayenga@arm.com return true; 16211566Smitch.hayenga@arm.com } 16311566Smitch.hayenga@arm.com // HStick matches always happen in priv mode (ie doesn't matter) 16411566Smitch.hayenga@arm.com if (interrupts[IT_HINTP]) { 16511566Smitch.hayenga@arm.com return true; 16611566Smitch.hayenga@arm.com } 16711566Smitch.hayenga@arm.com if (interrupts[IT_INT_VEC]) { 16811566Smitch.hayenga@arm.com // this will be cleared by an ASI read (or write) 16911566Smitch.hayenga@arm.com return true; 17011566Smitch.hayenga@arm.com } 17111566Smitch.hayenga@arm.com if (pstate.ie) { 17211566Smitch.hayenga@arm.com if (interrupts[IT_CPU_MONDO]) { 17311566Smitch.hayenga@arm.com return true; 17411566Smitch.hayenga@arm.com } 17511566Smitch.hayenga@arm.com if (interrupts[IT_DEV_MONDO]) { 17611566Smitch.hayenga@arm.com return true; 17711566Smitch.hayenga@arm.com } 17811566Smitch.hayenga@arm.com if (interrupts[IT_SOFT_INT]) { 17911566Smitch.hayenga@arm.com return true; 18011566Smitch.hayenga@arm.com } 18111566Smitch.hayenga@arm.com 18211566Smitch.hayenga@arm.com if (interrupts[IT_RES_ERROR]) { 18311566Smitch.hayenga@arm.com return true; 18411566Smitch.hayenga@arm.com } 18511566Smitch.hayenga@arm.com } // !hpriv && pstate.ie 18611566Smitch.hayenga@arm.com } // !hpriv 18711566Smitch.hayenga@arm.com 18811566Smitch.hayenga@arm.com return false; 1894009Ssaidi@eecs.umich.edu } 1903537Sgblack@eecs.umich.edu 1915704Snate@binkert.org Fault 1925704Snate@binkert.org getInterrupt(ThreadContext *tc) 1934009Ssaidi@eecs.umich.edu { 19411566Smitch.hayenga@arm.com assert(checkInterrupts(tc)); 19511566Smitch.hayenga@arm.com 1968829Sgblack@eecs.umich.edu HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 1978829Sgblack@eecs.umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 1983827Shsul@eecs.umich.edu 1994009Ssaidi@eecs.umich.edu // THESE ARE IN ORDER OF PRIORITY 2004009Ssaidi@eecs.umich.edu // since there are early returns, and the highest 2014009Ssaidi@eecs.umich.edu // priority interrupts should get serviced, 2024009Ssaidi@eecs.umich.edu // it is v. important that new interrupts are inserted 2034009Ssaidi@eecs.umich.edu // in the right order of processing 2048829Sgblack@eecs.umich.edu if (hpstate.hpriv) { 2058829Sgblack@eecs.umich.edu if (pstate.ie) { 2064103Ssaidi@eecs.umich.edu if (interrupts[IT_HINTP]) { 2074103Ssaidi@eecs.umich.edu // This will be cleaned by a HINTP write 20810474Sandreas.hansson@arm.com return std::make_shared<HstickMatch>(); 2093894Shsul@eecs.umich.edu } 2104103Ssaidi@eecs.umich.edu if (interrupts[IT_INT_VEC]) { 2114103Ssaidi@eecs.umich.edu // this will be cleared by an ASI read (or write) 21210474Sandreas.hansson@arm.com return std::make_shared<InterruptVector>(); 2134009Ssaidi@eecs.umich.edu } 2144103Ssaidi@eecs.umich.edu } 2154103Ssaidi@eecs.umich.edu } else { 2164103Ssaidi@eecs.umich.edu if (interrupts[IT_TRAP_LEVEL_ZERO]) { 2174103Ssaidi@eecs.umich.edu // this is cleared by deasserting HPSTATE::tlz 21810474Sandreas.hansson@arm.com return std::make_shared<TrapLevelZero>(); 2194103Ssaidi@eecs.umich.edu } 2204103Ssaidi@eecs.umich.edu // HStick matches always happen in priv mode (ie doesn't matter) 2214103Ssaidi@eecs.umich.edu if (interrupts[IT_HINTP]) { 22210474Sandreas.hansson@arm.com return std::make_shared<HstickMatch>(); 2234103Ssaidi@eecs.umich.edu } 2244103Ssaidi@eecs.umich.edu if (interrupts[IT_INT_VEC]) { 2254103Ssaidi@eecs.umich.edu // this will be cleared by an ASI read (or write) 22610474Sandreas.hansson@arm.com return std::make_shared<InterruptVector>(); 2274103Ssaidi@eecs.umich.edu } 2288829Sgblack@eecs.umich.edu if (pstate.ie) { 2294103Ssaidi@eecs.umich.edu if (interrupts[IT_CPU_MONDO]) { 23010474Sandreas.hansson@arm.com return std::make_shared<CpuMondo>(); 2314103Ssaidi@eecs.umich.edu } 2324103Ssaidi@eecs.umich.edu if (interrupts[IT_DEV_MONDO]) { 23310474Sandreas.hansson@arm.com return std::make_shared<DevMondo>(); 2344103Ssaidi@eecs.umich.edu } 2354103Ssaidi@eecs.umich.edu if (interrupts[IT_SOFT_INT]) { 2365704Snate@binkert.org int level = InterruptLevel(interrupts[IT_SOFT_INT]); 23710474Sandreas.hansson@arm.com return std::make_shared<InterruptLevelN>(level); 2384009Ssaidi@eecs.umich.edu } 2394009Ssaidi@eecs.umich.edu 2404103Ssaidi@eecs.umich.edu if (interrupts[IT_RES_ERROR]) { 24110474Sandreas.hansson@arm.com return std::make_shared<ResumableError>(); 2423894Shsul@eecs.umich.edu } 2438829Sgblack@eecs.umich.edu } // !hpriv && pstate.ie 2444103Ssaidi@eecs.umich.edu } // !hpriv 2454009Ssaidi@eecs.umich.edu return NoFault; 2464009Ssaidi@eecs.umich.edu } 2473537Sgblack@eecs.umich.edu 2485704Snate@binkert.org void 2495704Snate@binkert.org updateIntrInfo(ThreadContext *tc) 2507741Sgblack@eecs.umich.edu {} 2513654Shsul@eecs.umich.edu 2525704Snate@binkert.org uint64_t 2535704Snate@binkert.org get_vec(int int_num) 2544103Ssaidi@eecs.umich.edu { 2554103Ssaidi@eecs.umich.edu assert(int_num >= 0 && int_num < NumInterruptTypes); 2564103Ssaidi@eecs.umich.edu return interrupts[int_num]; 2574103Ssaidi@eecs.umich.edu } 2584103Ssaidi@eecs.umich.edu 2595704Snate@binkert.org void 26011168Sandreas.hansson@arm.com serialize(CheckpointOut &cp) const override 2614009Ssaidi@eecs.umich.edu { 2624103Ssaidi@eecs.umich.edu SERIALIZE_ARRAY(interrupts,NumInterruptTypes); 2634103Ssaidi@eecs.umich.edu SERIALIZE_SCALAR(intStatus); 2644009Ssaidi@eecs.umich.edu } 2653537Sgblack@eecs.umich.edu 2665704Snate@binkert.org void 26711168Sandreas.hansson@arm.com unserialize(CheckpointIn &cp) override 2684009Ssaidi@eecs.umich.edu { 2694103Ssaidi@eecs.umich.edu UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); 2704103Ssaidi@eecs.umich.edu UNSERIALIZE_SCALAR(intStatus); 2714009Ssaidi@eecs.umich.edu } 2724009Ssaidi@eecs.umich.edu}; 2734009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA 2743537Sgblack@eecs.umich.edu 2753537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__ 276