Browse Source

picorv32: have maskirq take a control mask; let mret = retirq

Have maskirq take a control mask as well as a data mask, so the IRQ
mask can be examined and/or atomically modified.

Allow the mret opcode as an alias for retirq so that the gcc
__attribute__((interrupt)) works.
H. Peter Anvin 3 years ago
parent
commit
0cf198bfb2
1 changed files with 8 additions and 2 deletions
  1. 8 2
      fpga/picorv32.v

+ 8 - 2
fpga/picorv32.v

@@ -866,7 +866,11 @@ module picorv32 #(
 			instr_auipc   <= mem_rdata_latched[6:0] == 7'b0010111;
 			instr_jal     <= mem_rdata_latched[6:0] == 7'b1101111;
 			instr_jalr    <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000;
-			instr_retirq  <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ;
+			// hpa: allow mret as an alias for retirq, so that
+			// __attribute__((interrupt)) works in gcc
+			instr_retirq  <= ENABLE_IRQ &&
+					 ((mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010) ||
+					  (mem_rdata_latched[6:0] == 7'b0000111 && mem_rdata_latched[31:25] == 7'b0011000));
 			instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ;
 
 			is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011;
@@ -1674,7 +1678,9 @@ module picorv32 #(
 						latched_store <= 1;
 						reg_out <= irq_mask;
 						`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
-						irq_mask <= cpuregs_rs1 | MASKED_IRQ;
+						// hpa: allow rs2 to specify bits to be preserved
+					        `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);)
+						irq_mask <= ((irq_mask & ~cpuregs_rs2) ^ cpuregs_rs1) | MASKED_IRQ;
 						dbg_rs1val <= cpuregs_rs1;
 						dbg_rs1val_valid <= 1;
 						cpu_state <= cpu_state_fetch;