Add option to hardwire PMP regions, or reduce their granularity
This commit is contained in:
parent
b823132a6e
commit
e0a9fb7312
|
@ -34,7 +34,7 @@ parameter RESET_VECTOR = 32'h0,
|
|||
parameter MTVEC_INIT = 32'h00000000,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RISC-V ISA and CSR support
|
||||
// RISC-V ISA support
|
||||
|
||||
// EXTENSION_A: Support for atomic read/modify/write instructions
|
||||
parameter EXTENSION_A = 1,
|
||||
|
@ -65,7 +65,11 @@ parameter EXTENSION_ZBKB = 1,
|
|||
// Optional, since a plain branch/jump will also flush the prefetch queue.
|
||||
parameter EXTENSION_ZIFENCEI = 1,
|
||||
|
||||
// Note the Zicsr extension is implied by any of the following CSR support:
|
||||
// Note the Zicsr extension is implied by any of CSR_M_MANDATORY, CSR_M_TRAP,
|
||||
// CSR_COUNTER.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CSR support
|
||||
|
||||
// CSR_M_MANDATORY: Bare minimum CSR support e.g. misa. Spec says must = 1 if
|
||||
// CSRs are present, but I won't tell anyone.
|
||||
|
@ -88,6 +92,30 @@ parameter U_MODE = 0,
|
|||
// PMP is more useful if U mode is supported, but this is not a requirement.
|
||||
parameter PMP_REGIONS = 0,
|
||||
|
||||
// PMPADDR_WRITE_MASK: mask of which pmpaddr bits are writable. Can reduce
|
||||
// region granularity, or create hardwired regions. If a register is
|
||||
// partially writable, it's recommended to set PMP_NO_NA4 for that region, so
|
||||
// that PMPCFG.A only permits OFF and NAPOT values.
|
||||
parameter PMPADDR_WRITE_MASK = PMP_REGIONS > 0 ? {PMP_REGIONS{~32'h0}} : 1'b0,
|
||||
|
||||
// PMPADDR_RESET_VAL: provide reset values for pmpaddr registers. The
|
||||
// highest-numbered PMP register is listed first in this mask. Note that
|
||||
// RISC-V pmpaddr registers are a right-shift by 2 of the physical address.
|
||||
parameter PMPADDR_RESET_VAL = PMP_REGIONS > 0 ? {PMP_REGIONS{32'h0}} : 1'b0,
|
||||
|
||||
// PMPCFG_WRITE_MASK: mask of which pmpcfg bits are writable. The reserved
|
||||
// bits [6:5] are ignored, and will never be writable.
|
||||
parameter PMPCFG_WRITE_MASK = PMP_REGIONS > 0 ? {PMP_REGIONS{8'hff}} : 1'b0,
|
||||
|
||||
// PMPCFG_RESET_VAL: reset values for pmpcfg registers. For regions that are
|
||||
// not fully hardwired, it's recommended to initialise A and L to 0.
|
||||
parameter PMPCFG_RESET_VAL = PMP_REGIONS > 0 ? {PMP_REGIONS{8'h00}} : 1'b0,
|
||||
|
||||
// PMP_CFG_NO_NA4: disable support for the NA4 region type on a per-region
|
||||
// basis, making the minimum region size 8 bytes. Recommended if the pmpaddr
|
||||
// register has had its LSBs tied off.
|
||||
parameter PMPCFG_NO_NA4 = PMP_REGIONS > 0 ? {PMP_REGIONS{1'b0}} : 1'b0,
|
||||
|
||||
// DEBUG_SUPPORT: Support for run/halt and instruction injection from an
|
||||
// external Debug Module, support for Debug Mode, and Debug Mode CSRs.
|
||||
// Requires: CSR_M_MANDATORY, CSR_M_TRAP.
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
.CSR_COUNTER (CSR_COUNTER),
|
||||
.U_MODE (U_MODE),
|
||||
.PMP_REGIONS (PMP_REGIONS),
|
||||
.PMPADDR_WRITE_MASK (PMPADDR_WRITE_MASK),
|
||||
.PMPADDR_RESET_VAL (PMPADDR_RESET_VAL),
|
||||
.PMPCFG_WRITE_MASK (PMPCFG_WRITE_MASK),
|
||||
.PMPCFG_RESET_VAL (PMPCFG_RESET_VAL),
|
||||
.PMPCFG_NO_NA4 (PMPCFG_NO_NA4),
|
||||
.DEBUG_SUPPORT (DEBUG_SUPPORT),
|
||||
.NUM_IRQ (NUM_IRQ),
|
||||
.MVENDORID_VAL (MVENDORID_VAL),
|
||||
|
|
|
@ -57,28 +57,44 @@ always @ (posedge clk or negedge rst_n) begin: cfg_update
|
|||
integer i;
|
||||
if (!rst_n) begin
|
||||
for (i = 0; i < PMP_REGIONS; i = i + 1) begin
|
||||
pmpcfg_l[i] <= 1'b0;
|
||||
pmpcfg_a[i] <= 2'd0;
|
||||
pmpcfg_r[i] <= 1'b0;
|
||||
pmpcfg_w[i] <= 1'b0;
|
||||
pmpcfg_x[i] <= 1'b0;
|
||||
pmpaddr[i] <= {W_ADDR-2{1'b0}};
|
||||
pmpcfg_l[i] <= PMPCFG_RESET_VAL[8 * i + 7];
|
||||
pmpcfg_a[i] <= PMPCFG_RESET_VAL[8 * i + 3 +: 2];
|
||||
pmpcfg_r[i] <= PMPCFG_RESET_VAL[8 * i + 2];
|
||||
pmpcfg_w[i] <= PMPCFG_RESET_VAL[8 * i + 1];
|
||||
pmpcfg_x[i] <= PMPCFG_RESET_VAL[8 * i + 0];
|
||||
pmpaddr[i] <= PMPADDR_RESET_VAL[32 * i +: 30];
|
||||
end
|
||||
end else if (cfg_wen) begin
|
||||
for (i = 0; i < PMP_REGIONS; i = i + 1) begin
|
||||
if (cfg_addr == PMPCFG0 + i / 4 && !pmpcfg_l[i]) begin
|
||||
pmpcfg_l[i] <= cfg_wdata[i % 4 * 8 + 7];
|
||||
// TOR is not supported, gets mapped to OFF:
|
||||
pmpcfg_a[i] <= {
|
||||
cfg_wdata[i % 4 * 8 + 4],
|
||||
cfg_wdata[i % 4 * 8 + 3] && cfg_wdata[i % 4 * 8 + 4]
|
||||
};
|
||||
pmpcfg_r[i] <= cfg_wdata[i % 4 * 8 + 2];
|
||||
pmpcfg_w[i] <= cfg_wdata[i % 4 * 8 + 1];
|
||||
pmpcfg_x[i] <= cfg_wdata[i % 4 * 8 + 0];
|
||||
|
||||
if (PMPCFG_WRITE_MASK[i * 8 + 7])
|
||||
pmpcfg_l[i] <= cfg_wdata[i % 4 * 8 + 7];
|
||||
|
||||
// Unsupported A values are mapped to OFF (it's a WARL field).
|
||||
pmpcfg_a[i] <=
|
||||
cfg_wdata[i % 4 * 8 + 3 +: 2] == PMP_A_TOR ? PMP_A_OFF :
|
||||
cfg_wdata[i % 4 * 8 + 3 +: 2] == PMP_A_NA4 && PMPCFG_NO_NA4[i] ? PMP_A_OFF :
|
||||
cfg_wdata[i % 4 * 8 + 3 +: 2];
|
||||
|
||||
// Suppress changes to unwritable bits.
|
||||
if (!PMPCFG_WRITE_MASK[i * 8 + 4])
|
||||
pmpcfg_a[i][1] <= pmpcfg_a[i][1];
|
||||
if (!PMPCFG_WRITE_MASK[i * 8 + 3])
|
||||
pmpcfg_a[i][0] <= pmpcfg_a[i][0];
|
||||
|
||||
if (PMPCFG_WRITE_MASK[i * 8 + 2])
|
||||
pmpcfg_r[i] <= cfg_wdata[i % 4 * 8 + 2];
|
||||
if (PMPCFG_WRITE_MASK[i * 8 + 1])
|
||||
pmpcfg_w[i] <= cfg_wdata[i % 4 * 8 + 1];
|
||||
if (PMPCFG_WRITE_MASK[i * 8 + 0])
|
||||
pmpcfg_x[i] <= cfg_wdata[i % 4 * 8 + 0];
|
||||
|
||||
end
|
||||
if (cfg_addr == PMPADDR0 + i && !pmpcfg_l[i]) begin
|
||||
pmpaddr[i] <= cfg_wdata[W_ADDR-3:0];
|
||||
pmpaddr[i] <=
|
||||
cfg_wdata[W_ADDR-3:0] & PMPADDR_WRITE_MASK[i * 32 +: 30] |
|
||||
pmpaddr[i] & ~PMPADDR_WRITE_MASK[i * 32 +: 30];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -227,7 +243,7 @@ always @ (*) begin: check_i_match
|
|||
i_x = pmpcfg_x[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Access rules
|
||||
|
|
Loading…
Reference in New Issue