From a5c4eb3de9deb3a71a6a5230a25ff5962e584980 Mon Sep 17 00:00:00 2001 From: Mitch Hayenga Date: Wed, 30 Sep 2015 11:14:19 -0500 Subject: isa,cpu: Add support for FS SMT Interrupts Adds per-thread interrupt controllers and thread/context logic so that interrupts properly get routed in SMT systems. --- src/arch/alpha/isa/decoder.isa | 2 +- src/arch/arm/faults.cc | 8 ++++---- src/arch/arm/isa.cc | 6 +++--- src/arch/arm/isa/insts/misc.isa | 11 ++++++----- src/arch/sparc/isa.cc | 4 ++-- src/arch/sparc/tlb.cc | 12 ++++++------ src/arch/sparc/ua2005.cc | 32 ++++++++++++++++---------------- src/arch/x86/utility.cc | 2 +- 8 files changed, 39 insertions(+), 38 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index c77ca434f..e61bb43ff 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -943,7 +943,7 @@ decode OPCODE default Unknown::unknown() { 0x01: quiesce({{ // Don't sleep if (unmasked) interrupts are pending Interrupts* interrupts = - xc->tcBase()->getCpuPtr()->getInterruptController(); + xc->tcBase()->getCpuPtr()->getInterruptController(0); if (interrupts->checkInterrupts(xc->tcBase())) { PseudoInst::quiesceSkip(xc->tcBase()); } else { diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 9d373e469..a2b1120ec 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -681,7 +681,7 @@ void Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst) { if (FullSystem) { - tc->getCpuPtr()->clearInterrupts(); + tc->getCpuPtr()->clearInterrupts(tc->threadId()); tc->clearArchRegs(); } if (!ArmSystem::highestELIs64(tc)) { @@ -938,7 +938,7 @@ AbortFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) } if (source == ArmFault::AsynchronousExternalAbort) { - tc->getCpuPtr()->clearInterrupt(INT_ABT, 0); + tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); } // Get effective fault source encoding CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); @@ -1353,7 +1353,7 @@ SystemError::SystemError() void SystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst) { - tc->getCpuPtr()->clearInterrupt(INT_ABT, 0); + tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); ArmFault::invoke(tc, inst); } @@ -1404,7 +1404,7 @@ ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) { // SEV execution and let pipeline continue as pcState is still // valid. tc->setMiscReg(MISCREG_SEV_MAILBOX, 1); - tc->getCpuPtr()->clearInterrupt(INT_SEV, 0); + tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0); } // Instantiate all the templates to make the linker happy diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index bac7bab89..f90b8a2df 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -668,12 +668,12 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) case MISCREG_DBGDSCRint: return 0; case MISCREG_ISR: - return tc->getCpuPtr()->getInterruptController()->getISR( + return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR( readMiscRegNoEffect(MISCREG_HCR), readMiscRegNoEffect(MISCREG_CPSR), readMiscRegNoEffect(MISCREG_SCR)); case MISCREG_ISR_EL1: - return tc->getCpuPtr()->getInterruptController()->getISR( + return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR( readMiscRegNoEffect(MISCREG_HCR_EL2), readMiscRegNoEffect(MISCREG_CPSR), readMiscRegNoEffect(MISCREG_SCR_EL3)); @@ -1929,7 +1929,7 @@ ISA::getGenericTimer(ThreadContext *tc) "been configured to use a generic timer.\n"); } - timer.reset(new GenericTimerISA(*generic_timer, tc->cpuId())); + timer.reset(new GenericTimerISA(*generic_timer, tc->contextId())); return *timer.get(); } diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 6ecaa78de..c8b1de1d8 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -649,7 +649,8 @@ let {{ if (SevMailbox == 1) { SevMailbox = 0; PseudoInst::quiesceSkip(tc); - } else if (tc->getCpuPtr()->getInterruptController()->checkInterrupts(tc)) { + } else if (tc->getCpuPtr()->getInterruptController( + tc->threadId())->checkInterrupts(tc)) { PseudoInst::quiesceSkip(tc); } else if (cpsr.el == EL0 && !sctlr.ntwe) { PseudoInst::quiesceSkip(tc); @@ -692,8 +693,8 @@ let {{ // WFI doesn't sleep if interrupts are pending (masked or not) ThreadContext *tc = xc->tcBase(); - if (tc->getCpuPtr()->getInterruptController()->checkWfiWake(hcr, cpsr, - scr)) { + if (tc->getCpuPtr()->getInterruptController( + tc->threadId())->checkWfiWake(hcr, cpsr, scr)) { PseudoInst::quiesceSkip(tc); } else if (cpsr.el == EL0 && !sctlr.ntwi) { PseudoInst::quiesceSkip(tc); @@ -711,7 +712,7 @@ let {{ } else { PseudoInst::quiesce(tc); } - tc->getCpuPtr()->clearInterrupt(INT_ABT, 0); + tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); ''' wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \ { "code" : wfiCode, "predicate_test" : predicateTest }, @@ -731,7 +732,7 @@ let {{ // Wake CPU with interrupt if they were sleeping if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) { // Post Interrupt and wake cpu if needed - oc->getCpuPtr()->postInterrupt(INT_SEV, 0); + oc->getCpuPtr()->postInterrupt(oc->threadId(), INT_SEV, 0); } } ''' diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc index a588eaf66..aa10a0b46 100644 --- a/src/arch/sparc/isa.cc +++ b/src/arch/sparc/isa.cc @@ -591,9 +591,9 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc) { tl = val; if (hpstate.tlz && tl == 0 && !hpstate.hpriv) - tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); + tc->getCpuPtr()->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); else - tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); + tc->getCpuPtr()->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); return; } case MISCREG_CWP: diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index c0c28f952..b4a761293 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1022,7 +1022,7 @@ TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) { SparcISA::Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); + tc->getCpuPtr()->getInterruptController(0)); pkt->set(interrupts->get_vec(IT_INT_VEC)); } break; @@ -1030,9 +1030,9 @@ TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) { SparcISA::Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); + tc->getCpuPtr()->getInterruptController(0)); temp = findMsbSet(interrupts->get_vec(IT_INT_VEC)); - tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, temp); + tc->getCpuPtr()->clearInterrupt(0, IT_INT_VEC, temp); pkt->set(temp); } break; @@ -1278,16 +1278,16 @@ TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) // clear all the interrupts that aren't set in the write SparcISA::Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); + tc->getCpuPtr()->getInterruptController(0)); while (interrupts->get_vec(IT_INT_VEC) & data) { msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data); - tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, msb); + tc->getCpuPtr()->clearInterrupt(0, IT_INT_VEC, msb); } } break; case ASI_SWVR_UDB_INTR_W: tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> - postInterrupt(bits(data, 5, 0), 0); + postInterrupt(0, bits(data, 5, 0), 0); break; default: doMmuWriteError: diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index b207f2fac..2c100957f 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -49,20 +49,20 @@ ISA::checkSoftInt(ThreadContext *tc) // If PIL < 14, copy over the tm and sm bits if (pil < 14 && softint & 0x10000) - cpu->postInterrupt(IT_SOFT_INT, 16); + cpu->postInterrupt(0, IT_SOFT_INT, 16); else - cpu->clearInterrupt(IT_SOFT_INT, 16); + cpu->clearInterrupt(0, IT_SOFT_INT, 16); if (pil < 14 && softint & 0x1) - cpu->postInterrupt(IT_SOFT_INT, 0); + cpu->postInterrupt(0, IT_SOFT_INT, 0); else - cpu->clearInterrupt(IT_SOFT_INT, 0); + cpu->clearInterrupt(0, IT_SOFT_INT, 0); // Copy over any of the other bits that are set for (int bit = 15; bit > 0; --bit) { if (1 << bit & softint && bit > pil) - cpu->postInterrupt(IT_SOFT_INT, bit); + cpu->postInterrupt(0, IT_SOFT_INT, bit); else - cpu->clearInterrupt(IT_SOFT_INT, bit); + cpu->clearInterrupt(0, IT_SOFT_INT, bit); } } @@ -149,9 +149,9 @@ ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_HINTP: setMiscRegNoEffect(miscReg, val); if (hintp) - cpu->postInterrupt(IT_HINTP, 0); + cpu->postInterrupt(0, IT_HINTP, 0); else - cpu->clearInterrupt(IT_HINTP, 0); + cpu->clearInterrupt(0, IT_HINTP, 0); break; case MISCREG_HTBA: @@ -163,25 +163,25 @@ ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_QUEUE_CPU_MONDO_TAIL: setMiscRegNoEffect(miscReg, val); if (cpu_mondo_head != cpu_mondo_tail) - cpu->postInterrupt(IT_CPU_MONDO, 0); + cpu->postInterrupt(0, IT_CPU_MONDO, 0); else - cpu->clearInterrupt(IT_CPU_MONDO, 0); + cpu->clearInterrupt(0, IT_CPU_MONDO, 0); break; case MISCREG_QUEUE_DEV_MONDO_HEAD: case MISCREG_QUEUE_DEV_MONDO_TAIL: setMiscRegNoEffect(miscReg, val); if (dev_mondo_head != dev_mondo_tail) - cpu->postInterrupt(IT_DEV_MONDO, 0); + cpu->postInterrupt(0, IT_DEV_MONDO, 0); else - cpu->clearInterrupt(IT_DEV_MONDO, 0); + cpu->clearInterrupt(0, IT_DEV_MONDO, 0); break; case MISCREG_QUEUE_RES_ERROR_HEAD: case MISCREG_QUEUE_RES_ERROR_TAIL: setMiscRegNoEffect(miscReg, val); if (res_error_head != res_error_tail) - cpu->postInterrupt(IT_RES_ERROR, 0); + cpu->postInterrupt(0, IT_RES_ERROR, 0); else - cpu->clearInterrupt(IT_RES_ERROR, 0); + cpu->clearInterrupt(0, IT_RES_ERROR, 0); break; case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: @@ -213,9 +213,9 @@ ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) setMiscRegNoEffect(miscReg, newVal); newVal = hpstate; if (newVal.tlz && tl == 0 && !newVal.hpriv) - cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); + cpu->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); else - cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); + cpu->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); break; } case MISCREG_HTSTATE: diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index f7d0f816e..cf6d2d910 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -183,7 +183,7 @@ void initCPU(ThreadContext *tc, int cpuId) tc->setMiscReg(MISCREG_APIC_BASE, lApicBase); Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); + tc->getCpuPtr()->getInterruptController(0)); assert(interrupts); interrupts->setRegNoEffect(APIC_ID, cpuId << 24); -- cgit v1.2.3