interrupts.cc revision 6378
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 345222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 355222Sksewell@umich.edu#include "arch/mips/isa_traits.hh" 365222Sksewell@umich.edu#include "cpu/thread_context.hh" 375222Sksewell@umich.edu#include "arch/mips/interrupts.hh" 385222Sksewell@umich.edu 395222Sksewell@umich.edunamespace MipsISA 405222Sksewell@umich.edu{ 416378Sgblack@eecs.umich.edu 426378Sgblack@eecs.umich.edustatic inline uint8_t 436378Sgblack@eecs.umich.edugetCauseIP(ThreadContext *tc) { 445222Sksewell@umich.edu MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause); 456378Sgblack@eecs.umich.edu return bits(cause, Cause_IP7, Cause_IP0); 465222Sksewell@umich.edu} 475222Sksewell@umich.edu 486378Sgblack@eecs.umich.edustatic inline void 496378Sgblack@eecs.umich.edusetCauseIP_(ThreadContext *tc, uint8_t val) { 505222Sksewell@umich.edu MiscReg cause = tc->readMiscRegNoEffect(MipsISA::Cause); 516378Sgblack@eecs.umich.edu replaceBits(cause, Cause_IP7, Cause_IP0, val); 526378Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MipsISA::Cause, cause); 535222Sksewell@umich.edu} 545222Sksewell@umich.edu 556378Sgblack@eecs.umich.eduvoid 566378Sgblack@eecs.umich.eduInterrupts::post(int int_num, ThreadContext* tc) 575222Sksewell@umich.edu{ 585222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d posted\n", int_num); 595222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 605222Sksewell@umich.edu panic("int_num out of bounds\n"); 615222Sksewell@umich.edu 626378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 635222Sksewell@umich.edu intstatus |= 1 << int_num; 646378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 655222Sksewell@umich.edu} 665222Sksewell@umich.edu 676378Sgblack@eecs.umich.eduvoid 686378Sgblack@eecs.umich.eduInterrupts::post(int int_num, int index) 695222Sksewell@umich.edu{ 706378Sgblack@eecs.umich.edu fatal("Must use Thread Context when posting MIPS Interrupts in M5"); 715222Sksewell@umich.edu} 725222Sksewell@umich.edu 736378Sgblack@eecs.umich.eduvoid 746378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, ThreadContext* tc) 755222Sksewell@umich.edu{ 765222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num); 775222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 785222Sksewell@umich.edu panic("int_num out of bounds\n"); 795222Sksewell@umich.edu 806378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 815222Sksewell@umich.edu intstatus &= ~(1 << int_num); 826378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 835222Sksewell@umich.edu} 845222Sksewell@umich.edu 856378Sgblack@eecs.umich.eduvoid 866378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, int index) 875222Sksewell@umich.edu{ 886378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 895222Sksewell@umich.edu} 905222Sksewell@umich.edu 916378Sgblack@eecs.umich.eduvoid 926378Sgblack@eecs.umich.eduInterrupts::clearAll(ThreadContext *tc) 935222Sksewell@umich.edu{ 945222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts all cleared\n"); 955222Sksewell@umich.edu uint8_t intstatus = 0; 966378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 975222Sksewell@umich.edu} 985222Sksewell@umich.edu 996378Sgblack@eecs.umich.eduvoid 1006378Sgblack@eecs.umich.eduInterrupts::clearAll() 1015222Sksewell@umich.edu{ 1026378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 1035222Sksewell@umich.edu} 1045222Sksewell@umich.edu 1055222Sksewell@umich.edu 1065222Sksewell@umich.edu 1076378Sgblack@eecs.umich.eduFault 1086378Sgblack@eecs.umich.eduInterrupts::getInterrupt(ThreadContext * tc) 1095222Sksewell@umich.edu{ 1105222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts getInterrupt\n"); 1115222Sksewell@umich.edu 1125222Sksewell@umich.edu //Check if there are any outstanding interrupts 1135222Sksewell@umich.edu MiscReg status = tc->readMiscRegNoEffect(MipsISA::Status); 1146378Sgblack@eecs.umich.edu // Interrupts must be enabled, error level must be 0 or interrupts 1156378Sgblack@eecs.umich.edu // inhibited, and exception level must be 0 or interrupts inhibited 1166378Sgblack@eecs.umich.edu if (bits(status, Status_IE_LO) == 1 && 1176378Sgblack@eecs.umich.edu bits(status, Status_ERL_HI, Status_ERL_LO) == 0 && 1186378Sgblack@eecs.umich.edu bits(status, Status_EXL_HI, Status_EXL_LO) == 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 1226378Sgblack@eecs.umich.edu uint8_t InterruptMask = bits(status, Status_IM7, Status_IM0); 1236378Sgblack@eecs.umich.edu uint8_t InterruptPending = getCauseIP(tc); 1246378Sgblack@eecs.umich.edu // InterruptMask and InterruptPending are already correctly aligned 1256378Sgblack@eecs.umich.edu if (InterruptMask && InterruptPending){ 1265222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", 1276378Sgblack@eecs.umich.edu InterruptMask, InterruptPending); 1285222Sksewell@umich.edu return new InterruptFault; 1295222Sksewell@umich.edu } 1305222Sksewell@umich.edu } 1315222Sksewell@umich.edu 1325222Sksewell@umich.edu return NoFault; 1336378Sgblack@eecs.umich.edu} 1345222Sksewell@umich.edu 1356378Sgblack@eecs.umich.edubool 1366378Sgblack@eecs.umich.eduInterrupts::onCpuTimerInterrupt(ThreadContext * tc) const 1375222Sksewell@umich.edu{ 1385222Sksewell@umich.edu MiscReg compare = tc->readMiscRegNoEffect(MipsISA::Compare); 1395222Sksewell@umich.edu MiscReg count = tc->readMiscRegNoEffect(MipsISA::Count); 1405222Sksewell@umich.edu if (compare == count && count != 0) 1415222Sksewell@umich.edu return true; 1425222Sksewell@umich.edu return false; 1435222Sksewell@umich.edu} 1446378Sgblack@eecs.umich.edu 1456378Sgblack@eecs.umich.eduvoid 1466378Sgblack@eecs.umich.eduInterrupts::updateIntrInfo(ThreadContext *tc) const 1475222Sksewell@umich.edu{ 1485222Sksewell@umich.edu //Nothing needs to be done. 1495222Sksewell@umich.edu} 1505222Sksewell@umich.edu 1516378Sgblack@eecs.umich.edubool 1526378Sgblack@eecs.umich.eduInterrupts::interruptsPending(ThreadContext *tc) const 1535222Sksewell@umich.edu{ 1545222Sksewell@umich.edu //if there is a on cpu timer interrupt (i.e. Compare == Count) 1555222Sksewell@umich.edu //update CauseIP before proceeding to interrupt 1566378Sgblack@eecs.umich.edu if (onCpuTimerInterrupt(tc)) { 1576378Sgblack@eecs.umich.edu DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); 1585222Sksewell@umich.edu //determine timer interrupt IP # 1595222Sksewell@umich.edu MiscReg intctl = tc->readMiscRegNoEffect(MipsISA::IntCtl); 1605222Sksewell@umich.edu uint8_t IPTI = bits(intctl, IntCtl_IPTI_HI, IntCtl_IPTI_LO); 1615222Sksewell@umich.edu //set intstatus to correspond 1625222Sksewell@umich.edu //post(IPTI, tc); 1636378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 1645222Sksewell@umich.edu intstatus |= 1 << IPTI; 1656378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 1665222Sksewell@umich.edu } 1675222Sksewell@umich.edu 1686378Sgblack@eecs.umich.edu return (getCauseIP(tc) != 0); 1695222Sksewell@umich.edu 1705222Sksewell@umich.edu} 1715222Sksewell@umich.edu 1725222Sksewell@umich.edu} 173