diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 3eb1b374..dc091ad5 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -58,7 +58,9 @@ class ioCtrlDpath extends Bundle() val sboard_clr0a = UFix(5, 'input); val sboard_clr1 = Bool('input); val sboard_clr1a = UFix(5, 'input); - val timer_int = Bool('input); + val mem_valid = Bool('input); // high if there's a valid (not flushed) instruction in mem stage + val irq_timer = Bool('input); + val irq_ipi = Bool('input); } class ioCtrlAll extends Bundle() @@ -234,6 +236,7 @@ class rocketCtrl extends Component DI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,N,N,N,Y), ERET-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,N,Y,N,Y), FENCE-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,Y,N,N,N), + FENCE_I-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,Y,N,N,N), //FIXME CFLUSH-> List(Y, BR_N, REN_Y,REN_N,A2_X, A1_X, DW_X, FN_X, M_Y,M_FLA, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,N,N,N,Y), MFPCR-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PCR,REN_Y,WEN_N,N,N,N,Y), MTPCR-> List(Y, BR_N, REN_N,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_Y,N,N,N,Y) @@ -453,8 +456,17 @@ class rocketCtrl extends Component // exception handling // FIXME: verify PC in MEM stage points to valid, restartable instruction - val interrupt = io.dpath.status(SR_ET).toBool && io.dpath.status(15).toBool && io.dpath.timer_int; - val interrupt_cause = UFix(0x17, 5); + val p_irq_timer = (io.dpath.status(15).toBool && io.dpath.irq_timer); + val p_irq_ipi = (io.dpath.status(13).toBool && io.dpath.irq_ipi); + val interrupt = + io.dpath.status(SR_ET).toBool && io.dpath.mem_valid && + ((io.dpath.status(15).toBool && io.dpath.irq_timer) || + (io.dpath.status(13).toBool && io.dpath.irq_ipi)); + + val interrupt_cause = + Mux(p_irq_ipi, UFix(21,5), + Mux(p_irq_timer, UFix(23,5), + UFix(0,5))); val mem_exception = interrupt || diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index e49a1761..bfb5eedb 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -354,8 +354,9 @@ class rocketDpath extends Component pcr.io.host.from_wen ^^ io.host.from_wen; pcr.io.host.from ^^ io.host.from; pcr.io.host.to ^^ io.host.to; - - io.ctrl.timer_int := pcr.io.timer_int; + + io.ctrl.irq_timer := pcr.io.irq_timer; + io.ctrl.irq_ipi := pcr.io.irq_ipi; io.ctrl.status := pcr.io.status; io.ptbr := pcr.io.ptbr; io.debug.error_mode := pcr.io.debug.error_mode; @@ -399,6 +400,7 @@ class rocketDpath extends Component // for load/use hazard detection (load byte/halfword) io.ctrl.mem_waddr := mem_reg_waddr; + io.ctrl.mem_valid := mem_reg_valid; // 32/64 bit load handling (moved to earlier in file) diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index 951ec9c1..97b5e15b 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -53,7 +53,8 @@ class ioDpathPCR extends Bundle() val pc = UFix(VADDR_BITS, 'input); val badvaddr = UFix(VADDR_BITS, 'input); val eret = Bool('input); - val timer_int = Bool('output); + val irq_timer = Bool('output); + val irq_ipi = Bool('output); } class rocketDpathPCR extends Component @@ -83,7 +84,8 @@ class rocketDpathPCR extends Component val reg_status_ps = Reg(resetVal = Bool(false)); val reg_status_et = Reg(resetVal = Bool(false)); - val timer_interrupt = Reg(resetVal = Bool(false)); + val r_irq_timer = Reg(resetVal = Bool(false)); + val r_irq_ipi = Reg(resetVal = Bool(false)); val reg_status = Cat(reg_status_sx, reg_status_ux, reg_status_s, reg_status_ps, Bits(0,1), reg_status_ev, reg_status_ef, reg_status_et); val rdata = Wire() { Bits() }; @@ -105,7 +107,7 @@ class rocketDpathPCR extends Component reg_fromhost <== Bits(0,32); } } - + when (io.badvaddr_wen) { reg_badvaddr <== io.badvaddr; } @@ -143,9 +145,11 @@ class rocketDpathPCR extends Component when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS-1,0).toUFix; } when (io.w.addr === PCR_EVEC) { reg_ebase <== io.w.data(VADDR_BITS-1,0).toUFix; } when (io.w.addr === PCR_COUNT) { reg_count <== io.w.data(31,0).toUFix; } - when (io.w.addr === PCR_COMPARE) { reg_compare <== io.w.data(31,0).toUFix; timer_interrupt <== Bool(false); } + when (io.w.addr === PCR_COMPARE) { reg_compare <== io.w.data(31,0).toUFix; r_irq_timer <== Bool(false); } when (io.w.addr === PCR_CAUSE) { reg_cause <== io.w.data(4,0); } when (io.w.addr === PCR_FROMHOST) { reg_fromhost <== io.w.data(31,0); } + when (io.w.addr === PCR_SENDIPI) { r_irq_ipi <== Bool(true); } + when (io.w.addr === PCR_CLEARIPI) { r_irq_ipi <== Bool(false); } when (io.w.addr === PCR_K0) { reg_k0 <== io.w.data; } when (io.w.addr === PCR_K1) { reg_k1 <== io.w.data; } when (io.w.addr === PCR_PTBR) { reg_ptbr <== Cat(io.w.data(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; } @@ -153,9 +157,10 @@ class rocketDpathPCR extends Component reg_count <== reg_count + UFix(1); when (reg_count === reg_compare) { - timer_interrupt <== Bool(true); + r_irq_timer <== Bool(true); } - io.timer_int := timer_interrupt; + io.irq_timer := r_irq_timer; + io.irq_ipi := r_irq_ipi; when (!io.r.en) { rdata <== Bits(0,64); } switch (io.r.addr) {