1
0

added IPIs and timer interrupts

This commit is contained in:
Rimas Avizienis 2011-11-14 03:24:02 -08:00
parent 5b29765917
commit 890bfa7c48
3 changed files with 30 additions and 11 deletions

View File

@ -58,7 +58,9 @@ class ioCtrlDpath extends Bundle()
val sboard_clr0a = UFix(5, 'input); val sboard_clr0a = UFix(5, 'input);
val sboard_clr1 = Bool('input); val sboard_clr1 = Bool('input);
val sboard_clr1a = UFix(5, '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() 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), 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), 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-> 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), 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), 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) 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 // exception handling
// FIXME: verify PC in MEM stage points to valid, restartable instruction // 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 p_irq_timer = (io.dpath.status(15).toBool && io.dpath.irq_timer);
val interrupt_cause = UFix(0x17, 5); 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 = val mem_exception =
interrupt || interrupt ||

View File

@ -354,8 +354,9 @@ class rocketDpath extends Component
pcr.io.host.from_wen ^^ io.host.from_wen; pcr.io.host.from_wen ^^ io.host.from_wen;
pcr.io.host.from ^^ io.host.from; pcr.io.host.from ^^ io.host.from;
pcr.io.host.to ^^ io.host.to; 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.ctrl.status := pcr.io.status;
io.ptbr := pcr.io.ptbr; io.ptbr := pcr.io.ptbr;
io.debug.error_mode := pcr.io.debug.error_mode; 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) // for load/use hazard detection (load byte/halfword)
io.ctrl.mem_waddr := mem_reg_waddr; io.ctrl.mem_waddr := mem_reg_waddr;
io.ctrl.mem_valid := mem_reg_valid;
// 32/64 bit load handling (moved to earlier in file) // 32/64 bit load handling (moved to earlier in file)

View File

@ -53,7 +53,8 @@ class ioDpathPCR extends Bundle()
val pc = UFix(VADDR_BITS, 'input); val pc = UFix(VADDR_BITS, 'input);
val badvaddr = UFix(VADDR_BITS, 'input); val badvaddr = UFix(VADDR_BITS, 'input);
val eret = Bool('input); val eret = Bool('input);
val timer_int = Bool('output); val irq_timer = Bool('output);
val irq_ipi = Bool('output);
} }
class rocketDpathPCR extends Component class rocketDpathPCR extends Component
@ -83,7 +84,8 @@ class rocketDpathPCR extends Component
val reg_status_ps = Reg(resetVal = Bool(false)); val reg_status_ps = Reg(resetVal = Bool(false));
val reg_status_et = 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 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() }; val rdata = Wire() { Bits() };
@ -105,7 +107,7 @@ class rocketDpathPCR extends Component
reg_fromhost <== Bits(0,32); reg_fromhost <== Bits(0,32);
} }
} }
when (io.badvaddr_wen) { when (io.badvaddr_wen) {
reg_badvaddr <== io.badvaddr; 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_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_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_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_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_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_K0) { reg_k0 <== io.w.data; }
when (io.w.addr === PCR_K1) { reg_k1 <== 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; } 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); reg_count <== reg_count + UFix(1);
when (reg_count === reg_compare) { 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); } when (!io.r.en) { rdata <== Bits(0,64); }
switch (io.r.addr) { switch (io.r.addr) {