interrupts.cc revision 7902
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" 395222Sksewell@umich.edu 405222Sksewell@umich.edunamespace MipsISA 415222Sksewell@umich.edu{ 426378Sgblack@eecs.umich.edu 436378Sgblack@eecs.umich.edustatic inline uint8_t 446378Sgblack@eecs.umich.edugetCauseIP(ThreadContext *tc) { 456383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 466379Sgblack@eecs.umich.edu return cause.ip; 475222Sksewell@umich.edu} 485222Sksewell@umich.edu 496378Sgblack@eecs.umich.edustatic inline void 506379Sgblack@eecs.umich.edusetCauseIP(ThreadContext *tc, uint8_t val) { 516383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 526379Sgblack@eecs.umich.edu cause.ip = val; 536383Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 545222Sksewell@umich.edu} 555222Sksewell@umich.edu 566378Sgblack@eecs.umich.eduvoid 576378Sgblack@eecs.umich.eduInterrupts::post(int int_num, ThreadContext* tc) 585222Sksewell@umich.edu{ 595222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d posted\n", int_num); 605222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 615222Sksewell@umich.edu panic("int_num out of bounds\n"); 625222Sksewell@umich.edu 636378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 645222Sksewell@umich.edu intstatus |= 1 << int_num; 656378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 665222Sksewell@umich.edu} 675222Sksewell@umich.edu 686378Sgblack@eecs.umich.eduvoid 696378Sgblack@eecs.umich.eduInterrupts::post(int int_num, int index) 705222Sksewell@umich.edu{ 716378Sgblack@eecs.umich.edu fatal("Must use Thread Context when posting MIPS Interrupts in M5"); 725222Sksewell@umich.edu} 735222Sksewell@umich.edu 746378Sgblack@eecs.umich.eduvoid 756378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, ThreadContext* tc) 765222Sksewell@umich.edu{ 775222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num); 785222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 795222Sksewell@umich.edu panic("int_num out of bounds\n"); 805222Sksewell@umich.edu 816378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 825222Sksewell@umich.edu intstatus &= ~(1 << int_num); 836378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 845222Sksewell@umich.edu} 855222Sksewell@umich.edu 866378Sgblack@eecs.umich.eduvoid 876378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, int index) 885222Sksewell@umich.edu{ 896378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 905222Sksewell@umich.edu} 915222Sksewell@umich.edu 926378Sgblack@eecs.umich.eduvoid 936378Sgblack@eecs.umich.eduInterrupts::clearAll(ThreadContext *tc) 945222Sksewell@umich.edu{ 955222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts all cleared\n"); 965222Sksewell@umich.edu uint8_t intstatus = 0; 976378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 985222Sksewell@umich.edu} 995222Sksewell@umich.edu 1006378Sgblack@eecs.umich.eduvoid 1016378Sgblack@eecs.umich.eduInterrupts::clearAll() 1025222Sksewell@umich.edu{ 1036378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 1045222Sksewell@umich.edu} 1055222Sksewell@umich.edu 1065222Sksewell@umich.edu 1075222Sksewell@umich.edu 1086378Sgblack@eecs.umich.eduFault 1096378Sgblack@eecs.umich.eduInterrupts::getInterrupt(ThreadContext * tc) 1105222Sksewell@umich.edu{ 1115222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts getInterrupt\n"); 1125222Sksewell@umich.edu 1135222Sksewell@umich.edu //Check if there are any outstanding interrupts 1146383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 1156378Sgblack@eecs.umich.edu // Interrupts must be enabled, error level must be 0 or interrupts 1166378Sgblack@eecs.umich.edu // inhibited, and exception level must be 0 or interrupts inhibited 1176379Sgblack@eecs.umich.edu if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) { 1185222Sksewell@umich.edu // Software interrupts & hardware interrupts are handled in software. 1195222Sksewell@umich.edu // So if any interrupt that isn't masked is detected, jump to interrupt 1205222Sksewell@umich.edu // handler 1216383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 1226379Sgblack@eecs.umich.edu if (status.im && cause.ip) { 1235222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", 1246379Sgblack@eecs.umich.edu (unsigned)status.im, (unsigned)cause.ip); 1255222Sksewell@umich.edu return new InterruptFault; 1265222Sksewell@umich.edu } 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu 1295222Sksewell@umich.edu return NoFault; 1306378Sgblack@eecs.umich.edu} 1315222Sksewell@umich.edu 1326378Sgblack@eecs.umich.edubool 1336378Sgblack@eecs.umich.eduInterrupts::onCpuTimerInterrupt(ThreadContext * tc) const 1345222Sksewell@umich.edu{ 1356383Sgblack@eecs.umich.edu MiscReg compare = tc->readMiscRegNoEffect(MISCREG_COMPARE); 1366383Sgblack@eecs.umich.edu MiscReg count = tc->readMiscRegNoEffect(MISCREG_COUNT); 1375222Sksewell@umich.edu if (compare == count && count != 0) 1385222Sksewell@umich.edu return true; 1395222Sksewell@umich.edu return false; 1405222Sksewell@umich.edu} 1416378Sgblack@eecs.umich.edu 1426378Sgblack@eecs.umich.eduvoid 1436378Sgblack@eecs.umich.eduInterrupts::updateIntrInfo(ThreadContext *tc) const 1445222Sksewell@umich.edu{ 1455222Sksewell@umich.edu //Nothing needs to be done. 1465222Sksewell@umich.edu} 1475222Sksewell@umich.edu 1486378Sgblack@eecs.umich.edubool 1496378Sgblack@eecs.umich.eduInterrupts::interruptsPending(ThreadContext *tc) const 1505222Sksewell@umich.edu{ 1515222Sksewell@umich.edu //if there is a on cpu timer interrupt (i.e. Compare == Count) 1525222Sksewell@umich.edu //update CauseIP before proceeding to interrupt 1536378Sgblack@eecs.umich.edu if (onCpuTimerInterrupt(tc)) { 1546378Sgblack@eecs.umich.edu DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); 1555222Sksewell@umich.edu //determine timer interrupt IP # 1566383Sgblack@eecs.umich.edu IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL); 1576379Sgblack@eecs.umich.edu uint8_t intStatus = getCauseIP(tc); 1586379Sgblack@eecs.umich.edu intStatus |= 1 << intCtl.ipti; 1596379Sgblack@eecs.umich.edu setCauseIP(tc, intStatus); 1605222Sksewell@umich.edu } 1615222Sksewell@umich.edu 1626378Sgblack@eecs.umich.edu return (getCauseIP(tc) != 0); 1635222Sksewell@umich.edu 1645222Sksewell@umich.edu} 1655222Sksewell@umich.edu 1665222Sksewell@umich.edu} 1676379Sgblack@eecs.umich.edu 1686379Sgblack@eecs.umich.eduMipsISA::Interrupts * 1696379Sgblack@eecs.umich.eduMipsInterruptsParams::create() 1706379Sgblack@eecs.umich.edu{ 1716379Sgblack@eecs.umich.edu return new MipsISA::Interrupts(this); 1726379Sgblack@eecs.umich.edu} 173