Skip to content

Commit

Permalink
Use physical address from the MMU output as input to PMP instead of v…
Browse files Browse the repository at this point in the history
…irtual address
  • Loading branch information
OlivierBetschi committed Nov 20, 2024
1 parent 45d0176 commit f88bc36
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 219 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
166 changes: 84 additions & 82 deletions core/load_store_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -205,37 +205,34 @@ 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 [ 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;
logic pmp_translation_valid;
logic match_any_execute_region;
logic dtlb_hit;
logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn;

logic ld_valid;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id;
logic [ CVA6Cfg.XLEN-1:0] ld_result;
logic st_valid;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id;
logic [ CVA6Cfg.XLEN-1:0] st_result;

logic [ 11:0] page_offset;
logic page_offset_matches;

exception_t misaligned_exception;
exception_t ld_ex;
exception_t st_ex;

logic hs_ld_st_inst;
logic hlvx_inst;
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_i;
logic pmp_translation_valid;
logic dtlb_hit;
logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn;

logic ld_valid;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id;
logic [ CVA6Cfg.XLEN-1:0] ld_result;
logic st_valid;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id;
logic [ CVA6Cfg.XLEN-1:0] st_result;

logic [ 11:0] page_offset;
logic page_offset_matches;

exception_t misaligned_exception;
exception_t ld_ex;
exception_t st_ex;

logic hs_ld_st_inst;
logic hlvx_inst;

logic [2:0] enable_translation, en_ld_st_translation, flush_tlb;
logic [1:0] sum, mxr;
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 @@ -352,38 +362,30 @@ 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)
);
.CVA6Cfg (CVA6Cfg),
.icache_areq_t(icache_areq_t),
.exception_t (exception_t)
) i_pmp_data_if (
.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)
);


logic store_buffer_empty;
Expand Down
4 changes: 2 additions & 2 deletions core/pmp/src/pmp.sv
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ module pmp #(
input riscv::pmp_access_t access_type_i,
input riscv::priv_lvl_t priv_lvl_i,
// Configuration
input logic [NR_ENTRIES:0][PMP_LEN-1:0] conf_addr_i,
input riscv::pmpcfg_t [NR_ENTRIES:0] conf_i,
input logic [NR_ENTRIES-1:0][PMP_LEN-1:0] conf_addr_i,
input riscv::pmpcfg_t [NR_ENTRIES-1:0] conf_i,
// Output
output logic allow_o
);
Expand Down
Loading

0 comments on commit f88bc36

Please sign in to comment.