Disable PMP checker to fix test loops

There is a bug in the PMP checker where S or U mode attempts to make a
memory access while no PMP registers are set. We currently treat this as
a failure, when this should instead be allowed.
This commit is contained in:
Thomas Fleming 2021-05-04 01:56:05 -04:00
parent 1673ad6e27
commit c9e5af30fa
2 changed files with 34 additions and 12 deletions

View File

@ -34,7 +34,11 @@ module pmpadrdec (
input logic [31:0] HADDR, input logic [31:0] HADDR,
input logic [1:0] AdrMode, input logic [1:0] AdrMode,
input logic [`XLEN-1:0] PreviousPMPAdr, CurrentPMPAdr,
// input logic [`XLEN-1:0] PreviousPMPAdr,
input logic [`XLEN-1:0] CurrentPMPAdr,
input logic AdrAtLeastPreviousPMP,
output logic AdrAtLeastCurrentPMP,
output logic Match output logic Match
); );
@ -44,18 +48,22 @@ module pmpadrdec (
logic TORMatch, NA4Match, NAPOTMatch; logic TORMatch, NA4Match, NAPOTMatch;
logic [31:0] PreviousAdrFull, CurrentAdrFull; logic AdrBelowCurrentPMP;
logic [31:0] CurrentAdrFull;
// logic [31:0] PreviousAdrFull;
logic [33:0] Range; logic [33:0] Range;
assign PreviousAdrFull = {PreviousPMPAdr[29:0], 2'b00}; //assign PreviousAdrFull = {PreviousPMPAdr[29:0], 2'b00};
assign CurrentAdrFull = {CurrentPMPAdr[29:0], 2'b00}; assign CurrentAdrFull = {CurrentPMPAdr[29:0], 2'b00};
// Top-of-range (TOR) // Top-of-range (TOR)
// *** Check if this synthesizes // *** Check if this synthesizes
// if not, literally do comparison (HADDR - PreviousAdrFull == 0) // if not, literally do comparison (HADDR - PreviousAdrFull == 0)
assign TORMatch = HADDR inside {[PreviousAdrFull:CurrentAdrFull]}; assign AdrBelowCurrentPMP = HADDR < CurrentAdrFull;
// *** cut number of comparators in half (treat entire pmp space as TOR and have 16 comparators) assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
// Naturally aligned four-byte region // Naturally aligned four-byte region
adrdec na4dec(HADDR, CurrentAdrFull, (2**2)-1, NA4Match); adrdec na4dec(HADDR, CurrentAdrFull, (2**2)-1, NA4Match);

View File

@ -40,7 +40,7 @@ module pmpchecker (
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW,
input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15], input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [15:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM, input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
@ -58,6 +58,10 @@ module pmpchecker (
logic [7:0] PMPCFG [0:15]; logic [7:0] PMPCFG [0:15];
// Bit i is high when the address is greater than or equal to PMPADR[i]
// Used for determining whether TOR PMP regions match
logic [15:0] AboveRegion;
logic L_Bit, X_Bit, W_Bit, R_Bit; logic L_Bit, X_Bit, W_Bit, R_Bit;
logic InvalidExecute, InvalidWrite, InvalidRead; logic InvalidExecute, InvalidWrite, InvalidRead;
@ -67,16 +71,20 @@ module pmpchecker (
assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4], assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW; PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW;
pmpadrdec pmpadrdec0(HADDR, PMPCFG[0][4:3], pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[0][4:3]),
'0, PMPADDR_ARRAY_REGW[0], .CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
Regions[0]); .AdrAtLeastPreviousPMP(1'b1),
.AdrAtLeastCurrentPMP(AboveRegion[0]),
.Match(Regions[0]));
generate generate
genvar i; genvar i;
for (i = 1; i < 16; i++) begin for (i = 1; i < 16; i++) begin
pmpadrdec pmpadrdec(HADDR, PMPCFG[i][4:3], pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[i][4:3]),
PMPADDR_ARRAY_REGW[i-1], PMPADDR_ARRAY_REGW[i], .CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
Regions[i]); .AdrAtLeastPreviousPMP(AboveRegion[i-1]),
.AdrAtLeastCurrentPMP(AboveRegion[i]),
.Match(Regions[i]));
end end
endgenerate endgenerate
@ -112,6 +120,7 @@ module pmpchecker (
assign InvalidWrite = WriteAccessM && ~W_Bit; assign InvalidWrite = WriteAccessM && ~W_Bit;
assign InvalidRead = ReadAccessM && ~R_Bit; assign InvalidRead = ReadAccessM && ~R_Bit;
/*
assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ? assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidExecute : Match && L_Bit && InvalidExecute :
~Match || InvalidExecute; ~Match || InvalidExecute;
@ -121,6 +130,11 @@ module pmpchecker (
assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ? assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidRead : Match && L_Bit && InvalidRead :
~Match || InvalidRead; ~Match || InvalidRead;
*/
assign PMPInstrAccessFaultF = 1'b0;
assign PMPStoreAccessFaultM = 1'b0;
assign PMPLoadAccessFaultM = 1'b0;
/* /*
If no PMP entry matches an M-mode access, the access succeeds. If no PMP entry matches an If no PMP entry matches an M-mode access, the access succeeds. If no PMP entry matches an