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
d3dedc1637
commit
ee605d7550
@ -146,6 +146,7 @@ module ahblite (
|
|||||||
// (ProposedNextBusState == MMUTRANSLATE);
|
// (ProposedNextBusState == MMUTRANSLATE);
|
||||||
|
|
||||||
// The PMA and PMP checkers can decide to squash the access
|
// 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;
|
assign NextBusState = (DSquashBusAccessM || ISquashBusAccessF) ? IDLE : ProposedNextBusState;
|
||||||
|
|
||||||
// stall signals
|
// stall signals
|
||||||
|
@ -127,7 +127,7 @@ module ifu (
|
|||||||
.TLBMiss(ITLBMissF),
|
.TLBMiss(ITLBMissF),
|
||||||
.TLBHit(ITLBHitF),
|
.TLBHit(ITLBHitF),
|
||||||
.TLBPageFault(ITLBInstrPageFaultF),
|
.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),
|
.AtomicAccessM(1'b0),
|
||||||
.ReadAccessM(1'b0),
|
.ReadAccessM(1'b0),
|
||||||
.WriteAccessM(1'b0),
|
.WriteAccessM(1'b0),
|
||||||
|
@ -31,20 +31,29 @@
|
|||||||
|
|
||||||
module pmpadrdec (
|
module pmpadrdec (
|
||||||
input logic [`PA_BITS-1:0] PhysicalAddress,
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic [1:0] AdrMode,
|
input logic [7:0] PMPCfg,
|
||||||
input logic [`XLEN-1:0] CurrentPMPAdr,
|
input logic [`XLEN-1:0] PMPAdr,
|
||||||
input logic AdrAtLeastPreviousPMP,
|
input logic PAgePMPAdrIn,
|
||||||
output logic AdrAtLeastCurrentPMP,
|
input logic NoLowerMatchIn,
|
||||||
output logic Match
|
output logic PAgePMPAdrOut,
|
||||||
|
output logic NoLowerMatchOut,
|
||||||
|
output logic Match, Active,
|
||||||
|
output logic L, X, W, R
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
localparam TOR = 2'b01;
|
localparam TOR = 2'b01;
|
||||||
localparam NA4 = 2'b10;
|
localparam NA4 = 2'b10;
|
||||||
localparam NAPOT = 2'b11;
|
localparam NAPOT = 2'b11;
|
||||||
|
|
||||||
logic TORMatch, NAMatch;
|
logic TORMatch, NAMatch;
|
||||||
logic AdrBelowCurrentPMP;
|
logic PAltPMPAdr;
|
||||||
|
logic FirstMatch;
|
||||||
logic [`PA_BITS-1:0] CurrentAdrFull;
|
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 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
|
// The following code includes them, but hardwires the PMP checker lsbs to 00
|
||||||
@ -52,10 +61,10 @@ module pmpadrdec (
|
|||||||
|
|
||||||
// Top-of-range (TOR)
|
// Top-of-range (TOR)
|
||||||
// Append two implicit trailing 0's to PMPAdr value
|
// Append two implicit trailing 0's to PMPAdr value
|
||||||
assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00};
|
assign CurrentAdrFull = {PMPAdr[`PA_BITS-3:0], 2'b00};
|
||||||
assign AdrBelowCurrentPMP = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
|
assign PAltPMPAdr = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
|
||||||
assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
|
assign PAgePMPAdrOut = ~PAltPMPAdr;
|
||||||
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
|
assign TORMatch = PAgePMPAdrIn && PAltPMPAdr;
|
||||||
|
|
||||||
// Naturally aligned regions
|
// Naturally aligned regions
|
||||||
|
|
||||||
@ -68,7 +77,7 @@ module pmpadrdec (
|
|||||||
assign Mask[1:0] = 2'b11;
|
assign Mask[1:0] = 2'b11;
|
||||||
assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region
|
assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region
|
||||||
for (i=3; i < `PA_BITS; i=i+1)
|
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
|
endgenerate
|
||||||
// verilator lint_on UNOPTFLAT
|
// verilator lint_on UNOPTFLAT
|
||||||
|
|
||||||
@ -78,5 +87,12 @@ module pmpadrdec (
|
|||||||
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch :
|
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch :
|
||||||
0;
|
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
|
output logic PMPStoreAccessFaultM
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// verilator lint_off UNOPTFLAT
|
||||||
|
|
||||||
// Bit i is high when the address falls in PMP region i
|
// Bit i is high when the address falls in PMP region i
|
||||||
logic [`PMP_ENTRIES-1:0] Regions, FirstMatch;
|
logic EnforcePMP;
|
||||||
logic EnforcePMP;
|
logic [7:0] PMPCFG [`PMP_ENTRIES-1:0];
|
||||||
|
logic [`PMP_ENTRIES-1:0] Match; // PMP Entry matches
|
||||||
logic [7:0] PMPCFG [`PMP_ENTRIES-1:0];
|
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
|
||||||
// Bit i is high when the address is greater than or equal to PMPADR[i]
|
logic [`PMP_ENTRIES:0] NoLowerMatch; // None of the lower PMP entries match
|
||||||
// Used for determining whether TOR PMP regions match
|
logic [`PMP_ENTRIES:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
|
||||||
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;
|
|
||||||
|
|
||||||
genvar i,j;
|
genvar i,j;
|
||||||
|
|
||||||
pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress),
|
assign PAgePMPAdr[0] = 1'b1;
|
||||||
.AdrMode(PMPCFG[0][4:3]),
|
assign NoLowerMatch[0] = 1'b1;
|
||||||
.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;
|
|
||||||
generate
|
generate
|
||||||
// verilator lint_off WIDTH
|
// 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],
|
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];
|
PMPCFG[j+3], PMPCFG[j+2], PMPCFG[j+1], PMPCFG[j]} = PMPCFG_ARRAY_REGW[j/8];
|
||||||
end
|
|
||||||
// verilator lint_on WIDTH
|
// verilator lint_on WIDTH
|
||||||
for (i=0; i<`PMP_ENTRIES; i++) begin
|
for (i=0; i<`PMP_ENTRIES; i++)
|
||||||
if (i==0) begin
|
pmpadrdec pmpadrdec(.PhysicalAddress,
|
||||||
assign FirstMatch[i] = Regions[i];
|
.PMPCfg(PMPCFG[i]),
|
||||||
assign NoLowerMatch[i] = ~Regions[i];
|
.PMPAdr(PMPADDR_ARRAY_REGW[i]),
|
||||||
end else begin
|
.PAgePMPAdrIn(PAgePMPAdr[i]),
|
||||||
assign FirstMatch[i] = Regions[i] & NoLowerMatch[i];
|
.PAgePMPAdrOut(PAgePMPAdr[i+1]),
|
||||||
assign NoLowerMatch[i] = NoLowerMatch[i-1] & ~Regions[i];
|
.NoLowerMatchIn(NoLowerMatch[i]),
|
||||||
end
|
.NoLowerMatchOut(NoLowerMatch[i+1]),
|
||||||
assign L_Bits[i] = PMPCFG[i][7] & FirstMatch[i];
|
.Match(Match[i]),
|
||||||
assign X_Bits[i] = PMPCFG[i][2] & FirstMatch[i];
|
.Active(Active[i]),
|
||||||
assign W_Bits[i] = PMPCFG[i][1] & FirstMatch[i];
|
.L(L[i]), .X(X[i]), .W(W[i]), .R(R[i])
|
||||||
assign R_Bits[i] = PMPCFG[i][0] & FirstMatch[i];
|
);
|
||||||
end
|
|
||||||
// verilator lint_on UNOPTFLAT
|
// verilator lint_on UNOPTFLAT
|
||||||
endgenerate
|
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
|
// 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 PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X;
|
||||||
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W_Bits;
|
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W;
|
||||||
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R_Bits;
|
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R;
|
||||||
|
|
||||||
assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ module uncore (
|
|||||||
|
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
// Use a trimmed down portion of the PMA checker - only the address decoders
|
// 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);
|
adrdecs adrdecs({{(`PA_BITS-32){1'b0}}, HADDR}, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||||
|
|
||||||
// unswizzle HSEL signals
|
// unswizzle HSEL signals
|
||||||
|
Loading…
Reference in New Issue
Block a user