interrupts.hh revision 3827
12810SN/A/* 22810SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32810SN/A * All rights reserved. 42810SN/A * 52810SN/A * Redistribution and use in source and binary forms, with or without 62810SN/A * modification, are permitted provided that the following conditions are 72810SN/A * met: redistributions of source code must retain the above copyright 82810SN/A * notice, this list of conditions and the following disclaimer; 92810SN/A * redistributions in binary form must reproduce the above copyright 102810SN/A * notice, this list of conditions and the following disclaimer in the 112810SN/A * documentation and/or other materials provided with the distribution; 122810SN/A * neither the name of the copyright holders nor the names of its 132810SN/A * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A * 282810SN/A * Authors: Steve Reinhardt 294458SN/A * Kevin Lim 304458SN/A */ 312810SN/A 322810SN/A#ifndef __ARCH_ALPHA_INTERRUPT_HH__ 332810SN/A#define __ARCH_ALPHA_INTERRUPT_HH__ 342810SN/A 352810SN/A#include "arch/alpha/faults.hh" 362810SN/A#include "arch/alpha/isa_traits.hh" 372810SN/A#include "cpu/thread_context.hh" 382810SN/A 392810SN/Anamespace AlphaISA 402810SN/A{ 417676Snate@binkert.org class Interrupts 427676Snate@binkert.org { 437676Snate@binkert.org protected: 442810SN/A uint64_t interrupts[NumInterruptLevels]; 452810SN/A uint64_t intstatus; 462825SN/A 472810SN/A public: 482810SN/A Interrupts() 496215Snate@binkert.org { 508232Snate@binkert.org memset(interrupts, 0, sizeof(interrupts)); 518232Snate@binkert.org intstatus = 0; 525338Sstever@gmail.com newInfoSet = false; 532810SN/A } 542810SN/A 558229Snate@binkert.org void post(int int_num, int index) 564626SN/A { 575034SN/A DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 582811SN/A 598786Sgblack@eecs.umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 604626SN/A panic("int_num out of bounds\n"); 618833Sdam.sunwoo@arm.com 622810SN/A if (index < 0 || index >= sizeof(uint64_t) * 8) 633194SN/A panic("int_num out of bounds\n"); 642810SN/A 652810SN/A interrupts[int_num] |= 1 << index; 662810SN/A intstatus |= (ULL(1) << int_num); 672810SN/A } 682810SN/A 694628SN/A void clear(int int_num, int index) 704628SN/A { 714628SN/A DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 724628SN/A 734628SN/A if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 744628SN/A panic("int_num out of bounds\n"); 754628SN/A 764628SN/A if (index < 0 || index >= sizeof(uint64_t) * 8) 778737Skoansin.tan@gmail.com panic("int_num out of bounds\n"); 784628SN/A 794628SN/A interrupts[int_num] &= ~(1 << index); 804628SN/A if (interrupts[int_num] == 0) 814628SN/A intstatus &= ~(ULL(1) << int_num); 824628SN/A } 834628SN/A 844628SN/A void clear_all() 854628SN/A { 864628SN/A DPRINTF(Interrupt, "Interrupts all cleared\n"); 874628SN/A 884628SN/A memset(interrupts, 0, sizeof(interrupts)); 894628SN/A intstatus = 0; 904628SN/A } 914628SN/A 924628SN/A void serialize(std::ostream &os) 934628SN/A { 944628SN/A SERIALIZE_ARRAY(interrupts, NumInterruptLevels); 954628SN/A SERIALIZE_SCALAR(intstatus); 964628SN/A } 974628SN/A 988737Skoansin.tan@gmail.com void unserialize(Checkpoint *cp, const std::string §ion) 994628SN/A { 1004626SN/A UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); 1012810SN/A UNSERIALIZE_SCALAR(intstatus); 1022844SN/A } 1032810SN/A 1042810SN/A bool check_interrupts(ThreadContext * tc) const 1053738SN/A { 1064965SN/A return (intstatus != 0) && !(tc->readPC() & 0x3); 1076122SSteve.Reinhardt@amd.com } 1084458SN/A 1096227Snate@binkert.org Fault getInterrupt(ThreadContext * tc) 1102810SN/A { 1114458SN/A int ipl = 0; 1123013SN/A int summary = 0; 1134666SN/A 1144666SN/A if (tc->readMiscReg(IPR_ASTRR)) 1154666SN/A panic("asynchronous traps not implemented\n"); 1165314SN/A 1175314SN/A if (tc->readMiscReg(IPR_SIRR)) { 1182811SN/A for (int i = INTLEVEL_SOFTWARE_MIN; 1192810SN/A i < INTLEVEL_SOFTWARE_MAX; i++) { 1202810SN/A if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { 1212810SN/A // See table 4-19 of 21164 hardware reference 1222810SN/A ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 1235314SN/A summary |= (ULL(1) << i); 1243606SN/A } 1252810SN/A } 1262810SN/A } 1272897SN/A 1282897SN/A uint64_t interrupts = intstatus; 1294458SN/A if (interrupts) { 1304458SN/A for (int i = INTLEVEL_EXTERNAL_MIN; 1314888SN/A i < INTLEVEL_EXTERNAL_MAX; i++) { 1324666SN/A if (interrupts & (ULL(1) << i)) { 1334666SN/A // See table 4-19 of 21164 hardware reference 1344458SN/A ipl = i; 1354458SN/A summary |= (ULL(1) << i); 1364458SN/A } 1374626SN/A } 1384626SN/A } 1394626SN/A 1402811SN/A if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) { 1412810SN/A newIpl = ipl; 1423338SN/A newSummary = summary; 1433738SN/A newInfoSet = true; 1443338SN/A DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 1454626SN/A tc->readMiscReg(IPR_IPLR), ipl, summary); 1464626SN/A 1474626SN/A return new InterruptFault; 1484626SN/A } else { 1494626SN/A return NoFault; 1504626SN/A } 1514626SN/A } 1524626SN/A 1534628SN/A void updateIntrInfo(ThreadContext *tc) 1544628SN/A { 1554628SN/A assert(newInfoSet); 1564666SN/A tc->setMiscReg(IPR_ISR, newSummary); 1574628SN/A tc->setMiscReg(IPR_INTID, newIpl); 1584628SN/A newInfoSet = false; 1594628SN/A } 1604628SN/A 1614628SN/A private: 1624628SN/A bool newInfoSet; 1634628SN/A int newIpl; 1644628SN/A int newSummary; 1654628SN/A }; 1664628SN/A} 1674628SN/A 1684628SN/A#endif 1697667Ssteve.reinhardt@amd.com 1704628SN/A