Skip to content

Commit

Permalink
Rework the PMP extraction to take the translated/physical address whe…
Browse files Browse the repository at this point in the history
…n CVA6 is instantiated with the MMU
  • Loading branch information
OlivierBetschi committed Nov 19, 2024
1 parent 7b751d8 commit c1521d3
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 182 deletions.
37 changes: 6 additions & 31 deletions core/cva6_mmu/cva6_mmu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,9 @@ module cva6_mmu
output dcache_req_i_t req_port_o,

// PMP
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input logic pmp_instr_allow_i,
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input exception_t pmp_fetch_exception_i,
input exception_t pmp_exception_i,
input exception_t pmp_misaligned_ex_i

input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
);

// memory management, pte for cva6
Expand Down Expand Up @@ -442,8 +438,6 @@ module cva6_mmu
icache_areq_o.fetch_exception.tinst = '0;
icache_areq_o.fetch_exception.gva = v_i;
end
end else if (!pmp_instr_allow_i) begin
icache_areq_o.fetch_exception = pmp_fetch_exception_i;
end
end else if (ptw_active && walking_instr) begin
// ---------//
Expand Down Expand Up @@ -474,7 +468,7 @@ module cva6_mmu
end else begin
icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT;
icache_areq_o.fetch_exception.valid = 1'b1;
if (CVA6Cfg.TvalEn) //To confirm this is the right TVAL
if (CVA6Cfg.TvalEn) //To confirm this is the right TVAL
icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(update_vaddr);
if (CVA6Cfg.RVH) begin
icache_areq_o.fetch_exception.tval2 = '0;
Expand All @@ -484,16 +478,6 @@ module cva6_mmu
end
end
end

// if it didn't match any execute region throw an `Instruction Access Fault`
// or: if we are not translating, check PMPs immediately on the paddr
if ((!match_any_execute_region_i && !ptw_error) || (!(enable_translation_i || enable_g_translation_i) && !pmp_instr_allow_i)) begin
icache_areq_o.fetch_exception = pmp_fetch_exception_i;
if (CVA6Cfg.TvalEn) begin // To confirm this is the right TVAL
if (enable_translation_i || enable_g_translation_i)
icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(update_vaddr);
end
end
end


Expand Down Expand Up @@ -526,7 +510,7 @@ module cva6_mmu
dtlb_is_page_n = dtlb_is_page;

lsu_valid_o = lsu_req_q;
lsu_exception_o = pmp_misaligned_ex_i;
lsu_exception_o = misaligned_ex_i;

// Check if the User flag is set, then we may only access it in supervisor mode
// if SUM is enabled
Expand All @@ -547,7 +531,7 @@ module cva6_mmu
lsu_dtlb_ppn_o = (CVA6Cfg.PPNW)'(lsu_vaddr_n[((CVA6Cfg.PLEN > CVA6Cfg.VLEN) ? CVA6Cfg.VLEN -1: CVA6Cfg.PLEN -1 ):12]);

// translation is enabled and no misaligned exception occurred
if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !pmp_misaligned_ex_i.valid) begin
if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !misaligned_ex_i.valid) begin
lsu_valid_o = 1'b0;

lsu_dtlb_ppn_o = (en_ld_st_g_translation_i && CVA6Cfg.RVH)? dtlb_g_content.ppn :dtlb_content.ppn;
Expand Down Expand Up @@ -606,9 +590,6 @@ module cva6_mmu
lsu_exception_o.tinst = lsu_tinst_q;
lsu_exception_o.gva = ld_st_v_i;
end
// Check if any PMPs are violated
end else if (!pmp_data_allow_i) begin
lsu_exception_o = pmp_exception_i;
end
// this is a load
end else begin
Expand Down Expand Up @@ -637,9 +618,6 @@ module cva6_mmu
lsu_exception_o.tinst = lsu_tinst_q;
lsu_exception_o.gva = ld_st_v_i;
end
// Check if any PMPs are violated
end else if (!pmp_data_allow_i) begin
lsu_exception_o = pmp_exception_i;
end
end
end else
Expand Down Expand Up @@ -735,9 +713,6 @@ module cva6_mmu
end
end
end
// If translation is not enabled, check the paddr immediately against PMPs
end else if (lsu_req_q && !pmp_misaligned_ex_i.valid && !pmp_data_allow_i) begin
lsu_exception_o = pmp_exception_i;
end
end

Expand Down
104 changes: 53 additions & 51 deletions core/load_store_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,15 @@ module load_store_unit
logic translation_req;
logic translation_valid;
logic [CVA6Cfg.VLEN-1:0] mmu_vaddr;
logic [CVA6Cfg.PLEN-1:0] pmp_paddr, mmu_paddr, mmu_vaddr_plen, fetch_vaddr_plen;
logic [CVA6Cfg.PLEN-1:0] mmu_paddr, pmp_paddr, lsu_paddr, mmu_vaddr_plen, fetch_vaddr_plen;
logic [ 31:0] mmu_tinst;
logic mmu_hs_ld_st_inst;
logic mmu_hlvx_inst;
exception_t mmu_exception;
exception_t pmp_exception;
exception_t pmp_misaligned_ex;
icache_areq_t pmp_icache_areq_o;
logic pmp_data_allow;
logic pmp_instr_allow;
icache_areq_t pmp_icache_areq_i;
logic pmp_translation_valid;
logic match_any_execute_region;
logic dtlb_hit;
logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn;

Expand Down Expand Up @@ -263,12 +260,12 @@ module load_store_unit
.clk_i(clk_i),
.rst_ni(rst_ni),
.flush_i(flush_i),
.enable_translation_i,
.enable_g_translation_i,
.en_ld_st_translation_i,
.en_ld_st_g_translation_i,
.enable_translation_i(enable_translation_i),
.enable_g_translation_i(enable_g_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),
.en_ld_st_g_translation_i(en_ld_st_g_translation_i),
.icache_areq_i(icache_areq_i),
.icache_areq_o(icache_areq_o),
.icache_areq_o(pmp_icache_areq_i),
// misaligned bypass
.misaligned_ex_i(misaligned_exception),
.lsu_req_i(translation_req),
Expand All @@ -279,9 +276,9 @@ module load_store_unit
.lsu_dtlb_hit_o(dtlb_hit), // send in the same cycle as the request
.lsu_dtlb_ppn_o(dtlb_ppn), // send in the same cycle as the request

.lsu_valid_o (translation_valid),
.lsu_paddr_o (mmu_paddr),
.lsu_exception_o(mmu_exception),
.lsu_valid_o (pmp_translation_valid),
.lsu_paddr_o (lsu_paddr),
.lsu_exception_o(pmp_exception),

.priv_lvl_i (priv_lvl_i),
.v_i,
Expand Down Expand Up @@ -314,22 +311,35 @@ module load_store_unit
.req_port_i(dcache_req_ports_i[0]),
.req_port_o(dcache_req_ports_o[0]),

.pmp_data_allow_i(pmp_data_allow),
.pmp_instr_allow_i(pmp_instr_allow),
.match_any_execute_region_i(match_any_execute_region),
.pmp_fetch_exception_i(pmp_icache_areq_o.fetch_exception),
.pmp_misaligned_ex_i(pmp_misaligned_ex),
.pmp_exception_i(pmp_exception),
.pmpcfg_i,
.pmpaddr_i
);
end else begin : gen_no_mmu
// icache request without MMU, virtual and physical address are identical
assign pmp_icache_areq_i.fetch_valid = icache_areq_i.fetch_req;
if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_instruction
assign pmp_icache_areq_i.fetch_paddr = icache_areq_i.fetch_vaddr[CVA6Cfg.PLEN-1:0];
end else begin
assign pmp_icache_areq_i.fetch_paddr = CVA6Cfg.PLEN'(icache_areq_i.fetch_vaddr);
end
assign pmp_icache_areq_i.fetch_exception = 'h0;
// dcache request without mmu for load or store,
// Delay of 1 cycle to match MMU latency giving the address tag
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
lsu_paddr <= 'h0;
end else begin
if (CVA6Cfg.VLEN >= CVA6Cfg.PLEN) begin : gen_virtual_physical_address_lsu
lsu_paddr <= mmu_vaddr[CVA6Cfg.PLEN-1:0];
end else begin
lsu_paddr <= CVA6Cfg.PLEN'(mmu_vaddr);
end
end
end
assign pmp_exception = misaligned_exception;
assign pmp_translation_valid = translation_req;

assign mmu_exception = pmp_exception;
assign icache_areq_o = pmp_icache_areq_o;
assign translation_valid = pmp_translation_valid;
assign mmu_paddr = pmp_paddr;

// dcache interface of PTW not used
assign dcache_req_ports_o[0].address_index = '0;
assign dcache_req_ports_o[0].address_tag = '0;
assign dcache_req_ports_o[0].data_wdata = '0;
Expand All @@ -354,35 +364,27 @@ module load_store_unit
pmp_data_if #(
.CVA6Cfg (CVA6Cfg),
.icache_areq_t(icache_areq_t),
.icache_arsp_t(icache_arsp_t),
.exception_t (exception_t)
) i_pmp_data_if (
.clk_i (clk_i),
.rst_ni (rst_ni),
.enable_translation_i (enable_translation_i),
.enable_g_translation_i (enable_g_translation_i),
.en_ld_st_translation_i (en_ld_st_translation_i),
.en_ld_st_g_translation_i (en_ld_st_g_translation_i),
.icache_areq_i (icache_areq_i),
.icache_areq_o (pmp_icache_areq_o),
.misaligned_ex_i (misaligned_exception),
.lsu_req_i (translation_req),
.lsu_vaddr_i (mmu_vaddr),
.lsu_tinst_i (mmu_tinst),
.lsu_is_store_i (st_translation_req),
.lsu_valid_o (pmp_translation_valid),
.lsu_paddr_o (pmp_paddr),
.lsu_exception_o (pmp_exception),
.priv_lvl_i (priv_lvl_i),
.v_i (v_i),
.ld_st_priv_lvl_i (ld_st_priv_lvl_i),
.ld_st_v_i (ld_st_v_i),
.pmpcfg_i (pmpcfg_i),
.pmpaddr_i (pmpaddr_i),
.data_allow_o (pmp_data_allow),
.instr_allow_o (pmp_instr_allow),
.match_any_execute_region_o(match_any_execute_region),
.misaligned_ex_o (pmp_misaligned_ex)
.clk_i (clk_i),
.rst_ni (rst_ni),
.icache_areq_i (pmp_icache_areq_i),
.icache_areq_o (icache_areq_o),
.icache_fetch_vaddr_i(icache_areq_i.fetch_vaddr),
.lsu_valid_i (pmp_translation_valid),
.lsu_paddr_i (lsu_paddr),
.lsu_vaddr_i (mmu_vaddr),
.lsu_exception_i (pmp_exception),
.lsu_is_store_i (st_translation_req),
.lsu_valid_o (translation_valid),
.lsu_paddr_o (mmu_paddr),
.lsu_exception_o (mmu_exception),
.priv_lvl_i (priv_lvl_i),
.v_i (v_i),
.ld_st_priv_lvl_i (ld_st_priv_lvl_i),
.ld_st_v_i (ld_st_v_i),
.pmpcfg_i (pmpcfg_i),
.pmpaddr_i (pmpaddr_i)
);


Expand Down
Loading

0 comments on commit c1521d3

Please sign in to comment.