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 2c39c0a6a5
commit d7fa0903bc
2 changed files with 34 additions and 12 deletions

View File

@ -34,7 +34,11 @@ module pmpadrdec (
input logic [31:0] HADDR,
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
);
@ -44,18 +48,22 @@ module pmpadrdec (
logic TORMatch, NA4Match, NAPOTMatch;
logic [31:0] PreviousAdrFull, CurrentAdrFull;
logic AdrBelowCurrentPMP;
logic [31:0] CurrentAdrFull;
// logic [31:0] PreviousAdrFull;
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};
// Top-of-range (TOR)
// *** Check if this synthesizes
// if not, literally do comparison (HADDR - PreviousAdrFull == 0)
assign TORMatch = HADDR inside {[PreviousAdrFull:CurrentAdrFull]};
// *** cut number of comparators in half (treat entire pmp space as TOR and have 16 comparators)
assign AdrBelowCurrentPMP = HADDR < CurrentAdrFull;
assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
// Naturally aligned four-byte region
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 [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15],
input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [15:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
@ -58,6 +58,10 @@ module pmpchecker (
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 InvalidExecute, InvalidWrite, InvalidRead;
@ -67,16 +71,20 @@ module pmpchecker (
assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW;
pmpadrdec pmpadrdec0(HADDR, PMPCFG[0][4:3],
'0, PMPADDR_ARRAY_REGW[0],
Regions[0]);
pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[0][4:3]),
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
.AdrAtLeastPreviousPMP(1'b1),
.AdrAtLeastCurrentPMP(AboveRegion[0]),
.Match(Regions[0]));
generate
genvar i;
for (i = 1; i < 16; i++) begin
pmpadrdec pmpadrdec(HADDR, PMPCFG[i][4:3],
PMPADDR_ARRAY_REGW[i-1], PMPADDR_ARRAY_REGW[i],
Regions[i]);
pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[i][4:3]),
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
.AdrAtLeastPreviousPMP(AboveRegion[i-1]),
.AdrAtLeastCurrentPMP(AboveRegion[i]),
.Match(Regions[i]));
end
endgenerate
@ -112,6 +120,7 @@ module pmpchecker (
assign InvalidWrite = WriteAccessM && ~W_Bit;
assign InvalidRead = ReadAccessM && ~R_Bit;
/*
assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidExecute :
~Match || InvalidExecute;
@ -121,6 +130,11 @@ module pmpchecker (
assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && 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