1
0

Merge pull request #963 from freechipsproject/interrupt-order

Respect ISA requirements on interrupt priority order
This commit is contained in:
Andrew Waterman 2017-08-18 00:10:19 -07:00 committed by GitHub
commit 82df766f4a

View File

@ -300,7 +300,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
val pending_interrupts = read_mip & reg_mie val pending_interrupts = read_mip & reg_mie
val d_interrupts = reg_debugint << CSR.debugIntCause val d_interrupts = reg_debugint << CSR.debugIntCause
val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0)) val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
val s_interrupts = Mux(m_interrupts === 0 && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0)) val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0))
val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts)) val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts))
val interruptMSB = BigInt(1) << (xLen-1) val interruptMSB = BigInt(1) << (xLen-1)
val interruptCause = UInt(interruptMSB) + whichInterrupt val interruptCause = UInt(interruptMSB) + whichInterrupt
@ -756,12 +756,15 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
} }
} }
def chooseInterrupt(masks: Seq[UInt]) = { def chooseInterrupt(masks: Seq[UInt]): (Bool, UInt) = {
// we can't simply choose the highest-numbered interrupt, because timer val nonstandard = supported_interrupts.getWidth-1 to 12 by -1
// interrupts are in the wrong place in mip. // MEI, MSI, MTI, SEI, SSI, STI, UEI, USI, UTI
val timerMask = UInt(0xF0, xLen) val standard = Seq(11, 3, 7, 9, 1, 5, 8, 0, 4)
val masked = masks.map(m => Cat(m.padTo(xLen) & ~timerMask, m.padTo(xLen) & timerMask)) val priority = nonstandard ++ standard
(masks.map(_.orR).reduce(_||_), Log2(masked.asUInt)(log2Ceil(xLen)-1, 0)) val paddedMasks = masks.reverse.map(_.padTo(xLen))
val any = paddedMasks.flatMap(m => priority.map(i => m(i))).reduce(_||_)
val which = PriorityMux(paddedMasks.flatMap(m => priority.map(i => (m(i), i.U))))
(any, which)
} }
def readModifyWriteCSR(cmd: UInt, rdata: UInt, wdata: UInt) = def readModifyWriteCSR(cmd: UInt, rdata: UInt, wdata: UInt) =