interrupts.cc revision 8745
15222Sksewell@umich.edu/* 25254Sksewell@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 35254Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc. 45254Sksewell@umich.edu * All rights reserved. 55222Sksewell@umich.edu * 65254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 75254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 85254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 95254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 105254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 115254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 125254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 135254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 145254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 155254Sksewell@umich.edu * this software without specific prior written permission. 165222Sksewell@umich.edu * 175254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285222Sksewell@umich.edu * 295254Sksewell@umich.edu * Authors: Steve Reinhardt 305254Sksewell@umich.edu * Kevin Lim 315254Sksewell@umich.edu * Korey Sewell 325222Sksewell@umich.edu */ 335222Sksewell@umich.edu 346379Sgblack@eecs.umich.edu#include "arch/mips/interrupts.hh" 356379Sgblack@eecs.umich.edu#include "arch/mips/isa_traits.hh" 365222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 376379Sgblack@eecs.umich.edu#include "base/trace.hh" 385222Sksewell@umich.edu#include "cpu/thread_context.hh" 398745Sgblack@eecs.umich.edu#include "debug/Interrupt.hh" 405222Sksewell@umich.edu 415222Sksewell@umich.edunamespace MipsISA 425222Sksewell@umich.edu{ 436378Sgblack@eecs.umich.edu 446378Sgblack@eecs.umich.edustatic inline uint8_t 456378Sgblack@eecs.umich.edugetCauseIP(ThreadContext *tc) { 466383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 476379Sgblack@eecs.umich.edu return cause.ip; 485222Sksewell@umich.edu} 495222Sksewell@umich.edu 506378Sgblack@eecs.umich.edustatic inline void 516379Sgblack@eecs.umich.edusetCauseIP(ThreadContext *tc, uint8_t val) { 526383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 536379Sgblack@eecs.umich.edu cause.ip = val; 546383Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 555222Sksewell@umich.edu} 565222Sksewell@umich.edu 576378Sgblack@eecs.umich.eduvoid 586378Sgblack@eecs.umich.eduInterrupts::post(int int_num, ThreadContext* tc) 595222Sksewell@umich.edu{ 605222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d posted\n", int_num); 615222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 625222Sksewell@umich.edu panic("int_num out of bounds\n"); 635222Sksewell@umich.edu 646378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 655222Sksewell@umich.edu intstatus |= 1 << int_num; 666378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 675222Sksewell@umich.edu} 685222Sksewell@umich.edu 696378Sgblack@eecs.umich.eduvoid 706378Sgblack@eecs.umich.eduInterrupts::post(int int_num, int index) 715222Sksewell@umich.edu{ 726378Sgblack@eecs.umich.edu fatal("Must use Thread Context when posting MIPS Interrupts in M5"); 735222Sksewell@umich.edu} 745222Sksewell@umich.edu 756378Sgblack@eecs.umich.eduvoid 766378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, ThreadContext* tc) 775222Sksewell@umich.edu{ 785222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num); 795222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 805222Sksewell@umich.edu panic("int_num out of bounds\n"); 815222Sksewell@umich.edu 826378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 835222Sksewell@umich.edu intstatus &= ~(1 << int_num); 846378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 855222Sksewell@umich.edu} 865222Sksewell@umich.edu 876378Sgblack@eecs.umich.eduvoid 886378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, int index) 895222Sksewell@umich.edu{ 906378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 915222Sksewell@umich.edu} 925222Sksewell@umich.edu 936378Sgblack@eecs.umich.eduvoid 946378Sgblack@eecs.umich.eduInterrupts::clearAll(ThreadContext *tc) 955222Sksewell@umich.edu{ 965222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts all cleared\n"); 975222Sksewell@umich.edu uint8_t intstatus = 0; 986378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 995222Sksewell@umich.edu} 1005222Sksewell@umich.edu 1016378Sgblack@eecs.umich.eduvoid 1026378Sgblack@eecs.umich.eduInterrupts::clearAll() 1035222Sksewell@umich.edu{ 1046378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 1055222Sksewell@umich.edu} 1065222Sksewell@umich.edu 1075222Sksewell@umich.edu 1085222Sksewell@umich.edu 1096378Sgblack@eecs.umich.eduFault 1106378Sgblack@eecs.umich.eduInterrupts::getInterrupt(ThreadContext * tc) 1115222Sksewell@umich.edu{ 1125222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts getInterrupt\n"); 1135222Sksewell@umich.edu 1145222Sksewell@umich.edu //Check if there are any outstanding interrupts 1156383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 1166378Sgblack@eecs.umich.edu // Interrupts must be enabled, error level must be 0 or interrupts 1176378Sgblack@eecs.umich.edu // inhibited, and exception level must be 0 or interrupts inhibited 1186379Sgblack@eecs.umich.edu if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) { 1195222Sksewell@umich.edu // Software interrupts & hardware interrupts are handled in software. 1205222Sksewell@umich.edu // So if any interrupt that isn't masked is detected, jump to interrupt 1215222Sksewell@umich.edu // handler 1226383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 1236379Sgblack@eecs.umich.edu if (status.im && cause.ip) { 1245222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", 1256379Sgblack@eecs.umich.edu (unsigned)status.im, (unsigned)cause.ip); 1265222Sksewell@umich.edu return new InterruptFault; 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu } 1295222Sksewell@umich.edu 1305222Sksewell@umich.edu return NoFault; 1316378Sgblack@eecs.umich.edu} 1325222Sksewell@umich.edu 1336378Sgblack@eecs.umich.edubool 1346378Sgblack@eecs.umich.eduInterrupts::onCpuTimerInterrupt(ThreadContext * tc) const 1355222Sksewell@umich.edu{ 1366383Sgblack@eecs.umich.edu MiscReg compare = tc->readMiscRegNoEffect(MISCREG_COMPARE); 1376383Sgblack@eecs.umich.edu MiscReg count = tc->readMiscRegNoEffect(MISCREG_COUNT); 1385222Sksewell@umich.edu if (compare == count && count != 0) 1395222Sksewell@umich.edu return true; 1405222Sksewell@umich.edu return false; 1415222Sksewell@umich.edu} 1426378Sgblack@eecs.umich.edu 1436378Sgblack@eecs.umich.eduvoid 1446378Sgblack@eecs.umich.eduInterrupts::updateIntrInfo(ThreadContext *tc) const 1455222Sksewell@umich.edu{ 1465222Sksewell@umich.edu //Nothing needs to be done. 1475222Sksewell@umich.edu} 1485222Sksewell@umich.edu 1496378Sgblack@eecs.umich.edubool 1506378Sgblack@eecs.umich.eduInterrupts::interruptsPending(ThreadContext *tc) const 1515222Sksewell@umich.edu{ 1525222Sksewell@umich.edu //if there is a on cpu timer interrupt (i.e. Compare == Count) 1535222Sksewell@umich.edu //update CauseIP before proceeding to interrupt 1546378Sgblack@eecs.umich.edu if (onCpuTimerInterrupt(tc)) { 1556378Sgblack@eecs.umich.edu DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); 1565222Sksewell@umich.edu //determine timer interrupt IP # 1576383Sgblack@eecs.umich.edu IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL); 1586379Sgblack@eecs.umich.edu uint8_t intStatus = getCauseIP(tc); 1596379Sgblack@eecs.umich.edu intStatus |= 1 << intCtl.ipti; 1606379Sgblack@eecs.umich.edu setCauseIP(tc, intStatus); 1615222Sksewell@umich.edu } 1625222Sksewell@umich.edu 1636378Sgblack@eecs.umich.edu return (getCauseIP(tc) != 0); 1645222Sksewell@umich.edu 1655222Sksewell@umich.edu} 1665222Sksewell@umich.edu 1675222Sksewell@umich.edu} 1686379Sgblack@eecs.umich.edu 1696379Sgblack@eecs.umich.eduMipsISA::Interrupts * 1706379Sgblack@eecs.umich.eduMipsInterruptsParams::create() 1716379Sgblack@eecs.umich.edu{ 1726379Sgblack@eecs.umich.edu return new MipsISA::Interrupts(this); 1736379Sgblack@eecs.umich.edu} 174