mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Changed IMMU ExecuteAccessF to 1 rather than InstrReadF to fix buildroot; simplified PMP checker
This commit is contained in:
parent
d44916dacf
commit
1fa4abf7b6
@ -146,6 +146,7 @@ module ahblite (
|
||||
// (ProposedNextBusState == MMUTRANSLATE);
|
||||
|
||||
// The PMA and PMP checkers can decide to squash the access
|
||||
// *** this probably needs to be controlled by the caches rather than EBU dh 7/2/11
|
||||
assign NextBusState = (DSquashBusAccessM || ISquashBusAccessF) ? IDLE : ProposedNextBusState;
|
||||
|
||||
// stall signals
|
||||
|
@ -127,7 +127,7 @@ module ifu (
|
||||
.TLBMiss(ITLBMissF),
|
||||
.TLBHit(ITLBHitF),
|
||||
.TLBPageFault(ITLBInstrPageFaultF),
|
||||
.ExecuteAccessF(InstrReadF), /// *** Ross Thompson this is definitely wrong. InstrReadF changed to icache read to memory.
|
||||
.ExecuteAccessF(1'b1), // ***dh -- this should eventually change to only true if an instruction fetch is occurring
|
||||
.AtomicAccessM(1'b0),
|
||||
.ReadAccessM(1'b0),
|
||||
.WriteAccessM(1'b0),
|
||||
|
@ -31,20 +31,29 @@
|
||||
|
||||
module pmpadrdec (
|
||||
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||
input logic [1:0] AdrMode,
|
||||
input logic [`XLEN-1:0] CurrentPMPAdr,
|
||||
input logic AdrAtLeastPreviousPMP,
|
||||
output logic AdrAtLeastCurrentPMP,
|
||||
output logic Match
|
||||
input logic [7:0] PMPCfg,
|
||||
input logic [`XLEN-1:0] PMPAdr,
|
||||
input logic PAgePMPAdrIn,
|
||||
input logic NoLowerMatchIn,
|
||||
output logic PAgePMPAdrOut,
|
||||
output logic NoLowerMatchOut,
|
||||
output logic Match, Active,
|
||||
output logic L, X, W, R
|
||||
);
|
||||
|
||||
|
||||
localparam TOR = 2'b01;
|
||||
localparam NA4 = 2'b10;
|
||||
localparam NAPOT = 2'b11;
|
||||
|
||||
logic TORMatch, NAMatch;
|
||||
logic AdrBelowCurrentPMP;
|
||||
logic PAltPMPAdr;
|
||||
logic FirstMatch;
|
||||
logic [`PA_BITS-1:0] CurrentAdrFull;
|
||||
logic [1:0] AdrMode;
|
||||
|
||||
|
||||
assign AdrMode = PMPCfg[4:3];
|
||||
|
||||
// The two lsb of the physical address don't matter for this checking.
|
||||
// The following code includes them, but hardwires the PMP checker lsbs to 00
|
||||
@ -52,10 +61,10 @@ module pmpadrdec (
|
||||
|
||||
// Top-of-range (TOR)
|
||||
// Append two implicit trailing 0's to PMPAdr value
|
||||
assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00};
|
||||
assign AdrBelowCurrentPMP = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
|
||||
assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
|
||||
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
|
||||
assign CurrentAdrFull = {PMPAdr[`PA_BITS-3:0], 2'b00};
|
||||
assign PAltPMPAdr = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
|
||||
assign PAgePMPAdrOut = ~PAltPMPAdr;
|
||||
assign TORMatch = PAgePMPAdrIn && PAltPMPAdr;
|
||||
|
||||
// Naturally aligned regions
|
||||
|
||||
@ -68,7 +77,7 @@ module pmpadrdec (
|
||||
assign Mask[1:0] = 2'b11;
|
||||
assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region
|
||||
for (i=3; i < `PA_BITS; i=i+1)
|
||||
assign Mask[i] = Mask[i-1] & CurrentPMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore
|
||||
assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore
|
||||
endgenerate
|
||||
// verilator lint_on UNOPTFLAT
|
||||
|
||||
@ -78,5 +87,12 @@ module pmpadrdec (
|
||||
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch :
|
||||
0;
|
||||
|
||||
endmodule
|
||||
assign FirstMatch = NoLowerMatchIn & Match;
|
||||
assign NoLowerMatchOut = NoLowerMatchIn & ~Match;
|
||||
assign L = PMPCfg[7] & FirstMatch;
|
||||
assign X = PMPCfg[2] & FirstMatch;
|
||||
assign W = PMPCfg[1] & FirstMatch;
|
||||
assign R = PMPCfg[0] & FirstMatch;
|
||||
assign Active = |PMPCfg[4:3];
|
||||
endmodule
|
||||
|
||||
|
@ -51,76 +51,49 @@ module pmpchecker (
|
||||
output logic PMPStoreAccessFaultM
|
||||
);
|
||||
|
||||
// verilator lint_off UNOPTFLAT
|
||||
|
||||
// Bit i is high when the address falls in PMP region i
|
||||
logic [`PMP_ENTRIES-1:0] Regions, FirstMatch;
|
||||
logic EnforcePMP;
|
||||
|
||||
logic [7:0] PMPCFG [`PMP_ENTRIES-1:0];
|
||||
|
||||
// Bit i is high when the address is greater than or equal to PMPADR[i]
|
||||
// Used for determining whether TOR PMP regions match
|
||||
logic [`PMP_ENTRIES-1:0] AboveRegion;
|
||||
|
||||
// Bit i is high if PMP register i is non-null
|
||||
logic [`PMP_ENTRIES-1:0] ActiveRegion;
|
||||
|
||||
logic [`PMP_ENTRIES-1:0] L_Bits, X_Bits, W_Bits, R_Bits;
|
||||
|
||||
logic EnforcePMP;
|
||||
logic [7:0] PMPCFG [`PMP_ENTRIES-1:0];
|
||||
logic [`PMP_ENTRIES-1:0] Match; // PMP Entry matches
|
||||
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null
|
||||
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
|
||||
logic [`PMP_ENTRIES:0] NoLowerMatch; // None of the lower PMP entries match
|
||||
logic [`PMP_ENTRIES:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
|
||||
genvar i,j;
|
||||
|
||||
pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress),
|
||||
.AdrMode(PMPCFG[0][4:3]),
|
||||
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
|
||||
.AdrAtLeastPreviousPMP(1'b1),
|
||||
.AdrAtLeastCurrentPMP(AboveRegion[0]),
|
||||
.Match(Regions[0]));
|
||||
|
||||
assign ActiveRegion[0] = |PMPCFG[0][4:3];
|
||||
|
||||
generate // *** only for PMP_ENTRIES > 0
|
||||
for (i = 1; i < `PMP_ENTRIES; i++) begin
|
||||
pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress),
|
||||
.AdrMode(PMPCFG[i][4:3]),
|
||||
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
|
||||
.AdrAtLeastPreviousPMP(AboveRegion[i-1]),
|
||||
.AdrAtLeastCurrentPMP(AboveRegion[i]),
|
||||
.Match(Regions[i]));
|
||||
|
||||
assign ActiveRegion[i] = |PMPCFG[i][4:3];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// verilator lint_off UNOPTFLAT
|
||||
logic [`PMP_ENTRIES-1:0] NoLowerMatch;
|
||||
assign PAgePMPAdr[0] = 1'b1;
|
||||
assign NoLowerMatch[0] = 1'b1;
|
||||
|
||||
generate
|
||||
// verilator lint_off WIDTH
|
||||
for (j=0; j<`PMP_ENTRIES; j = j+8) begin
|
||||
for (j=0; j<`PMP_ENTRIES; j = j+8)
|
||||
assign {PMPCFG[j+7], PMPCFG[j+6], PMPCFG[j+5], PMPCFG[j+4],
|
||||
PMPCFG[j+3], PMPCFG[j+2], PMPCFG[j+1], PMPCFG[j]} = PMPCFG_ARRAY_REGW[j/8];
|
||||
end
|
||||
// verilator lint_on WIDTH
|
||||
for (i=0; i<`PMP_ENTRIES; i++) begin
|
||||
if (i==0) begin
|
||||
assign FirstMatch[i] = Regions[i];
|
||||
assign NoLowerMatch[i] = ~Regions[i];
|
||||
end else begin
|
||||
assign FirstMatch[i] = Regions[i] & NoLowerMatch[i];
|
||||
assign NoLowerMatch[i] = NoLowerMatch[i-1] & ~Regions[i];
|
||||
end
|
||||
assign L_Bits[i] = PMPCFG[i][7] & FirstMatch[i];
|
||||
assign X_Bits[i] = PMPCFG[i][2] & FirstMatch[i];
|
||||
assign W_Bits[i] = PMPCFG[i][1] & FirstMatch[i];
|
||||
assign R_Bits[i] = PMPCFG[i][0] & FirstMatch[i];
|
||||
end
|
||||
for (i=0; i<`PMP_ENTRIES; i++)
|
||||
pmpadrdec pmpadrdec(.PhysicalAddress,
|
||||
.PMPCfg(PMPCFG[i]),
|
||||
.PMPAdr(PMPADDR_ARRAY_REGW[i]),
|
||||
.PAgePMPAdrIn(PAgePMPAdr[i]),
|
||||
.PAgePMPAdrOut(PAgePMPAdr[i+1]),
|
||||
.NoLowerMatchIn(NoLowerMatch[i]),
|
||||
.NoLowerMatchOut(NoLowerMatch[i+1]),
|
||||
.Match(Match[i]),
|
||||
.Active(Active[i]),
|
||||
.L(L[i]), .X(X[i]), .W(W[i]), .R(R[i])
|
||||
);
|
||||
|
||||
// verilator lint_on UNOPTFLAT
|
||||
endgenerate
|
||||
|
||||
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
|
||||
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L_Bits : |ActiveRegion;
|
||||
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;
|
||||
|
||||
assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X_Bits;
|
||||
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W_Bits;
|
||||
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R_Bits;
|
||||
assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X;
|
||||
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W;
|
||||
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R;
|
||||
|
||||
assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
||||
|
||||
|
@ -74,6 +74,7 @@ module uncore (
|
||||
|
||||
// Determine which region of physical memory (if any) is being accessed
|
||||
// Use a trimmed down portion of the PMA checker - only the address decoders
|
||||
// Set access types to all 1 as don't cares because the MMU has already done access checking
|
||||
adrdecs adrdecs({{(`PA_BITS-32){1'b0}}, HADDR}, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||
|
||||
// unswizzle HSEL signals
|
||||
|
Loading…
Reference in New Issue
Block a user