interrupts.hh revision 5810
12SN/A/* 21762SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 292665Ssaidi@eecs.umich.edu * Kevin Lim 302SN/A */ 312SN/A 322SN/A#ifndef __ARCH_ALPHA_INTERRUPT_HH__ 332SN/A#define __ARCH_ALPHA_INTERRUPT_HH__ 342SN/A 352SN/A#include "arch/alpha/faults.hh" 361354SN/A#include "arch/alpha/isa_traits.hh" 371354SN/A#include "base/compiler.hh" 382SN/A#include "base/trace.hh" 392SN/A#include "cpu/thread_context.hh" 405501Snate@binkert.org#include "params/AlphaInterrupts.hh" 415546Snate@binkert.org#include "sim/sim_object.hh" 427004Snate@binkert.org 432SN/Anamespace AlphaISA { 442SN/A 4556SN/Aclass Interrupts : public SimObject 465769Snate@binkert.org{ 472361SN/A private: 481354SN/A bool newInfoSet; 496216Snate@binkert.org int newIpl; 5056SN/A int newSummary; 512SN/A BaseCPU * cpu; 525543Ssaidi@eecs.umich.edu 532SN/A protected: 541354SN/A uint64_t interrupts[NumInterruptLevels]; 551354SN/A uint64_t intstatus; 562SN/A 572SN/A public: 582SN/A typedef AlphaInterruptsParams Params; 592SN/A 605501Snate@binkert.org const Params * 615501Snate@binkert.org params() const 622SN/A { 63395SN/A return dynamic_cast<const Params *>(_params); 642SN/A } 652SN/A 662SN/A Interrupts(Params * p) : SimObject(p), cpu(NULL) 675769Snate@binkert.org { 685769Snate@binkert.org memset(interrupts, 0, sizeof(interrupts)); 695769Snate@binkert.org intstatus = 0; 705769Snate@binkert.org newInfoSet = false; 715769Snate@binkert.org } 725769Snate@binkert.org 735769Snate@binkert.org void 745769Snate@binkert.org setCPU(BaseCPU * _cpu) 755769Snate@binkert.org { 765769Snate@binkert.org cpu = _cpu; 775769Snate@binkert.org } 785769Snate@binkert.org 795774Snate@binkert.org void 805774Snate@binkert.org post(int int_num, int index) 815774Snate@binkert.org { 825769Snate@binkert.org DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 832SN/A 845502Snate@binkert.org if (int_num < 0 || int_num >= NumInterruptLevels) 855502Snate@binkert.org panic("int_num out of bounds\n"); 865502Snate@binkert.org 875503Snate@binkert.org if (index < 0 || index >= (int)sizeof(uint64_t) * 8) 885503Snate@binkert.org panic("int_num out of bounds\n"); 895502Snate@binkert.org 905502Snate@binkert.org interrupts[int_num] |= 1 << index; 915502Snate@binkert.org intstatus |= (ULL(1) << int_num); 925502Snate@binkert.org } 935502Snate@binkert.org 945502Snate@binkert.org void 955502Snate@binkert.org clear(int int_num, int index) 965602Snate@binkert.org { 975602Snate@binkert.org DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 985501Snate@binkert.org 995543Ssaidi@eecs.umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 1005543Ssaidi@eecs.umich.edu panic("int_num out of bounds\n"); 1015769Snate@binkert.org 1024016Sstever@eecs.umich.edu if (index < 0 || index >= (int)sizeof(uint64_t) * 8) 1034016Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 1044016Sstever@eecs.umich.edu 1054016Sstever@eecs.umich.edu interrupts[int_num] &= ~(1 << index); 1064016Sstever@eecs.umich.edu if (interrupts[int_num] == 0) 1074016Sstever@eecs.umich.edu intstatus &= ~(ULL(1) << int_num); 1084016Sstever@eecs.umich.edu } 1094016Sstever@eecs.umich.edu 1104016Sstever@eecs.umich.edu void 1115501Snate@binkert.org clearAll() 1125605Snate@binkert.org { 1135605Snate@binkert.org DPRINTF(Interrupt, "Interrupts all cleared\n"); 1145605Snate@binkert.org 1155605Snate@binkert.org memset(interrupts, 0, sizeof(interrupts)); 1165501Snate@binkert.org intstatus = 0; 1174016Sstever@eecs.umich.edu } 1185577SSteve.Reinhardt@amd.com 1195501Snate@binkert.org void 1205501Snate@binkert.org serialize(std::ostream &os) 1215501Snate@binkert.org { 1225502Snate@binkert.org SERIALIZE_ARRAY(interrupts, NumInterruptLevels); 1235502Snate@binkert.org SERIALIZE_SCALAR(intstatus); 1245605Snate@binkert.org } 1255502Snate@binkert.org 1265502Snate@binkert.org void 1275605Snate@binkert.org unserialize(Checkpoint *cp, const std::string §ion) 1285605Snate@binkert.org { 1295605Snate@binkert.org UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); 1305577SSteve.Reinhardt@amd.com UNSERIALIZE_SCALAR(intstatus); 1315502Snate@binkert.org } 1325502Snate@binkert.org 1335502Snate@binkert.org bool 1345502Snate@binkert.org checkInterrupts(ThreadContext *tc) const 1352SN/A { 1365769Snate@binkert.org return (intstatus != 0) && !(tc->readPC() & 0x3); 1375769Snate@binkert.org } 1385769Snate@binkert.org 1395769Snate@binkert.org Fault 1405769Snate@binkert.org getInterrupt(ThreadContext *tc) 1415769Snate@binkert.org { 1422SN/A int ipl = 0; 1435769Snate@binkert.org int summary = 0; 1445769Snate@binkert.org 1455769Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_ASTRR)) 1465769Snate@binkert.org panic("asynchronous traps not implemented\n"); 1475769Snate@binkert.org 1485769Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_SIRR)) { 1492SN/A for (int i = INTLEVEL_SOFTWARE_MIN; 1505769Snate@binkert.org i < INTLEVEL_SOFTWARE_MAX; i++) { 1515769Snate@binkert.org if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { 1525769Snate@binkert.org // See table 4-19 of 21164 hardware reference 1535769Snate@binkert.org ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 1545769Snate@binkert.org summary |= (ULL(1) << i); 1555769Snate@binkert.org } 1565769Snate@binkert.org } 1575769Snate@binkert.org } 1585769Snate@binkert.org 1595769Snate@binkert.org uint64_t interrupts = intstatus; 1605769Snate@binkert.org if (interrupts) { 1615769Snate@binkert.org for (int i = INTLEVEL_EXTERNAL_MIN; 1625769Snate@binkert.org i < INTLEVEL_EXTERNAL_MAX; i++) { 1635769Snate@binkert.org if (interrupts & (ULL(1) << i)) { 1645769Snate@binkert.org // See table 4-19 of 21164 hardware reference 1655769Snate@binkert.org ipl = i; 1665769Snate@binkert.org summary |= (ULL(1) << i); 1675769Snate@binkert.org } 1685769Snate@binkert.org } 1695769Snate@binkert.org } 1705769Snate@binkert.org 1715769Snate@binkert.org if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { 1725769Snate@binkert.org newIpl = ipl; 1735769Snate@binkert.org newSummary = summary; 1745769Snate@binkert.org newInfoSet = true; 1755769Snate@binkert.org DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 1765769Snate@binkert.org tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); 1775769Snate@binkert.org 1785501Snate@binkert.org return new InterruptFault; 1795543Ssaidi@eecs.umich.edu } else { 1802SN/A return NoFault; 1812SN/A } 182396SN/A } 183396SN/A 184396SN/A void 185396SN/A updateIntrInfo(ThreadContext *tc) 186396SN/A { 1875501Snate@binkert.org assert(newInfoSet); 1885543Ssaidi@eecs.umich.edu tc->setMiscRegNoEffect(IPR_ISR, newSummary); 1895501Snate@binkert.org tc->setMiscRegNoEffect(IPR_INTID, newIpl); 1903329Sstever@eecs.umich.edu newInfoSet = false; 1913329Sstever@eecs.umich.edu } 1923329Sstever@eecs.umich.edu}; 1933329Sstever@eecs.umich.edu 1943329Sstever@eecs.umich.edu} // namespace AlphaISA 1953329Sstever@eecs.umich.edu 1963329Sstever@eecs.umich.edu#endif // __ARCH_ALPHA_INTERRUPT_HH__ 1973329Sstever@eecs.umich.edu 1985543Ssaidi@eecs.umich.edu