mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Implement virtual memory protection
This commit is contained in:
parent
82320033d5
commit
70c801331a
@ -47,6 +47,7 @@ module dmem (
|
|||||||
output logic SquashSCW,
|
output logic SquashSCW,
|
||||||
// faults
|
// faults
|
||||||
input logic DataAccessFaultM,
|
input logic DataAccessFaultM,
|
||||||
|
output logic DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
||||||
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||||
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||||
// TLB management
|
// TLB management
|
||||||
@ -54,22 +55,25 @@ module dmem (
|
|||||||
input logic [`XLEN-1:0] PageTableEntryM,
|
input logic [`XLEN-1:0] PageTableEntryM,
|
||||||
input logic [1:0] PageTypeM,
|
input logic [1:0] PageTypeM,
|
||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW,
|
||||||
|
input logic STATUS_MXR, STATUS_SUM,
|
||||||
input logic DTLBWriteM, DTLBFlushM,
|
input logic DTLBWriteM, DTLBFlushM,
|
||||||
output logic DTLBMissM, DTLBHitM
|
output logic DTLBMissM, DTLBHitM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic MemAccessM; // Whether memory needs to be accessed
|
|
||||||
logic SquashSCM;
|
logic SquashSCM;
|
||||||
// *** needs to be sent to trap unit
|
|
||||||
logic DTLBPageFaultM;
|
logic DTLBPageFaultM;
|
||||||
|
|
||||||
tlb #(3) dtlb(.TLBAccess(MemAccessM), .VirtualAddress(MemAdrM),
|
tlb #(.ENTRY_BITS(3), .ITLB(0)) dtlb(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM),
|
||||||
.PageTableEntryWrite(PageTableEntryM), .PageTypeWrite(PageTypeM),
|
.PageTableEntryWrite(PageTableEntryM), .PageTypeWrite(PageTypeM),
|
||||||
.TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM),
|
.TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM),
|
||||||
.PhysicalAddress(MemPAdrM), .TLBMiss(DTLBMissM),
|
.PhysicalAddress(MemPAdrM), .TLBMiss(DTLBMissM),
|
||||||
.TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM),
|
.TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM),
|
||||||
.*);
|
.*);
|
||||||
|
|
||||||
|
// Specify which type of page fault is occurring
|
||||||
|
assign DTLBLoadPageFaultM = DTLBPageFaultM & MemRWM[1];
|
||||||
|
assign DTLBStorePageFaultM = DTLBPageFaultM & MemRWM[0];
|
||||||
|
|
||||||
// Determine if an Unaligned access is taking place
|
// Determine if an Unaligned access is taking place
|
||||||
always_comb
|
always_comb
|
||||||
case(Funct3M[1:0])
|
case(Funct3M[1:0])
|
||||||
@ -83,7 +87,6 @@ module dmem (
|
|||||||
// *** this is also the place to squash if the cache is hit
|
// *** this is also the place to squash if the cache is hit
|
||||||
assign MemReadM = MemRWM[1] & ~DataMisalignedM;
|
assign MemReadM = MemRWM[1] & ~DataMisalignedM;
|
||||||
assign MemWriteM = MemRWM[0] & ~DataMisalignedM && ~SquashSCM;
|
assign MemWriteM = MemRWM[0] & ~DataMisalignedM && ~SquashSCM;
|
||||||
assign MemAccessM = |MemRWM;
|
|
||||||
|
|
||||||
// Determine if address is valid
|
// Determine if address is valid
|
||||||
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
|
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
|
||||||
|
@ -85,6 +85,9 @@ module ahblite (
|
|||||||
logic IReady, DReady;
|
logic IReady, DReady;
|
||||||
logic CaptureDataM;
|
logic CaptureDataM;
|
||||||
|
|
||||||
|
// Describes type of access
|
||||||
|
logic Atomic, Execute, Write, Read;
|
||||||
|
|
||||||
assign HCLK = clk;
|
assign HCLK = clk;
|
||||||
assign HRESETn = ~reset;
|
assign HRESETn = ~reset;
|
||||||
|
|
||||||
@ -109,15 +112,6 @@ module ahblite (
|
|||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
MMUTRANSLATE: if (~HREADY) NextBusState = MMUTRANSLATE;
|
MMUTRANSLATE: if (~HREADY) NextBusState = MMUTRANSLATE;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
// *** Could the MMUIDLE state just be the normal idle state?
|
|
||||||
// Do we trust MMUTranslate to be high exactly when we need translation?
|
|
||||||
// MMUIDLE: if (MMUTranslate)
|
|
||||||
// NextBusState = MMUTRANSLATE;
|
|
||||||
// else if (AtomicM[1]) NextBusState = ATOMICREAD;
|
|
||||||
// else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
|
|
||||||
// else if (MemWriteM) NextBusState = MEMWRITE;
|
|
||||||
// else if (InstrReadF) NextBusState = INSTRREAD;
|
|
||||||
// else NextBusState = IDLE;
|
|
||||||
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
|
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
|
||||||
else NextBusState = ATOMICWRITE;
|
else NextBusState = ATOMICWRITE;
|
||||||
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
|
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
|
||||||
@ -148,6 +142,13 @@ module ahblite (
|
|||||||
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete));
|
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete));
|
||||||
|
|
||||||
|
// Determine access type (important for determining whether to fault)
|
||||||
|
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
||||||
|
assign Execute = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC));
|
||||||
|
assign Write = ((NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE));
|
||||||
|
assign Read = ((NextBusState == MEMREAD) || (NextBusState == ATOMICREAD) ||
|
||||||
|
(NextBusState == MMUTRANSLATE));
|
||||||
|
|
||||||
// bus outputs
|
// bus outputs
|
||||||
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
|
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
|
||||||
|
@ -61,7 +61,9 @@ module pagetablewalker (
|
|||||||
output logic MMUTranslationComplete,
|
output logic MMUTranslationComplete,
|
||||||
|
|
||||||
// Faults
|
// Faults
|
||||||
output logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM
|
output logic WalkerInstrPageFaultF,
|
||||||
|
output logic WalkerLoadPageFaultM,
|
||||||
|
output logic WalkerStorePageFaultM
|
||||||
);
|
);
|
||||||
|
|
||||||
// Internal signals
|
// Internal signals
|
||||||
@ -147,7 +149,6 @@ module pagetablewalker (
|
|||||||
|
|
||||||
assign SvMode = SATP_REGW[31];
|
assign SvMode = SATP_REGW[31];
|
||||||
|
|
||||||
// *** Do we need a synchronizer here for walker to talk to ahblite?
|
|
||||||
flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
|
flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||||
|
|
||||||
// State transition logic
|
// State transition logic
|
||||||
@ -193,9 +194,9 @@ module pagetablewalker (
|
|||||||
MMUTranslationComplete = '0;
|
MMUTranslationComplete = '0;
|
||||||
DTLBWriteM = '0;
|
DTLBWriteM = '0;
|
||||||
ITLBWriteF = '0;
|
ITLBWriteF = '0;
|
||||||
InstrPageFaultF = '0;
|
WalkerInstrPageFaultF = '0;
|
||||||
LoadPageFaultM = '0;
|
WalkerLoadPageFaultM = '0;
|
||||||
StorePageFaultM = '0;
|
WalkerStorePageFaultM = '0;
|
||||||
|
|
||||||
case (NextWalkerState)
|
case (NextWalkerState)
|
||||||
LEVEL1: begin
|
LEVEL1: begin
|
||||||
@ -216,9 +217,9 @@ module pagetablewalker (
|
|||||||
FAULT: begin
|
FAULT: begin
|
||||||
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
||||||
MMUTranslationComplete = '1;
|
MMUTranslationComplete = '1;
|
||||||
InstrPageFaultF = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||||
LoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||||
StorePageFaultM = DTLBMissM && MemStore;
|
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
// nothing
|
// nothing
|
||||||
@ -298,9 +299,9 @@ module pagetablewalker (
|
|||||||
MMUTranslationComplete = '0;
|
MMUTranslationComplete = '0;
|
||||||
DTLBWriteM = '0;
|
DTLBWriteM = '0;
|
||||||
ITLBWriteF = '0;
|
ITLBWriteF = '0;
|
||||||
InstrPageFaultF = '0;
|
WalkerInstrPageFaultF = '0;
|
||||||
LoadPageFaultM = '0;
|
WalkerLoadPageFaultM = '0;
|
||||||
StorePageFaultM = '0;
|
WalkerStorePageFaultM = '0;
|
||||||
|
|
||||||
case (NextWalkerState)
|
case (NextWalkerState)
|
||||||
LEVEL2: begin
|
LEVEL2: begin
|
||||||
@ -325,9 +326,9 @@ module pagetablewalker (
|
|||||||
FAULT: begin
|
FAULT: begin
|
||||||
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
||||||
MMUTranslationComplete = '1;
|
MMUTranslationComplete = '1;
|
||||||
InstrPageFaultF = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||||
LoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||||
StorePageFaultM = DTLBMissM && MemStore;
|
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
// nothing
|
// nothing
|
||||||
|
@ -54,6 +54,7 @@ module ifu (
|
|||||||
// output logic [`XLEN-1:0] PCLinkW,
|
// output logic [`XLEN-1:0] PCLinkW,
|
||||||
// Faults
|
// Faults
|
||||||
input logic IllegalBaseInstrFaultD,
|
input logic IllegalBaseInstrFaultD,
|
||||||
|
output logic ITLBInstrPageFaultF,
|
||||||
output logic IllegalIEUInstrFaultD,
|
output logic IllegalIEUInstrFaultD,
|
||||||
output logic InstrMisalignedFaultM,
|
output logic InstrMisalignedFaultM,
|
||||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||||
@ -62,6 +63,7 @@ module ifu (
|
|||||||
input logic [`XLEN-1:0] PageTableEntryF,
|
input logic [`XLEN-1:0] PageTableEntryF,
|
||||||
input logic [1:0] PageTypeF,
|
input logic [1:0] PageTypeF,
|
||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW,
|
||||||
|
input logic STATUS_MXR, STATUS_SUM,
|
||||||
input logic ITLBWriteF, ITLBFlushF,
|
input logic ITLBWriteF, ITLBFlushF,
|
||||||
output logic ITLBMissF, ITLBHitF
|
output logic ITLBMissF, ITLBHitF
|
||||||
);
|
);
|
||||||
@ -74,14 +76,12 @@ module ifu (
|
|||||||
logic CompressedF;
|
logic CompressedF;
|
||||||
logic [31:0] InstrRawD, InstrE, InstrW;
|
logic [31:0] InstrRawD, InstrE, InstrW;
|
||||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||||
// *** send this to the trap unit
|
|
||||||
logic ITLBPageFaultF;
|
|
||||||
|
|
||||||
tlb #(3) itlb(.TLBAccess(1'b1), .VirtualAddress(PCF),
|
tlb #(.ENTRY_BITS(3), .ITLB(1)) itlb(.TLBAccessType(2'b10), .VirtualAddress(PCF),
|
||||||
.PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF),
|
.PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF),
|
||||||
.TLBWrite(ITLBWriteF), .TLBFlush(ITLBFlushF),
|
.TLBWrite(ITLBWriteF), .TLBFlush(ITLBFlushF),
|
||||||
.PhysicalAddress(PCPF), .TLBMiss(ITLBMissF),
|
.PhysicalAddress(PCPF), .TLBMiss(ITLBMissF),
|
||||||
.TLBHit(ITLBHitF), .TLBPageFault(ITLBPageFaultF),
|
.TLBHit(ITLBHitF), .TLBPageFault(ITLBInstrPageFaultF),
|
||||||
.*);
|
.*);
|
||||||
|
|
||||||
// branch predictor signals
|
// branch predictor signals
|
||||||
|
@ -44,26 +44,26 @@
|
|||||||
* RSW(2) -- for OS
|
* RSW(2) -- for OS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* *** TODO:
|
|
||||||
* - add LRU algorithm (select the write index based on which entry was used
|
|
||||||
* least recently)
|
|
||||||
*/
|
|
||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
`include "wally-constants.vh"
|
`include "wally-constants.vh"
|
||||||
|
|
||||||
// The TLB will have 2**ENTRY_BITS total entries
|
// The TLB will have 2**ENTRY_BITS total entries
|
||||||
module tlb #(parameter ENTRY_BITS = 3) (
|
module tlb #(parameter ENTRY_BITS = 3,
|
||||||
|
parameter ITLB = 0) (
|
||||||
input clk, reset,
|
input clk, reset,
|
||||||
|
|
||||||
// Current value of satp CSR (from privileged unit)
|
// Current value of satp CSR (from privileged unit)
|
||||||
input [`XLEN-1:0] SATP_REGW,
|
input [`XLEN-1:0] SATP_REGW,
|
||||||
|
input STATUS_MXR, STATUS_SUM,
|
||||||
|
|
||||||
// Current privilege level of the processeor
|
// Current privilege level of the processeor
|
||||||
input [1:0] PrivilegeModeW,
|
input [1:0] PrivilegeModeW,
|
||||||
|
|
||||||
// High if the TLB is currently being accessed
|
// 00 - TLB is not being accessed
|
||||||
input TLBAccess,
|
// 1x - TLB is accessed for a read (or an instruction)
|
||||||
|
// x1 - TLB is accessed for a write
|
||||||
|
// 11 - TLB is accessed for both read and write
|
||||||
|
input [1:0] TLBAccessType,
|
||||||
|
|
||||||
// Virtual address input
|
// Virtual address input
|
||||||
input [`XLEN-1:0] VirtualAddress,
|
input [`XLEN-1:0] VirtualAddress,
|
||||||
@ -87,17 +87,7 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
|||||||
|
|
||||||
logic SvMode;
|
logic SvMode;
|
||||||
logic Translate;
|
logic Translate;
|
||||||
|
logic TLBAccess, ReadAccess, WriteAccess;
|
||||||
generate
|
|
||||||
if (`XLEN == 32) begin
|
|
||||||
assign SvMode = SATP_REGW[31]; // *** change to an enum somehow?
|
|
||||||
end else begin
|
|
||||||
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
// Whether translation should occur
|
|
||||||
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
|
|
||||||
|
|
||||||
// *** If we want to support multiple virtual memory modes (ie sv39 AND sv48),
|
// *** If we want to support multiple virtual memory modes (ie sv39 AND sv48),
|
||||||
// we could have some muxes that control which parameters are current.
|
// we could have some muxes that control which parameters are current.
|
||||||
@ -116,6 +106,9 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
|||||||
logic [7:0] PTEAccessBits;
|
logic [7:0] PTEAccessBits;
|
||||||
logic [11:0] PageOffset;
|
logic [11:0] PageOffset;
|
||||||
|
|
||||||
|
// Useful PTE Control Bits
|
||||||
|
logic PTE_U, PTE_X, PTE_W, PTE_R;
|
||||||
|
|
||||||
// Pattern location in the CAM and type of page hit
|
// Pattern location in the CAM and type of page hit
|
||||||
logic [ENTRY_BITS-1:0] VPNIndex;
|
logic [ENTRY_BITS-1:0] VPNIndex;
|
||||||
logic [1:0] HitPageType;
|
logic [1:0] HitPageType;
|
||||||
@ -123,18 +116,68 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
|||||||
// Whether the virtual address has a match in the CAM
|
// Whether the virtual address has a match in the CAM
|
||||||
logic CAMHit;
|
logic CAMHit;
|
||||||
|
|
||||||
|
// Grab the sv bit from SATP
|
||||||
|
generate
|
||||||
|
if (`XLEN == 32) begin
|
||||||
|
assign SvMode = SATP_REGW[31]; // *** change to an enum somehow?
|
||||||
|
end else begin
|
||||||
|
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// Whether translation should occur
|
||||||
|
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
|
||||||
|
|
||||||
|
// Determine how the TLB is currently being used
|
||||||
|
assign ReadAccess = TLBAccessType[1];
|
||||||
|
assign WriteAccess = TLBAccessType[0];
|
||||||
|
assign TLBAccess = ReadAccess || WriteAccess;
|
||||||
|
|
||||||
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
||||||
assign PageOffset = VirtualAddress[11:0];
|
assign PageOffset = VirtualAddress[11:0];
|
||||||
|
|
||||||
// Currently use random replacement algorithm
|
// TLB entries are evicted according to the LRU algorithm
|
||||||
// tlb_rand rdm(.*);
|
|
||||||
tlb_lru lru(.*);
|
tlb_lru lru(.*);
|
||||||
|
|
||||||
tlb_ram #(ENTRY_BITS) ram(.*);
|
tlb_ram #(ENTRY_BITS) tlb_ram(.*);
|
||||||
tlb_cam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) cam(.*);
|
tlb_cam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlb_cam(.*);
|
||||||
|
|
||||||
// *** check whether access is allowed, otherwise fault
|
// unswizzle useful PTE bits
|
||||||
assign TLBPageFault = 0; // *** temporary
|
assign PTE_U = PTEAccessBits[4];
|
||||||
|
assign PTE_X = PTEAccessBits[3];
|
||||||
|
assign PTE_W = PTEAccessBits[2];
|
||||||
|
assign PTE_R = PTEAccessBits[1];
|
||||||
|
|
||||||
|
// Check whether the access is allowed, page faulting if not.
|
||||||
|
// *** We might not have S mode.
|
||||||
|
generate
|
||||||
|
if (ITLB == 1) begin
|
||||||
|
logic ImproperPrivilege;
|
||||||
|
|
||||||
|
// User mode may only execute user mode pages, and supervisor mode may
|
||||||
|
// only execute non-user mode pages.
|
||||||
|
assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) ||
|
||||||
|
((PrivilegeModeW == `S_MODE) && PTE_U);
|
||||||
|
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X);
|
||||||
|
end else begin
|
||||||
|
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
||||||
|
|
||||||
|
// User mode may only load/store from user mode pages, and supervisor mode
|
||||||
|
// may only access user mode pages when STATUS_SUM is low.
|
||||||
|
assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) ||
|
||||||
|
((PrivilegeModeW == `S_MODE) && PTE_U && ~STATUS_SUM);
|
||||||
|
// Check for read error. Reads are invalid when the page is not readable
|
||||||
|
// (and executable pages are not readable) or when the page is neither
|
||||||
|
// readable nor executable (and executable pages are readable).
|
||||||
|
assign InvalidRead = ReadAccess &&
|
||||||
|
((~STATUS_MXR && ~PTE_R) || (STATUS_MXR && ~PTE_R && PTE_X));
|
||||||
|
// Check for write error. Writes are invalid when the page's write bit is
|
||||||
|
// low.
|
||||||
|
assign InvalidWrite = WriteAccess && ~PTE_W;
|
||||||
|
assign TLBPageFault = Translate && TLBHit &&
|
||||||
|
(ImproperPrivilege || InvalidRead || InvalidWrite);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
// *** Not the cleanest solution.
|
// *** Not the cleanest solution.
|
||||||
// The highest segment of the physical page number has some extra bits
|
// The highest segment of the physical page number has some extra bits
|
||||||
@ -158,6 +201,8 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
|||||||
// Output the hit physical address if translation is currently on.
|
// Output the hit physical address if translation is currently on.
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
|
// *** If we want rv32 to use the full 34 bit physical address space, this
|
||||||
|
// must be changed
|
||||||
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], Translate, PhysicalAddress);
|
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], Translate, PhysicalAddress);
|
||||||
end else begin
|
end else begin
|
||||||
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, Translate, PhysicalAddress);
|
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, Translate, PhysicalAddress);
|
||||||
|
@ -49,6 +49,7 @@ module csr #(parameter
|
|||||||
output logic [`XLEN-1:0] SATP_REGW,
|
output logic [`XLEN-1:0] SATP_REGW,
|
||||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||||
output logic STATUS_MIE, STATUS_SIE,
|
output logic STATUS_MIE, STATUS_SIE,
|
||||||
|
output logic STATUS_MXR, STATUS_SUM,
|
||||||
input logic [4:0] SetFflagsM,
|
input logic [4:0] SetFflagsM,
|
||||||
output logic [2:0] FRM_REGW,
|
output logic [2:0] FRM_REGW,
|
||||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||||
|
@ -36,10 +36,11 @@ module csrsr (
|
|||||||
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
||||||
output logic [1:0] STATUS_MPP,
|
output logic [1:0] STATUS_MPP,
|
||||||
output logic STATUS_SPP, STATUS_TSR,
|
output logic STATUS_SPP, STATUS_TSR,
|
||||||
output logic STATUS_MIE, STATUS_SIE
|
output logic STATUS_MIE, STATUS_SIE,
|
||||||
|
output logic STATUS_MXR, STATUS_SUM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||||
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
||||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ module privileged (
|
|||||||
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
|
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
|
||||||
input logic [3:0] InstrClassM,
|
input logic [3:0] InstrClassM,
|
||||||
input logic PrivilegedM,
|
input logic PrivilegedM,
|
||||||
input logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM,
|
input logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
||||||
|
input logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM,
|
||||||
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
|
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
|
||||||
input logic LoadMisalignedFaultM, LoadAccessFaultM,
|
input logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||||
input logic StoreMisalignedFaultM, StoreAccessFaultM,
|
input logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||||
@ -49,6 +50,7 @@ module privileged (
|
|||||||
input logic [4:0] SetFflagsM,
|
input logic [4:0] SetFflagsM,
|
||||||
output logic [1:0] PrivilegeModeW,
|
output logic [1:0] PrivilegeModeW,
|
||||||
output logic [`XLEN-1:0] SATP_REGW,
|
output logic [`XLEN-1:0] SATP_REGW,
|
||||||
|
output logic STATUS_MXR, STATUS_SUM,
|
||||||
output logic [2:0] FRM_REGW,
|
output logic [2:0] FRM_REGW,
|
||||||
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
|
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
|
||||||
);
|
);
|
||||||
@ -63,7 +65,8 @@ module privileged (
|
|||||||
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
|
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
|
||||||
logic IllegalCSRAccessM;
|
logic IllegalCSRAccessM;
|
||||||
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
|
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
|
||||||
logic InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
logic LoadPageFaultM, StorePageFaultM;
|
||||||
|
logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
||||||
logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
|
logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
|
||||||
logic IllegalInstrFaultM;
|
logic IllegalInstrFaultM;
|
||||||
|
|
||||||
@ -123,11 +126,12 @@ module privileged (
|
|||||||
assign EcallFaultM = ecallM;
|
assign EcallFaultM = ecallM;
|
||||||
assign ITLBFlushF = sfencevmaM;
|
assign ITLBFlushF = sfencevmaM;
|
||||||
assign DTLBFlushM = sfencevmaM;
|
assign DTLBFlushM = sfencevmaM;
|
||||||
// *** Page faults now driven by page table walker. Might need to make the
|
|
||||||
// below signals ORs of a walker fault and a tlb fault if both of those come in
|
// A page fault might occur because of insufficient privilege during a TLB
|
||||||
// assign InstrPageFaultM = 0;
|
// lookup or a improperly formatted page table during walking
|
||||||
// assign LoadPageFaultM = 0;
|
assign InstrPageFaultF = ITLBInstrPageFaultF || WalkerInstrPageFaultF;
|
||||||
// assign StorePageFaultM = 0;
|
assign LoadPageFaultM = DTLBLoadPageFaultM || WalkerLoadPageFaultM;
|
||||||
|
assign StorePageFaultM = DTLBStorePageFaultM || WalkerStorePageFaultM;
|
||||||
|
|
||||||
// pipeline fault signals
|
// pipeline fault signals
|
||||||
flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD,
|
flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD,
|
||||||
|
@ -77,7 +77,8 @@ module wallypipelinedhart (
|
|||||||
logic InstrMisalignedFaultM;
|
logic InstrMisalignedFaultM;
|
||||||
logic DataMisalignedM;
|
logic DataMisalignedM;
|
||||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||||
logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM;
|
logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM;
|
||||||
|
logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM;
|
||||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||||
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
||||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||||
@ -103,6 +104,7 @@ module wallypipelinedhart (
|
|||||||
logic ITLBMissF, ITLBHitF;
|
logic ITLBMissF, ITLBHitF;
|
||||||
logic DTLBMissM, DTLBHitM;
|
logic DTLBMissM, DTLBHitM;
|
||||||
logic [`XLEN-1:0] SATP_REGW;
|
logic [`XLEN-1:0] SATP_REGW;
|
||||||
|
logic STATUS_MXR, STATUS_SUM;
|
||||||
logic [1:0] PrivilegeModeW;
|
logic [1:0] PrivilegeModeW;
|
||||||
|
|
||||||
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
|
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
|
||||||
|
Loading…
Reference in New Issue
Block a user