1
0

Support vectored stvec interrupts, too

137812654e
This commit is contained in:
Andrew Waterman 2017-05-07 15:14:51 -07:00
parent c6135a02df
commit 7eefc12705

View File

@ -478,12 +478,12 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug) val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug)
val debugTVec = Mux(reg_debug, Mux(insn_break, UInt(0x800), UInt(0x808)), UInt(0x800)) val debugTVec = Mux(reg_debug, Mux(insn_break, UInt(0x800), UInt(0x808)), UInt(0x800))
val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs))
val mtvecBaseAlign = 2
val mtvecInterruptAlign = log2Ceil(new MIP().getWidth)
val notDebugTVec = { val notDebugTVec = {
val base = Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec) val base = Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)
val baseAlign = 2 val interruptOffset = cause(mtvecInterruptAlign-1, 0) << mtvecBaseAlign
val interruptAlign = log2Ceil(new MIP().getWidth) val interruptVec = Cat(base >> (mtvecInterruptAlign + mtvecBaseAlign), interruptOffset)
val interruptOffset = cause(interruptAlign-1, 0) << baseAlign
val interruptVec = Cat(base >> (interruptAlign + baseAlign), interruptOffset)
Mux(base(0) && cause(cause.getWidth-1), interruptVec, base) Mux(base(0) && cause(cause.getWidth-1), interruptVec, base)
} }
val tvec = Mux(trapToDebug, debugTVec, notDebugTVec) val tvec = Mux(trapToDebug, debugTVec, notDebugTVec)
@ -624,7 +624,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
when (decoded_addr(CSRs.mepc)) { reg_mepc := formEPC(wdata) } when (decoded_addr(CSRs.mepc)) { reg_mepc := formEPC(wdata) }
when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata } when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
if (mtvecWritable) if (mtvecWritable)
when (decoded_addr(CSRs.mtvec)) { reg_mtvec := wdata & ~UInt(2, mtvecWidth) } when (decoded_addr(CSRs.mtvec)) { reg_mtvec := ~(~wdata | 2.U | Mux(wdata(0), UInt(((BigInt(1) << mtvecInterruptAlign) - 1) << mtvecBaseAlign), 0.U)) }
when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) } when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) }
@ -680,7 +680,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
when (decoded_addr(CSRs.sie)) { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) } when (decoded_addr(CSRs.sie)) { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) }
when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata }
when (decoded_addr(CSRs.sepc)) { reg_sepc := formEPC(wdata) } when (decoded_addr(CSRs.sepc)) { reg_sepc := formEPC(wdata) }
when (decoded_addr(CSRs.stvec)) { reg_stvec := wdata >> 2 << 2 } when (decoded_addr(CSRs.stvec)) { reg_stvec := ~(~wdata | 2.U | Mux(wdata(0), UInt(((BigInt(1) << mtvecInterruptAlign) - 1) << mtvecBaseAlign), 0.U)) }
when (decoded_addr(CSRs.scause)) { reg_scause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } when (decoded_addr(CSRs.scause)) { reg_scause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
when (decoded_addr(CSRs.sbadaddr)) { reg_sbadaddr := wdata(vaddrBitsExtended-1,0) } when (decoded_addr(CSRs.sbadaddr)) { reg_sbadaddr := wdata(vaddrBitsExtended-1,0) }
when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts } when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts }