Update lowrisc_ibex to lowRISC/ibex@4b43afa5
Update code from upstream repository
https://github.com/lowRISC/ibex.git to revision
4b43afa53315d00784d5c3b714583276127eddcc
* [doc] Fix table rendering for `mseccfg` (Greg Chadwick)
* [rtl] Add MSECCFGH CSR (Greg Chadwick)
* [rtl] Hard wire dcsr.stepie to 0 (Greg Chadwick)
* [rtl] Fix hardware breakpoints and exceptions interaction (Greg
Chadwick)
* Fix spacing for bullet points to appear (Yusef Karim)
* [ci/ibex] temporarily remove pmp_full_random_test (Udi Jonnalagadda)
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
diff --git a/hw/vendor/lowrisc_ibex.lock.hjson b/hw/vendor/lowrisc_ibex.lock.hjson
index da03b10..cd2d429 100644
--- a/hw/vendor/lowrisc_ibex.lock.hjson
+++ b/hw/vendor/lowrisc_ibex.lock.hjson
@@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/lowRISC/ibex.git
- rev: 42827fc9cd0b2043d5d179cae46b0238a55d3652
+ rev: 4b43afa53315d00784d5c3b714583276127eddcc
}
}
diff --git a/hw/vendor/lowrisc_ibex/doc/03_reference/cs_registers.rst b/hw/vendor/lowrisc_ibex/doc/03_reference/cs_registers.rst
index e6a3a3f..af884c3 100644
--- a/hw/vendor/lowrisc_ibex/doc/03_reference/cs_registers.rst
+++ b/hw/vendor/lowrisc_ibex/doc/03_reference/cs_registers.rst
@@ -36,6 +36,8 @@
+---------+--------------------+--------+-----------------------------------------------+
| 0x390 | ``mseccfg`` | WARL | Machine Security Configuration |
+---------+--------------------+--------+-----------------------------------------------+
+| 0x391 | ``mseccfgh`` | WARL | Upper 32 bits of ``mseccfg`` |
++---------+--------------------+--------+-----------------------------------------------+
| 0x3A0 | ``pmpcfg0`` | WARL | PMP Configuration Register |
+---------+--------------------+--------+-----------------------------------------------+
| . . . . |
@@ -248,12 +250,12 @@
| 3 | **Machine Software Interrupt Pending (MSIP):** if set, ``irq_software_i`` is pending. |
+-------+---------------------------------------------------------------------------------------+
-Machine Security Configuration (mseccfg)
+Machine Security Configuration (mseccfg/mseccfgh)
----------------------------------------
-CSR Address: ``0x390``
+CSR Address: ``0x390 - 0x391``
-Reset Value: ``0x0000_0000``
+Reset Value: ``0x0000_0000_0000_0000``
+------+-----------------------------------------------------------------------------------------------------------------------------------+
| Bit# | Definition |
@@ -262,12 +264,14 @@
+------+-----------------------------------------------------------------------------------------------------------------------------------+
| 1 | **Machine Mode Whitelist Policy (MMWP):** If set default policy for PMP is deny for M-Mode accesses that don't match a PMP region |
+------+-----------------------------------------------------------------------------------------------------------------------------------+
-| 0 | **Machine Mode Lockdown (MML):** Alters behaviour of ``pmpcfgX`` bits |
+| 0 | **Machine Mode Lockdown (MML):** Alters behaviour of ``pmpcfgX`` bits |
+------+-----------------------------------------------------------------------------------------------------------------------------------+
``mseccfg`` is specified in the Trusted Execution Environment (TEE) working group proposal :download:`PMP Enhancements for memory access and execution prevention on Machine mode <../03_reference/pdfs/riscv-epmp.pdf>`, which gives the full details of it's functionality including the new PMP behaviour when ``mseccfg.MML`` is set.
Note that the reset value means PMP behavior out of reset matches the RISC-V Privileged Architecture.
A write to ``mseccfg`` is required to change it.
+Note ``mseccfgh`` reads as all 0s and ignores all writes.
+Any access to ``mseccfg`` or ``mseccfgh`` when using an Ibex configuration without PMP (``PMPEnable`` is 0) will trigger an illegal instruction exception.
PMP Configuration Register (pmpcfgx)
------------------------------------
diff --git a/hw/vendor/lowrisc_ibex/doc/03_reference/security.rst b/hw/vendor/lowrisc_ibex/doc/03_reference/security.rst
index 80bca31..b44d715 100644
--- a/hw/vendor/lowrisc_ibex/doc/03_reference/security.rst
+++ b/hw/vendor/lowrisc_ibex/doc/03_reference/security.rst
@@ -21,6 +21,7 @@
In Ibex, most instructions already execute independent of their input operands.
When data-independent timing is enabled:
+
* Branches execute identically regardless of their taken/not-taken status
* Early completion of multiplication by zero/one is removed
* Early completion of divide by zero is removed
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
index 07c3136..26dbf3c 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
@@ -145,10 +145,14 @@
logic special_req;
logic special_req_pc_change;
logic special_req_flush_only;
- logic enter_debug_mode_d;
- logic enter_debug_mode_q;
+ logic do_single_step_d;
+ logic do_single_step_q;
+ logic enter_debug_mode_prio_d;
+ logic enter_debug_mode_prio_q;
+ logic enter_debug_mode;
logic ebreak_into_debug;
logic handle_irq;
+ logic id_wb_pending;
logic [3:0] mfip_id;
logic unused_irq_timer;
@@ -233,6 +237,9 @@
// generic special request signal, applies to all instructions
assign special_req = special_req_pc_change | special_req_flush_only;
+ // Is there an instruction in ID or WB that has yet to complete?
+ assign id_wb_pending = instr_valid_i | ~ready_wb_i;
+
// Exception/fault prioritisation is taken from Table 3.7 of Priviledged Spec v1.11
if (WritebackStage) begin : g_wb_exceptions
always_comb begin
@@ -308,8 +315,24 @@
// due to a recently flushed IF (or a delay in an instruction returning from
// memory) before it has had anything to single step.
// Also enter debug mode on a trigger match (hardware breakpoint)
- assign enter_debug_mode_d = (debug_req_i | (debug_single_step_i & instr_valid_i) |
- trigger_match_i) & ~debug_mode_q;
+
+ // Set `do_single_step_q` when a valid instruction is seen outside of debug mode and core is in
+ // single step mode. The first valid instruction on debug mode entry will clear it. Hold its value
+ // when there is no valid instruction so `do_single_step_d` remains asserted until debug mode is
+ // entered.
+ assign do_single_step_d = instr_valid_i ? ~debug_mode_q & debug_single_step_i : do_single_step_q;
+ // Enter debug mode due to:
+ // * external `debug_req_i`
+ // * core in single step mode (dcsr.step == 1).
+ // * trigger match (hardware breakpoint)
+ //
+ // `debug_req_i` and `do_single_step_d` request debug mode with priority. This results in a debug
+ // mode entry even if the controller goes to `FLUSH` in preparation for handling an exception or
+ // interrupt. `trigger_match_i` is not a priority entry into debug mode as it must be ignored
+ // where control flow changes such that the instruction causing the trigger is no longer being
+ // executed.
+ assign enter_debug_mode_prio_d = (debug_req_i | do_single_step_d) & ~debug_mode_q;
+ assign enter_debug_mode = enter_debug_mode_prio_d | (trigger_match_i & ~debug_mode_q);
// Set when an ebreak should enter debug mode rather than jump to exception
// handler
@@ -452,7 +475,7 @@
end
// enter debug mode
- if (enter_debug_mode_d) begin
+ if (enter_debug_mode) begin
ctrl_fsm_ns = DBG_TAKEN_IF;
// Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
// ID state is needed for correct debug mode entry
@@ -516,15 +539,14 @@
pc_set_spec_o = BranchPredictor ? ~instr_bp_taken_i : 1'b1;
end
- // If entering debug mode or handling an IRQ the core needs to wait
- // until the current instruction has finished executing. Stall IF
- // during that time.
- if ((enter_debug_mode_d || handle_irq) && stall) begin
+ // If entering debug mode or handling an IRQ the core needs to wait until any instruction in
+ // ID or WB has finished executing. Stall IF during that time.
+ if ((enter_debug_mode || handle_irq) && (stall || id_wb_pending)) begin
halt_if = 1'b1;
end
- if (!stall && !special_req) begin
- if (enter_debug_mode_d) begin
+ if (!stall && !special_req && !id_wb_pending) begin
+ if (enter_debug_mode) begin
// enter debug mode
ctrl_fsm_ns = DBG_TAKEN_IF;
// Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
@@ -757,7 +779,7 @@
// If an EBREAK instruction is causing us to enter debug mode on the
// same cycle as a debug_req or single step, honor the EBREAK and
// proceed to DBG_TAKEN_ID.
- if (enter_debug_mode_q && !(ebrk_insn_prio && ebreak_into_debug)) begin
+ if (enter_debug_mode_prio_q && !(ebrk_insn_prio && ebreak_into_debug)) begin
ctrl_fsm_ns = DBG_TAKEN_IF;
end
end // FLUSH
@@ -799,23 +821,25 @@
// update registers
always_ff @(posedge clk_i or negedge rst_ni) begin : update_regs
if (!rst_ni) begin
- ctrl_fsm_cs <= RESET;
- nmi_mode_q <= 1'b0;
- debug_mode_q <= 1'b0;
- enter_debug_mode_q <= 1'b0;
- load_err_q <= 1'b0;
- store_err_q <= 1'b0;
- exc_req_q <= 1'b0;
- illegal_insn_q <= 1'b0;
+ ctrl_fsm_cs <= RESET;
+ nmi_mode_q <= 1'b0;
+ do_single_step_q <= 1'b0;
+ debug_mode_q <= 1'b0;
+ enter_debug_mode_prio_q <= 1'b0;
+ load_err_q <= 1'b0;
+ store_err_q <= 1'b0;
+ exc_req_q <= 1'b0;
+ illegal_insn_q <= 1'b0;
end else begin
- ctrl_fsm_cs <= ctrl_fsm_ns;
- nmi_mode_q <= nmi_mode_d;
- debug_mode_q <= debug_mode_d;
- enter_debug_mode_q <= enter_debug_mode_d;
- load_err_q <= load_err_d;
- store_err_q <= store_err_d;
- exc_req_q <= exc_req_d;
- illegal_insn_q <= illegal_insn_d;
+ ctrl_fsm_cs <= ctrl_fsm_ns;
+ nmi_mode_q <= nmi_mode_d;
+ do_single_step_q <= do_single_step_d;
+ debug_mode_q <= debug_mode_d;
+ enter_debug_mode_prio_q <= enter_debug_mode_prio_d;
+ load_err_q <= load_err_d;
+ store_err_q <= store_err_d;
+ exc_req_q <= exc_req_d;
+ illegal_insn_q <= illegal_insn_d;
end
end
@@ -853,13 +877,13 @@
logic exception_pc_set, seen_exception_pc_set, expect_exception_pc_set;
logic exception_req_needs_pc_set;
- assign exception_req = (special_req | enter_debug_mode_d | handle_irq);
+ assign exception_req = (special_req | enter_debug_mode | handle_irq);
// Any exception rquest will cause a transition out of DECODE, once the controller transitions
// back into DECODE we're done handling the request.
assign exception_req_done =
exception_req_pending & (ctrl_fsm_cs != DECODE) & (ctrl_fsm_ns == DECODE);
- assign exception_req_needs_pc_set = enter_debug_mode_d | handle_irq | special_req_pc_change;
+ assign exception_req_needs_pc_set = enter_debug_mode | handle_irq | special_req_pc_change;
// An exception PC set uses specific PC types
assign exception_pc_set =
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
index 39ce15d..b423268 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
@@ -349,10 +349,22 @@
end
CSR_MSECCFG: begin
- csr_rdata_int = '0;
- csr_rdata_int[CSR_MSECCFG_MML_BIT] = pmp_mseccfg.mml;
- csr_rdata_int[CSR_MSECCFG_MMWP_BIT] = pmp_mseccfg.mmwp;
- csr_rdata_int[CSR_MSECCFG_RLB_BIT] = pmp_mseccfg.rlb;
+ if (PMPEnable) begin
+ csr_rdata_int = '0;
+ csr_rdata_int[CSR_MSECCFG_MML_BIT] = pmp_mseccfg.mml;
+ csr_rdata_int[CSR_MSECCFG_MMWP_BIT] = pmp_mseccfg.mmwp;
+ csr_rdata_int[CSR_MSECCFG_RLB_BIT] = pmp_mseccfg.rlb;
+ end else begin
+ illegal_csr = 1'b1;
+ end
+ end
+
+ CSR_MSECCFGH: begin
+ if (PMPEnable) begin
+ csr_rdata_int = '0;
+ end else begin
+ illegal_csr = 1'b1;
+ end
end
// PMP registers
@@ -564,6 +576,9 @@
// Read-only for SW
dcsr_d.cause = dcsr_q.cause;
+ // Interrupts always disabled during single stepping
+ dcsr_d.stepie = 1'b0;
+
// currently not supported:
dcsr_d.nmip = 1'b0;
dcsr_d.mprven = 1'b0;
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv
index b982c50..dcff9df 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv
@@ -368,6 +368,7 @@
CSR_MIP = 12'h344,
CSR_MSECCFG = 12'h390,
+ CSR_MSECCFGH = 12'h391,
// Physical memory protection
CSR_PMPCFG0 = 12'h3A0,