Add pmpcfgm0 register: make regions M-mode without locking them
This commit is contained in:
parent
65e3d1c48b
commit
92ebbbe95f
|
@ -158,6 +158,9 @@ localparam MENVCFG = 12'h30a;
|
||||||
localparam MENVCFGH = 12'h31a;
|
localparam MENVCFGH = 12'h31a;
|
||||||
|
|
||||||
// Custom M-mode CSRs:
|
// Custom M-mode CSRs:
|
||||||
|
localparam PMPCFGM0 = 12'hbd0; // Make PMP regions M-mode without locking
|
||||||
|
// bd1 // (reserved for >32 regions)
|
||||||
|
|
||||||
localparam MEIEA = 12'hbe0; // External interrupt pending array
|
localparam MEIEA = 12'hbe0; // External interrupt pending array
|
||||||
localparam MEIPA = 12'hbe1; // External interrupt enable array
|
localparam MEIPA = 12'hbe1; // External interrupt enable array
|
||||||
localparam MEIFA = 12'hbe2; // External interrupt force array
|
localparam MEIFA = 12'hbe2; // External interrupt force array
|
||||||
|
|
|
@ -53,6 +53,12 @@ reg pmpcfg_x [0:PMP_REGIONS-1];
|
||||||
// physical address space). We don't implement bits 33 or 32.
|
// physical address space). We don't implement bits 33 or 32.
|
||||||
reg [W_ADDR-3:0] pmpaddr [0:PMP_REGIONS-1];
|
reg [W_ADDR-3:0] pmpaddr [0:PMP_REGIONS-1];
|
||||||
|
|
||||||
|
// Hazard3 extension for applying PMP regions to M-mode without locking.
|
||||||
|
// Different from ePMP mseccfg.rlb: low-numbered regions may be locked for
|
||||||
|
// security reasons, but higher-numbered regions should stll be available for
|
||||||
|
// other purposes e.g. stack guarding, peripheral emulation
|
||||||
|
reg [PMP_REGIONS-1:0] pmpcfg_m;
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin: cfg_update
|
always @ (posedge clk or negedge rst_n) begin: cfg_update
|
||||||
integer i;
|
integer i;
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
|
@ -66,6 +72,7 @@ always @ (posedge clk or negedge rst_n) begin: cfg_update
|
||||||
pmpaddr[i] <= PMP_HARDWIRED[i] ? PMP_HARDWIRED_ADDR[32 * i +: 30] :
|
pmpaddr[i] <= PMP_HARDWIRED[i] ? PMP_HARDWIRED_ADDR[32 * i +: 30] :
|
||||||
PMP_GRAIN > 1 ? ~(~30'h0 << (PMP_GRAIN - 1)) : 30'h0;
|
PMP_GRAIN > 1 ? ~(~30'h0 << (PMP_GRAIN - 1)) : 30'h0;
|
||||||
end
|
end
|
||||||
|
pmpcfg_m <= {PMP_REGIONS{1'b0}};
|
||||||
end else if (cfg_wen) begin
|
end else if (cfg_wen) begin
|
||||||
for (i = 0; i < PMP_REGIONS; i = i + 1) begin
|
for (i = 0; i < PMP_REGIONS; i = i + 1) begin
|
||||||
if (cfg_addr == PMPCFG0 + i / 4 && !pmpcfg_l[i]) begin
|
if (cfg_addr == PMPCFG0 + i / 4 && !pmpcfg_l[i]) begin
|
||||||
|
@ -77,6 +84,7 @@ always @ (posedge clk or negedge rst_n) begin: cfg_update
|
||||||
pmpcfg_w[i] <= PMP_HARDWIRED_CFG[8 * i + 1];
|
pmpcfg_w[i] <= PMP_HARDWIRED_CFG[8 * i + 1];
|
||||||
pmpcfg_x[i] <= PMP_HARDWIRED_CFG[8 * i + 0];
|
pmpcfg_x[i] <= PMP_HARDWIRED_CFG[8 * i + 0];
|
||||||
pmpaddr[i] <= PMP_HARDWIRED_ADDR[32 * i +: 30];
|
pmpaddr[i] <= PMP_HARDWIRED_ADDR[32 * i +: 30];
|
||||||
|
pmpcfgm[i] <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
pmpcfg_l[i] <= cfg_wdata[i % 4 * 8 + 7];
|
pmpcfg_l[i] <= cfg_wdata[i % 4 * 8 + 7];
|
||||||
pmpcfg_r[i] <= cfg_wdata[i % 4 * 8 + 2];
|
pmpcfg_r[i] <= cfg_wdata[i % 4 * 8 + 2];
|
||||||
|
@ -97,6 +105,9 @@ always @ (posedge clk or negedge rst_n) begin: cfg_update
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if (cfg_addr == PMPCFGM0) begin
|
||||||
|
pmpcfg_m <= cfg_wdata[PMP_REGIONS-1:0];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -126,6 +137,9 @@ always @ (*) begin: cfg_read
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if (cfg_addr == PMPCFGM0) begin
|
||||||
|
cfg_rdata = {{32-PMP_REGIONS{1'b0}}, pmpcfg_m};
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -172,6 +186,7 @@ end
|
||||||
// happen, and we choose alignment fault in this case.
|
// happen, and we choose alignment fault in this case.
|
||||||
|
|
||||||
reg d_match;
|
reg d_match;
|
||||||
|
reg d_m; // Hazard3 extension (M-mode without locking)
|
||||||
reg d_l;
|
reg d_l;
|
||||||
reg d_r;
|
reg d_r;
|
||||||
reg d_w;
|
reg d_w;
|
||||||
|
@ -180,6 +195,7 @@ reg d_x; // needed because of MXR
|
||||||
always @ (*) begin: check_d_match
|
always @ (*) begin: check_d_match
|
||||||
integer i;
|
integer i;
|
||||||
d_match = 1'b0;
|
d_match = 1'b0;
|
||||||
|
d_m = 1'b0;
|
||||||
d_l = 1'b0;
|
d_l = 1'b0;
|
||||||
d_r = 1'b0;
|
d_r = 1'b0;
|
||||||
d_w = 1'b0;
|
d_w = 1'b0;
|
||||||
|
@ -189,6 +205,7 @@ always @ (*) begin: check_d_match
|
||||||
for (i = PMP_REGIONS - 1; i >= 0; i = i - 1) begin
|
for (i = PMP_REGIONS - 1; i >= 0; i = i - 1) begin
|
||||||
if (|pmpcfg_a[i] && (d_addr & match_mask[i]) == match_addr[i]) begin
|
if (|pmpcfg_a[i] && (d_addr & match_mask[i]) == match_addr[i]) begin
|
||||||
d_match = 1'b1;
|
d_match = 1'b1;
|
||||||
|
d_m = pmpcfg_m[i];
|
||||||
d_l = pmpcfg_l[i];
|
d_l = pmpcfg_l[i];
|
||||||
d_r = pmpcfg_r[i];
|
d_r = pmpcfg_r[i];
|
||||||
d_w = pmpcfg_w[i];
|
d_w = pmpcfg_w[i];
|
||||||
|
@ -230,6 +247,7 @@ end
|
||||||
|
|
||||||
reg i_match;
|
reg i_match;
|
||||||
reg i_partial_match;
|
reg i_partial_match;
|
||||||
|
reg i_m; // Hazard3 extension (M-mode without locking)
|
||||||
reg i_l;
|
reg i_l;
|
||||||
reg i_x;
|
reg i_x;
|
||||||
|
|
||||||
|
@ -248,6 +266,7 @@ always @ (*) begin: check_i_match
|
||||||
if (match_hw0 || match_hw1) begin
|
if (match_hw0 || match_hw1) begin
|
||||||
i_match = 1'b1;
|
i_match = 1'b1;
|
||||||
i_partial_match = (match_hw0 ^ match_hw1) && i_instr_is_32bit;
|
i_partial_match = (match_hw0 ^ match_hw1) && i_instr_is_32bit;
|
||||||
|
i_m = pmpcfg_m[i];
|
||||||
i_l = pmpcfg_l[i];
|
i_l = pmpcfg_l[i];
|
||||||
i_x = pmpcfg_x[i];
|
i_x = pmpcfg_x[i];
|
||||||
end
|
end
|
||||||
|
@ -259,7 +278,7 @@ end
|
||||||
|
|
||||||
// M-mode gets to ignore protections, unless the lock bit is set.
|
// M-mode gets to ignore protections, unless the lock bit is set.
|
||||||
|
|
||||||
assign d_kill = !(d_m_mode && !d_l) && (
|
assign d_kill = (!d_m_mode || d_l || d_m) && (
|
||||||
(!d_write && !(d_r || (d_x && mstatus_mxr))) ||
|
(!d_write && !(d_r || (d_x && mstatus_mxr))) ||
|
||||||
( d_write && !d_w)
|
( d_write && !d_w)
|
||||||
);
|
);
|
||||||
|
@ -267,7 +286,7 @@ assign d_kill = !(d_m_mode && !d_l) && (
|
||||||
// Straddling a protection boundary is always an error.
|
// Straddling a protection boundary is always an error.
|
||||||
|
|
||||||
assign i_kill = i_partial_match || (
|
assign i_kill = i_partial_match || (
|
||||||
!(i_m_mode && !i_l) && !i_x
|
(!i_m_mode || i_l || i_m) && !i_x
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue