pub fn prepare_epmp(jtag: &mut dyn Jtag) -> Result<()>
Expand description

Set up the ePMP to enable read/write/execute from SRAM and read/write access to the full MMIO region. Specifically, this function will:

  1. set the PMP entry 15 to NAPOT to cover the SRAM as RWX
  2. set the PMP entry 11 to TOR to cover the MMIO region as RW.

This follows the memory layout used by the ROM 0.

The Ibex core is initialized with a default ePMP configuration 3 when it starts. This configuration has no PMP entry for the RAM, only partial access to the MMIO region (e.g., RV_PLIC access is denied), and mseccfg.mmwp is set to 1 so accesses that don’t match a PMP entry will be denied.

Before transferring the SRAM program to the device, we must configure the PMP unit to enable reading, writing, and executing from SRAM, and reading and writing to the entire MMIO region. Due to implementation details of OpenTitan’s hardware debug module, it is important that the RV_ROM remains accessible at all times 1. It uses entry 13 of the PMP on boot so we want to preserve that. However, we can safely modify the other PMP configuration registers.

In more detail, the problem is that our debug module implements the “Access Register” abstract command by assembling instructions in the program buffer and then executing the buffer. If one of those instructions clobbers the PMP configuration register that allows execution from the program buffer (PMP entry 13), subsequent instruction fetches will generate exceptions.

Debug module concepts like abstract commands and the program buffer are defined in “RISC-V External Debug Support Version 0.13.2” 2. OpenTitan’s (vendored-in) implementation lives in hw/vendor/pulp_riscv_dbg.