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" 3511793Sbrandon.potter@amd.com 366379Sgblack@eecs.umich.edu#include "arch/mips/isa_traits.hh" 375222Sksewell@umich.edu#include "arch/mips/pra_constants.hh" 386379Sgblack@eecs.umich.edu#include "base/trace.hh" 395222Sksewell@umich.edu#include "cpu/thread_context.hh" 408745Sgblack@eecs.umich.edu#include "debug/Interrupt.hh" 415222Sksewell@umich.edu 425222Sksewell@umich.edunamespace MipsISA 435222Sksewell@umich.edu{ 446378Sgblack@eecs.umich.edu 456378Sgblack@eecs.umich.edustatic inline uint8_t 466378Sgblack@eecs.umich.edugetCauseIP(ThreadContext *tc) { 476383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 486379Sgblack@eecs.umich.edu return cause.ip; 495222Sksewell@umich.edu} 505222Sksewell@umich.edu 516378Sgblack@eecs.umich.edustatic inline void 526379Sgblack@eecs.umich.edusetCauseIP(ThreadContext *tc, uint8_t val) { 536383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 546379Sgblack@eecs.umich.edu cause.ip = val; 556383Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_CAUSE, cause); 565222Sksewell@umich.edu} 575222Sksewell@umich.edu 586378Sgblack@eecs.umich.eduvoid 596378Sgblack@eecs.umich.eduInterrupts::post(int int_num, ThreadContext* tc) 605222Sksewell@umich.edu{ 615222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d posted\n", int_num); 625222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 635222Sksewell@umich.edu panic("int_num out of bounds\n"); 645222Sksewell@umich.edu 656378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 665222Sksewell@umich.edu intstatus |= 1 << int_num; 676378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 685222Sksewell@umich.edu} 695222Sksewell@umich.edu 706378Sgblack@eecs.umich.eduvoid 716378Sgblack@eecs.umich.eduInterrupts::post(int int_num, int index) 725222Sksewell@umich.edu{ 736378Sgblack@eecs.umich.edu fatal("Must use Thread Context when posting MIPS Interrupts in M5"); 745222Sksewell@umich.edu} 755222Sksewell@umich.edu 766378Sgblack@eecs.umich.eduvoid 776378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, ThreadContext* tc) 785222Sksewell@umich.edu{ 795222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num); 805222Sksewell@umich.edu if (int_num < 0 || int_num >= NumInterruptLevels) 815222Sksewell@umich.edu panic("int_num out of bounds\n"); 825222Sksewell@umich.edu 836378Sgblack@eecs.umich.edu uint8_t intstatus = getCauseIP(tc); 845222Sksewell@umich.edu intstatus &= ~(1 << int_num); 856378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 865222Sksewell@umich.edu} 875222Sksewell@umich.edu 886378Sgblack@eecs.umich.eduvoid 896378Sgblack@eecs.umich.eduInterrupts::clear(int int_num, int index) 905222Sksewell@umich.edu{ 916378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 925222Sksewell@umich.edu} 935222Sksewell@umich.edu 946378Sgblack@eecs.umich.eduvoid 956378Sgblack@eecs.umich.eduInterrupts::clearAll(ThreadContext *tc) 965222Sksewell@umich.edu{ 975222Sksewell@umich.edu DPRINTF(Interrupt, "Interrupts all cleared\n"); 985222Sksewell@umich.edu uint8_t intstatus = 0; 996378Sgblack@eecs.umich.edu setCauseIP(tc, intstatus); 1005222Sksewell@umich.edu} 1015222Sksewell@umich.edu 1026378Sgblack@eecs.umich.eduvoid 1036378Sgblack@eecs.umich.eduInterrupts::clearAll() 1045222Sksewell@umich.edu{ 1056378Sgblack@eecs.umich.edu fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); 1065222Sksewell@umich.edu} 1075222Sksewell@umich.edu 1085222Sksewell@umich.edu 10911566Smitch.hayenga@arm.combool 11011566Smitch.hayenga@arm.comInterrupts::checkInterrupts(ThreadContext *tc) const 1115222Sksewell@umich.edu{ 11211566Smitch.hayenga@arm.com if (!interruptsPending(tc)) 11311566Smitch.hayenga@arm.com return false; 1145222Sksewell@umich.edu 1155222Sksewell@umich.edu //Check if there are any outstanding interrupts 1166383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 1176378Sgblack@eecs.umich.edu // Interrupts must be enabled, error level must be 0 or interrupts 1186378Sgblack@eecs.umich.edu // inhibited, and exception level must be 0 or interrupts inhibited 1196379Sgblack@eecs.umich.edu if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) { 1205222Sksewell@umich.edu // Software interrupts & hardware interrupts are handled in software. 1215222Sksewell@umich.edu // So if any interrupt that isn't masked is detected, jump to interrupt 1225222Sksewell@umich.edu // handler 1236383Sgblack@eecs.umich.edu CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 12411566Smitch.hayenga@arm.com if (status.im && cause.ip) 12511566Smitch.hayenga@arm.com return true; 12611566Smitch.hayenga@arm.com 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu 12911566Smitch.hayenga@arm.com return false; 13011566Smitch.hayenga@arm.com} 13111566Smitch.hayenga@arm.com 13211566Smitch.hayenga@arm.comFault 13311566Smitch.hayenga@arm.comInterrupts::getInterrupt(ThreadContext * tc) 13411566Smitch.hayenga@arm.com{ 13511566Smitch.hayenga@arm.com assert(checkInterrupts(tc)); 13611566Smitch.hayenga@arm.com 13711566Smitch.hayenga@arm.com StatusReg M5_VAR_USED status = tc->readMiscRegNoEffect(MISCREG_STATUS); 13811566Smitch.hayenga@arm.com CauseReg M5_VAR_USED cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); 13911566Smitch.hayenga@arm.com DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", 14011566Smitch.hayenga@arm.com (unsigned)status.im, (unsigned)cause.ip); 14111566Smitch.hayenga@arm.com 14211566Smitch.hayenga@arm.com return std::make_shared<InterruptFault>(); 1436378Sgblack@eecs.umich.edu} 1445222Sksewell@umich.edu 1456378Sgblack@eecs.umich.edubool 1466378Sgblack@eecs.umich.eduInterrupts::onCpuTimerInterrupt(ThreadContext * tc) const 1475222Sksewell@umich.edu{ 14813615Sgabeblack@google.com RegVal compare = tc->readMiscRegNoEffect(MISCREG_COMPARE); 14913615Sgabeblack@google.com RegVal count = tc->readMiscRegNoEffect(MISCREG_COUNT); 1505222Sksewell@umich.edu if (compare == count && count != 0) 1515222Sksewell@umich.edu return true; 1525222Sksewell@umich.edu return false; 1535222Sksewell@umich.edu} 1546378Sgblack@eecs.umich.edu 1556378Sgblack@eecs.umich.eduvoid 1566378Sgblack@eecs.umich.eduInterrupts::updateIntrInfo(ThreadContext *tc) const 1575222Sksewell@umich.edu{ 1585222Sksewell@umich.edu //Nothing needs to be done. 1595222Sksewell@umich.edu} 1605222Sksewell@umich.edu 1616378Sgblack@eecs.umich.edubool 1626378Sgblack@eecs.umich.eduInterrupts::interruptsPending(ThreadContext *tc) const 1635222Sksewell@umich.edu{ 1645222Sksewell@umich.edu //if there is a on cpu timer interrupt (i.e. Compare == Count) 1655222Sksewell@umich.edu //update CauseIP before proceeding to interrupt 1666378Sgblack@eecs.umich.edu if (onCpuTimerInterrupt(tc)) { 1676378Sgblack@eecs.umich.edu DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); 1685222Sksewell@umich.edu //determine timer interrupt IP # 1696383Sgblack@eecs.umich.edu IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL); 1706379Sgblack@eecs.umich.edu uint8_t intStatus = getCauseIP(tc); 1716379Sgblack@eecs.umich.edu intStatus |= 1 << intCtl.ipti; 1726379Sgblack@eecs.umich.edu setCauseIP(tc, intStatus); 1735222Sksewell@umich.edu } 1745222Sksewell@umich.edu 1756378Sgblack@eecs.umich.edu return (getCauseIP(tc) != 0); 1765222Sksewell@umich.edu 1775222Sksewell@umich.edu} 1785222Sksewell@umich.edu 1795222Sksewell@umich.edu} 1806379Sgblack@eecs.umich.edu 1816379Sgblack@eecs.umich.eduMipsISA::Interrupts * 1826379Sgblack@eecs.umich.eduMipsInterruptsParams::create() 1836379Sgblack@eecs.umich.edu{ 1846379Sgblack@eecs.umich.edu return new MipsISA::Interrupts(this); 1856379Sgblack@eecs.umich.edu} 186