Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make PMP disableable #2692

Merged
merged 9 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,8 @@ module cva6
logic acc_cons_en_csr;
logic debug_mode;
logic single_step_csr_commit;
riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg;
logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr;
riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg;
logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr;
logic [31:0] mcountinhibit_csr_perf;
// ----------------------------
// Performance Counters <-> *
Expand Down
5 changes: 1 addition & 4 deletions core/cva6_mmu/cva6_ptw.sv
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,7 @@ module cva6_ptw


pmp #(
.CVA6Cfg (CVA6Cfg),
.PLEN (CVA6Cfg.PLEN),
.PMP_LEN (CVA6Cfg.PLEN - 2),
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
.CVA6Cfg(CVA6Cfg)
) i_pmp_ptw (
.addr_i (ptw_pptr_q),
// PTW access are always checked as if in S-Mode...
Expand Down
4 changes: 2 additions & 2 deletions core/ex_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ module ex_stage
// To count the data TLB misses - PERF_COUNTERS
output logic dtlb_miss_o,
// Report the PMP configuration - CSR_REGFILE
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i,
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
// Report the PMP addresses - CSR_REGFILE
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
// Information dedicated to RVFI - RVFI
output lsu_ctrl_t rvfi_lsu_ctrl_o,
// Information dedicated to RVFI - RVFI
Expand Down
4 changes: 2 additions & 2 deletions core/load_store_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ module load_store_unit
input amo_resp_t amo_resp_i,

// PMP configuration - CSR_REGFILE
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i,
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
// PMP address - CSR_REGFILE
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,

// RVFI inforamtion - RVFI
output lsu_ctrl_t rvfi_lsu_ctrl_o,
Expand Down
27 changes: 11 additions & 16 deletions core/pmp/src/pmp.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,29 @@
// Description: purely combinatorial PMP unit (with extraction for more complex configs such as NAPOT)

module pmp #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter int unsigned PLEN = 34, // rv64: 56
parameter int unsigned PMP_LEN = 32, // rv64: 54
parameter int unsigned NR_ENTRIES = 4
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty
) (
// Input
input logic [PLEN-1:0] addr_i,
input logic [CVA6Cfg.PLEN-1:0] addr_i,
input riscv::pmp_access_t access_type_i,
input riscv::priv_lvl_t priv_lvl_i,
// Configuration
input logic [NR_ENTRIES-1:0][PMP_LEN-1:0] conf_addr_i,
input riscv::pmpcfg_t [NR_ENTRIES-1:0] conf_i,
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] conf_addr_i,
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] conf_i,
// Output
output logic allow_o
);
// if there are no PMPs we can always grant the access.
if (NR_ENTRIES > 0) begin : gen_pmp
logic [NR_ENTRIES-1:0] match;
if (CVA6Cfg.NrPMPEntries > 0) begin : gen_pmp
logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] match;

for (genvar i = 0; i < NR_ENTRIES; i++) begin
logic [PMP_LEN-1:0] conf_addr_prev;
for (genvar i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin
logic [CVA6Cfg.PLEN-3:0] conf_addr_prev;

assign conf_addr_prev = (i == 0) ? '0 : conf_addr_i[i-1];

pmp_entry #(
.CVA6Cfg(CVA6Cfg),
.PLEN (PLEN),
.PMP_LEN(PMP_LEN)
.CVA6Cfg(CVA6Cfg)
) i_pmp_entry (
.addr_i (addr_i),
.conf_addr_i (conf_addr_i[i]),
Expand All @@ -54,7 +49,7 @@ module pmp #(
int i;

allow_o = 1'b0;
for (i = 0; i < NR_ENTRIES; i++) begin
for (i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin
// either we are in S or U mode or the config is locked in which
// case it also applies in M mode
if (priv_lvl_i != riscv::PRIV_LVL_M || conf_i[i].locked) begin
Expand All @@ -65,7 +60,7 @@ module pmp #(
end
end
end
if (i == NR_ENTRIES) begin // no PMP entry matched the address
if (i == CVA6Cfg.NrPMPEntries) begin // no PMP entry matched the address
// allow all accesses from M-mode for no pmp match
if (priv_lvl_i == riscv::PRIV_LVL_M) allow_o = 1'b1;
// disallow accesses for all other modes
Expand Down
14 changes: 4 additions & 10 deletions core/pmp/src/pmp_data_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ module pmp_data_if
input riscv::priv_lvl_t ld_st_priv_lvl_i,
input logic ld_st_v_i,
// PMP
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i
);
// virtual address causing the exception
logic [CVA6Cfg.XLEN-1:0] fetch_vaddr_xlen, lsu_vaddr_xlen;
Expand Down Expand Up @@ -96,10 +96,7 @@ module pmp_data_if

// Instruction fetch
pmp #(
.CVA6Cfg (CVA6Cfg),
.PLEN (CVA6Cfg.PLEN),
.PMP_LEN (CVA6Cfg.PLEN - 2),
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
.CVA6Cfg(CVA6Cfg)
) i_pmp_if (
.addr_i (icache_areq_i.fetch_paddr),
.priv_lvl_i (priv_lvl_i),
Expand Down Expand Up @@ -144,10 +141,7 @@ module pmp_data_if

// Load/store PMP check
pmp #(
.CVA6Cfg (CVA6Cfg),
.PLEN (CVA6Cfg.PLEN),
.PMP_LEN (CVA6Cfg.PLEN - 2),
.NR_ENTRIES(CVA6Cfg.NrPMPEntries)
.CVA6Cfg(CVA6Cfg)
) i_pmp_data (
.addr_i (lsu_paddr_i),
.priv_lvl_i (ld_st_priv_lvl_i),
Expand Down
24 changes: 12 additions & 12 deletions core/pmp/src/pmp_entry.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@ module pmp_entry #(
parameter int unsigned PMP_LEN = 54
) (
// Input
input logic [PLEN-1:0] addr_i,
input logic [CVA6Cfg.PLEN-1:0] addr_i,

// Configuration
input logic [PMP_LEN-1:0] conf_addr_i,
input logic [PMP_LEN-1:0] conf_addr_prev_i,
input logic [CVA6Cfg.PLEN-3:0] conf_addr_i,
input logic [CVA6Cfg.PLEN-3:0] conf_addr_prev_i,
input riscv::pmp_addr_mode_t conf_addr_mode_i,

// Output
output logic match_o
);
logic [PLEN-1:0] conf_addr_n;
logic [$clog2(PLEN)-1:0] trail_ones;
logic [PLEN-1:0] base;
logic [PLEN-1:0] mask;
logic [CVA6Cfg.PLEN-1:0] conf_addr_n;
logic [$clog2(CVA6Cfg.PLEN)-1:0] trail_ones;
logic [CVA6Cfg.PLEN-1:0] base;
logic [CVA6Cfg.PLEN-1:0] mask;
int unsigned size;
assign conf_addr_n = {2'b11, ~conf_addr_i};
lzc #(
.WIDTH(PLEN),
.WIDTH(CVA6Cfg.PLEN),
.MODE (1'b0)
) i_lzc (
.in_i (conf_addr_n),
Expand Down Expand Up @@ -67,7 +67,7 @@ module pmp_entry #(
riscv::NAPOT: begin

// use the extracted trailing ones
size = {{(32 - $clog2(PLEN)) {1'b0}}, trail_ones} + 3;
size = {{(32 - $clog2(CVA6Cfg.PLEN)) {1'b0}}, trail_ones} + 3;

mask = '1 << size;
base = ({2'b0, conf_addr_i} << 2) & mask;
Expand All @@ -78,15 +78,15 @@ module pmp_entry #(
assert (size >= 2);
if (conf_addr_mode_i == riscv::NAPOT) begin
assert (size > 2);
if (size < PMP_LEN) assert (conf_addr_i[size-3] == 0);
for (int i = 0; i < PMP_LEN; i++) begin
if (size < CVA6Cfg.PLEN-2) assert (conf_addr_i[size-3] == 0);
for (int i = 0; i < CVA6Cfg.PLEN-2; i++) begin
JeanRochCoulon marked this conversation as resolved.
Show resolved Hide resolved
if (size > 3 && i <= size - 4) begin
assert (conf_addr_i[i] == 1); // check that all the rest are ones
end
end
end

if (size < PLEN - 1) begin
if (size < CVA6Cfg.PLEN - 1) begin
if (base + 2 ** size > base) begin // check for overflow
if (match_o == 0) begin
assert (addr_i >= base + 2 ** size || addr_i < base);
Expand Down
Loading