Simplified bad PTE detection

This commit is contained in:
David Harris 2021-07-17 03:30:17 -04:00
parent ac67342dd4
commit 5698433463

View File

@ -88,7 +88,7 @@ module pagetablewalker
logic Dirty, Accessed, Global, User, logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid; Executable, Writable, Readable, Valid;
// PTE descriptions // PTE descriptions
logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE; logic ValidPTE, ADPageFault, MegapageMisaligned, BadMegapage, LeafPTE;
// Outputs of walker // Outputs of walker
logic [`XLEN-1:0] PageTableEntry; logic [`XLEN-1:0] PageTableEntry;
@ -134,7 +134,7 @@ module pagetablewalker
flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ});
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState);
flopenr #(`XLEN) ptereg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
@ -150,7 +150,7 @@ module pagetablewalker
// Assign PTE descriptors common across all XLEN values // Assign PTE descriptors common across all XLEN values
assign LeafPTE = Executable | Writable | Readable; assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid && ~(Writable && ~Readable); assign ValidPTE = Valid && ~(Writable && ~Readable);
assign AccessAlert = ~Accessed | (MemStore & ~Dirty); assign ADPageFault = ~Accessed | (MemStore & ~Dirty);
// Assign specific outputs to general outputs // Assign specific outputs to general outputs
assign PageTableEntryF = PageTableEntry; assign PageTableEntryF = PageTableEntry;
@ -159,6 +159,11 @@ module pagetablewalker
// generate // generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
logic [9:0] VPN1, VPN0; logic [9:0] VPN1, VPN0;
assign VPN1 = TranslationVAdr[31:22];
assign VPN0 = TranslationVAdr[21:12];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[9:0]);
// State transition logic // State transition logic
@ -208,7 +213,7 @@ module pagetablewalker
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~BadMegapage) begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
end end
@ -239,7 +244,7 @@ module pagetablewalker
end end
LEVEL0: begin LEVEL0: begin
if (ValidPTE & LeafPTE & ~AccessAlert) begin if (ValidPTE & LeafPTE & ~ADPageFault) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
end else begin end else begin
@ -269,12 +274,7 @@ module pagetablewalker
endcase endcase
end end
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[9:0]);
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign VPN1 = TranslationVAdr[31:22];
assign VPN0 = TranslationVAdr[21:12];
@ -286,8 +286,20 @@ module pagetablewalker
end else begin end else begin
logic [8:0] VPN3, VPN2, VPN1, VPN0; logic [8:0] VPN3, VPN2, VPN1, VPN0;
assign VPN3 = TranslationVAdr[47:39];
assign VPN2 = TranslationVAdr[38:30];
assign VPN1 = TranslationVAdr[29:21];
assign VPN0 = TranslationVAdr[20:12];
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage; logic TerapageMisaligned, GigapageMisaligned;
// A terapage is a level 3 leaf page. This page must have zero PPN[2],
// zero PPN[1], and zero PPN[0]
assign TerapageMisaligned = |(CurrentPPN[26:0]);
// A gigapage is a Level 2 leaf page. This page must have zero PPN[1] and
// zero PPN[0]
assign GigapageMisaligned = |(CurrentPPN[17:0]);
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[8:0]);
always_comb begin always_comb begin
PRegEn = 1'b0; PRegEn = 1'b0;
@ -337,7 +349,7 @@ module pagetablewalker
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~BadTerapage) begin if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end end
@ -371,7 +383,7 @@ module pagetablewalker
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~BadGigapage) begin if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end end
@ -405,7 +417,7 @@ module pagetablewalker
// fault upon finding a superpage that is misaligned or has 0 // fault upon finding a superpage that is misaligned or has 0
// access bit. The following commented line of code is // access bit. The following commented line of code is
// supposed to perform that check. However, it is untested. // supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~BadMegapage) begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
@ -436,7 +448,7 @@ module pagetablewalker
end end
LEVEL0: begin LEVEL0: begin
if (ValidPTE && LeafPTE && ~AccessAlert) begin if (ValidPTE && LeafPTE && ~ADPageFault) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end else begin end else begin
@ -471,23 +483,6 @@ module pagetablewalker
endcase endcase
end end
// A terapage is a level 3 leaf page. This page must have zero PPN[2],
// zero PPN[1], and zero PPN[0]
assign TerapageMisaligned = |(CurrentPPN[26:0]);
// A gigapage is a Level 2 leaf page. This page must have zero PPN[1] and
// zero PPN[0]
assign GigapageMisaligned = |(CurrentPPN[17:0]);
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[8:0]);
assign BadTerapage = TerapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign VPN3 = TranslationVAdr[47:39];
assign VPN2 = TranslationVAdr[38:30];
assign VPN1 = TranslationVAdr[29:21];
assign VPN0 = TranslationVAdr[20:12];
// *** Major issue. We need the full virtual address here. // *** Major issue. We need the full virtual address here.
// When the TLB's are update it use use the orignal address // When the TLB's are update it use use the orignal address