13520Sgblack@eecs.umich.edu/* 23520Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 33520Sgblack@eecs.umich.edu * All rights reserved. 43520Sgblack@eecs.umich.edu * 53520Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 63520Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 73520Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 83520Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 93520Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 103520Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 113520Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 123520Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 133520Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 143520Sgblack@eecs.umich.edu * this software without specific prior written permission. 153520Sgblack@eecs.umich.edu * 163520Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173520Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183520Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193520Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203520Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213520Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223520Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233520Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243520Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253520Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263520Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273520Sgblack@eecs.umich.edu * 283520Sgblack@eecs.umich.edu * Authors: Steve Reinhardt 293520Sgblack@eecs.umich.edu * Kevin Lim 303520Sgblack@eecs.umich.edu */ 313520Sgblack@eecs.umich.edu 323520Sgblack@eecs.umich.edu#ifndef __ARCH_ALPHA_INTERRUPT_HH__ 333520Sgblack@eecs.umich.edu#define __ARCH_ALPHA_INTERRUPT_HH__ 343520Sgblack@eecs.umich.edu 3510474Sandreas.hansson@arm.com#include <memory> 3610474Sandreas.hansson@arm.com 373520Sgblack@eecs.umich.edu#include "arch/alpha/faults.hh" 383520Sgblack@eecs.umich.edu#include "arch/alpha/isa_traits.hh" 394103Ssaidi@eecs.umich.edu#include "base/compiler.hh" 405647Sgblack@eecs.umich.edu#include "base/trace.hh" 413520Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 428232Snate@binkert.org#include "debug/Flow.hh" 438232Snate@binkert.org#include "debug/Interrupt.hh" 445647Sgblack@eecs.umich.edu#include "params/AlphaInterrupts.hh" 455647Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 463520Sgblack@eecs.umich.edu 475565Snate@binkert.orgnamespace AlphaISA { 485565Snate@binkert.org 495647Sgblack@eecs.umich.educlass Interrupts : public SimObject 503520Sgblack@eecs.umich.edu{ 515565Snate@binkert.org private: 525565Snate@binkert.org bool newInfoSet; 535565Snate@binkert.org int newIpl; 545565Snate@binkert.org int newSummary; 555810Sgblack@eecs.umich.edu BaseCPU * cpu; 565565Snate@binkert.org 575565Snate@binkert.org protected: 585565Snate@binkert.org uint64_t interrupts[NumInterruptLevels]; 595565Snate@binkert.org uint64_t intstatus; 605565Snate@binkert.org 615565Snate@binkert.org public: 625647Sgblack@eecs.umich.edu typedef AlphaInterruptsParams 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) 713520Sgblack@eecs.umich.edu { 725565Snate@binkert.org memset(interrupts, 0, sizeof(interrupts)); 735565Snate@binkert.org intstatus = 0; 745565Snate@binkert.org newInfoSet = false; 755565Snate@binkert.org } 763520Sgblack@eecs.umich.edu 775565Snate@binkert.org void 785810Sgblack@eecs.umich.edu setCPU(BaseCPU * _cpu) 795810Sgblack@eecs.umich.edu { 805810Sgblack@eecs.umich.edu cpu = _cpu; 815810Sgblack@eecs.umich.edu } 825810Sgblack@eecs.umich.edu 835810Sgblack@eecs.umich.edu void 845565Snate@binkert.org post(int int_num, int index) 855565Snate@binkert.org { 865565Snate@binkert.org DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 873520Sgblack@eecs.umich.edu 885565Snate@binkert.org if (int_num < 0 || int_num >= NumInterruptLevels) 895565Snate@binkert.org panic("int_num out of bounds\n"); 903520Sgblack@eecs.umich.edu 915565Snate@binkert.org if (index < 0 || index >= (int)sizeof(uint64_t) * 8) 925565Snate@binkert.org panic("int_num out of bounds\n"); 933520Sgblack@eecs.umich.edu 945565Snate@binkert.org interrupts[int_num] |= 1 << index; 955565Snate@binkert.org intstatus |= (ULL(1) << int_num); 965565Snate@binkert.org } 973520Sgblack@eecs.umich.edu 985565Snate@binkert.org void 995565Snate@binkert.org clear(int int_num, int index) 1005565Snate@binkert.org { 1015565Snate@binkert.org DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1023520Sgblack@eecs.umich.edu 1035568Snate@binkert.org if (int_num < 0 || int_num >= NumInterruptLevels) 1045565Snate@binkert.org panic("int_num out of bounds\n"); 1053520Sgblack@eecs.umich.edu 1065565Snate@binkert.org if (index < 0 || index >= (int)sizeof(uint64_t) * 8) 1075565Snate@binkert.org panic("int_num out of bounds\n"); 1083520Sgblack@eecs.umich.edu 1095565Snate@binkert.org interrupts[int_num] &= ~(1 << index); 1105565Snate@binkert.org if (interrupts[int_num] == 0) 1115565Snate@binkert.org intstatus &= ~(ULL(1) << int_num); 1125565Snate@binkert.org } 1133520Sgblack@eecs.umich.edu 1145565Snate@binkert.org void 1155704Snate@binkert.org clearAll() 1165565Snate@binkert.org { 1175565Snate@binkert.org DPRINTF(Interrupt, "Interrupts all cleared\n"); 1183520Sgblack@eecs.umich.edu 1195565Snate@binkert.org memset(interrupts, 0, sizeof(interrupts)); 1205565Snate@binkert.org intstatus = 0; 1215565Snate@binkert.org } 1223520Sgblack@eecs.umich.edu 1235565Snate@binkert.org void 12410905Sandreas.sandberg@arm.com serialize(CheckpointOut &cp) const 1255565Snate@binkert.org { 1265565Snate@binkert.org SERIALIZE_ARRAY(interrupts, NumInterruptLevels); 1275565Snate@binkert.org SERIALIZE_SCALAR(intstatus); 1285565Snate@binkert.org } 1293520Sgblack@eecs.umich.edu 1305565Snate@binkert.org void 13110905Sandreas.sandberg@arm.com unserialize(CheckpointIn &cp) 1325565Snate@binkert.org { 1335565Snate@binkert.org UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); 1345565Snate@binkert.org UNSERIALIZE_SCALAR(intstatus); 1355565Snate@binkert.org } 1363520Sgblack@eecs.umich.edu 1375565Snate@binkert.org bool 1385704Snate@binkert.org checkInterrupts(ThreadContext *tc) const 1395565Snate@binkert.org { 14011566Smitch.hayenga@arm.com if (intstatus == 0) 14111566Smitch.hayenga@arm.com return false; 1423520Sgblack@eecs.umich.edu 14311566Smitch.hayenga@arm.com if (tc->pcState().pc() & 0x3) 14411566Smitch.hayenga@arm.com return false; 1453521Sgblack@eecs.umich.edu 1465565Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_ASTRR)) 1475565Snate@binkert.org panic("asynchronous traps not implemented\n"); 1483520Sgblack@eecs.umich.edu 14911566Smitch.hayenga@arm.com uint64_t ipl = 0; 15011566Smitch.hayenga@arm.com uint64_t summary = 0; 15111566Smitch.hayenga@arm.com 1525565Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_SIRR)) { 1536227Snate@binkert.org for (uint64_t i = INTLEVEL_SOFTWARE_MIN; 1545565Snate@binkert.org i < INTLEVEL_SOFTWARE_MAX; i++) { 1555565Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { 1565565Snate@binkert.org // See table 4-19 of 21164 hardware reference 1575565Snate@binkert.org ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 1585565Snate@binkert.org summary |= (ULL(1) << i); 1593520Sgblack@eecs.umich.edu } 1603520Sgblack@eecs.umich.edu } 1613520Sgblack@eecs.umich.edu } 1623520Sgblack@eecs.umich.edu 16311566Smitch.hayenga@arm.com for (uint64_t i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; 16411566Smitch.hayenga@arm.com i++) { 16511566Smitch.hayenga@arm.com if (intstatus & (ULL(1) << i)) { 16611566Smitch.hayenga@arm.com // See table 4-19 of 21164 hardware reference 16711566Smitch.hayenga@arm.com ipl = i; 16811566Smitch.hayenga@arm.com summary |= (ULL(1) << i); 16911566Smitch.hayenga@arm.com } 17011566Smitch.hayenga@arm.com } 17111566Smitch.hayenga@arm.com 17211566Smitch.hayenga@arm.com return ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR); 17311566Smitch.hayenga@arm.com } 17411566Smitch.hayenga@arm.com 17511566Smitch.hayenga@arm.com Fault 17611566Smitch.hayenga@arm.com getInterrupt(ThreadContext *tc) 17711566Smitch.hayenga@arm.com { 17811566Smitch.hayenga@arm.com assert(checkInterrupts(tc)); 17911566Smitch.hayenga@arm.com 18011566Smitch.hayenga@arm.com uint64_t ipl = 0; 18111566Smitch.hayenga@arm.com uint64_t summary = 0; 18211566Smitch.hayenga@arm.com if (tc->readMiscRegNoEffect(IPR_SIRR)) { 18311566Smitch.hayenga@arm.com for (uint64_t i = INTLEVEL_SOFTWARE_MIN; 18411566Smitch.hayenga@arm.com i < INTLEVEL_SOFTWARE_MAX; i++) { 18511566Smitch.hayenga@arm.com if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { 1865565Snate@binkert.org // See table 4-19 of 21164 hardware reference 18711566Smitch.hayenga@arm.com ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 1885565Snate@binkert.org summary |= (ULL(1) << i); 1895565Snate@binkert.org } 1905565Snate@binkert.org } 1913633Sktlim@umich.edu } 1923633Sktlim@umich.edu 19311566Smitch.hayenga@arm.com for (uint64_t i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; 19411566Smitch.hayenga@arm.com i++) { 19511566Smitch.hayenga@arm.com if (intstatus & (ULL(1) << i)) { 19611566Smitch.hayenga@arm.com // See table 4-19 of 21164 hardware reference 19711566Smitch.hayenga@arm.com ipl = i; 19811566Smitch.hayenga@arm.com summary |= (ULL(1) << i); 19911566Smitch.hayenga@arm.com } 20011566Smitch.hayenga@arm.com } 2015565Snate@binkert.org 20211566Smitch.hayenga@arm.com newIpl = ipl; 20311566Smitch.hayenga@arm.com newSummary = summary; 20411566Smitch.hayenga@arm.com newInfoSet = true; 20511566Smitch.hayenga@arm.com DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 20611566Smitch.hayenga@arm.com tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); 20711566Smitch.hayenga@arm.com 20811566Smitch.hayenga@arm.com return std::make_shared<InterruptFault>(); 2095565Snate@binkert.org } 2104103Ssaidi@eecs.umich.edu 2115565Snate@binkert.org void 2125565Snate@binkert.org updateIntrInfo(ThreadContext *tc) 2135565Snate@binkert.org { 2145565Snate@binkert.org assert(newInfoSet); 2155565Snate@binkert.org tc->setMiscRegNoEffect(IPR_ISR, newSummary); 2165565Snate@binkert.org tc->setMiscRegNoEffect(IPR_INTID, newIpl); 2175565Snate@binkert.org newInfoSet = false; 2185565Snate@binkert.org } 2195565Snate@binkert.org}; 2203520Sgblack@eecs.umich.edu 2215565Snate@binkert.org} // namespace AlphaISA 2225565Snate@binkert.org 2235565Snate@binkert.org#endif // __ARCH_ALPHA_INTERRUPT_HH__ 2245565Snate@binkert.org 225