From a78b01c0e65740b540e74d34522d9cebc30b9a0e Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 12 Sep 2024 13:41:40 +0100 Subject: [PATCH] Fix SATP mode WARL behaviour SATP mode WARL behaviour is different other WARL fields -- if a write of mode is not recognised, the entire write is ignored. This is used in Linux to detect SV48 support, so it's important to implement the semantics correctly. Signed-off-by: Gary Guo --- ip/pipeline/rtl/muntjac_cs_registers.sv | 13 ++++++++++--- ip/pipeline/rtl/muntjac_pkg.sv | 6 ++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ip/pipeline/rtl/muntjac_cs_registers.sv b/ip/pipeline/rtl/muntjac_cs_registers.sv index 4868a55..d531552 100644 --- a/ip/pipeline/rtl/muntjac_cs_registers.sv +++ b/ip/pipeline/rtl/muntjac_cs_registers.sv @@ -597,9 +597,16 @@ module muntjac_cs_registers import muntjac_pkg::*; # ( if (mideleg_q.irq_software_s) ssip_d = csr_wdata_int[CSR_SSIX_BIT]; end CSR_SATP: begin - satp_mode_d = csr_wdata_int[63]; - satp_asid_d = csr_wdata_int[44 +: AsidLen]; - satp_ppn_d = csr_wdata_int[0 +: PhysAddrLen-12]; + unique case (csr_wdata_int[63:60]) + SATP_MODE_BARE, SATP_MODE_SV39: begin + satp_mode_d = csr_wdata_int[63]; + satp_asid_d = csr_wdata_int[44 +: AsidLen]; + satp_ppn_d = csr_wdata_int[0 +: PhysAddrLen-12]; + end + // When we cannot recongise the mode register, entire CSR + // write needs to be ignored. + default:; + endcase end CSR_MSTATUS: begin diff --git a/ip/pipeline/rtl/muntjac_pkg.sv b/ip/pipeline/rtl/muntjac_pkg.sv index 9663e5d..51daa3a 100644 --- a/ip/pipeline/rtl/muntjac_pkg.sv +++ b/ip/pipeline/rtl/muntjac_pkg.sv @@ -229,6 +229,12 @@ typedef enum logic [1:0] { PRIV_LVL_U = 2'b00 } priv_lvl_e; +// SATP mode +typedef enum logic [3:0] { + SATP_MODE_BARE = 4'd0, + SATP_MODE_SV39 = 4'd8 +} satp_mode_e; + // Status register typedef struct packed { logic tsr;