This commit is contained in:
Ross Thompson 2023-08-28 09:13:16 -05:00
commit d1354385be
50 changed files with 775 additions and 431 deletions

View File

@ -42,11 +42,12 @@ localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 0; localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 1;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 1;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 1;
localparam SVNAPOT_SUPPORTED = 1;
localparam SVINVAL_SUPPORTED = 1; localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -44,11 +44,12 @@ localparam COUNTERS = 12'd32;
localparam ZICNTR_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 0; localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 1;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 1;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 1;
localparam SVNAPOT_SUPPORTED = 1;
localparam SVINVAL_SUPPORTED = 1; localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -48,6 +48,7 @@ localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 0; localparam SVINVAL_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -49,6 +49,7 @@ localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1; localparam ZICBOZ_SUPPORTED = 1;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 1; localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -48,6 +48,7 @@ localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 0; localparam SVINVAL_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -47,6 +47,7 @@ localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 0; localparam SVINVAL_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -48,6 +48,7 @@ localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 1; localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -49,8 +49,9 @@ localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1; localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1; localparam ZICBOZ_SUPPORTED = 1;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 1;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 1;
localparam SVNAPOT_SUPPORTED = 1;
localparam SVINVAL_SUPPORTED = 1; localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -48,6 +48,7 @@ localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 0; localparam SVINVAL_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features

View File

@ -101,10 +101,10 @@ localparam FPDUR = ((DIVN+1+(LOGR*DIVCOPIES))/(LOGR*DIVCOPIES)+(RADIX/4));
localparam DURLEN = ($clog2(FPDUR+1)); localparam DURLEN = ($clog2(FPDUR+1));
localparam DIVb = (FPDUR*LOGR*DIVCOPIES-1); // canonical fdiv size (b) localparam DIVb = (FPDUR*LOGR*DIVCOPIES-1); // canonical fdiv size (b)
localparam DIVBLEN = ($clog2(DIVb+1)-1); localparam DIVBLEN = ($clog2(DIVb+1)-1);
localparam DIVa = (DIVb+1-XLEN); // used for idiv on fpu localparam DIVa = (DIVb+1-XLEN); // used for idiv on fpu: Shift residual right by b - (XLEN-1) to put remainder in lsbs of integer result
// largest length in IEU/FPU // largest length in IEU/FPU
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN))); localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6)));

View File

@ -3,7 +3,7 @@
`include "BranchPredictorType.vh" `include "BranchPredictorType.vh"
parameter cvw_t P = '{ localparam cvw_t P = '{
FPGA : FPGA, FPGA : FPGA,
XLEN : XLEN, XLEN : XLEN,
IEEE754 : IEEE754, IEEE754 : IEEE754,
@ -25,6 +25,7 @@ parameter cvw_t P = '{
ZICBOZ_SUPPORTED : ZICBOZ_SUPPORTED, ZICBOZ_SUPPORTED : ZICBOZ_SUPPORTED,
ZICBOP_SUPPORTED : ZICBOP_SUPPORTED, ZICBOP_SUPPORTED : ZICBOP_SUPPORTED,
SVPBMT_SUPPORTED : SVPBMT_SUPPORTED, SVPBMT_SUPPORTED : SVPBMT_SUPPORTED,
SVNAPOT_SUPPORTED : SVNAPOT_SUPPORTED,
SVINVAL_SUPPORTED : SVINVAL_SUPPORTED, SVINVAL_SUPPORTED : SVINVAL_SUPPORTED,
BUS_SUPPORTED : BUS_SUPPORTED, BUS_SUPPORTED : BUS_SUPPORTED,
DCACHE_SUPPORTED : DCACHE_SUPPORTED, DCACHE_SUPPORTED : DCACHE_SUPPORTED,

View File

@ -60,6 +60,7 @@ typedef struct packed {
logic ZICBOZ_SUPPORTED; logic ZICBOZ_SUPPORTED;
logic ZICBOP_SUPPORTED; logic ZICBOP_SUPPORTED;
logic SVPBMT_SUPPORTED; logic SVPBMT_SUPPORTED;
logic SVNAPOT_SUPPORTED;
logic SVINVAL_SUPPORTED; logic SVINVAL_SUPPORTED;
// Microarchitectural Features // Microarchitectural Features

View File

@ -375,12 +375,14 @@ module controller import cvw::*; #(parameter cvw_t P) (
LSUPrefetchD = 1'b0; LSUPrefetchD = 1'b0;
ImmSrcD = PreImmSrcD; ImmSrcD = PreImmSrcD;
if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destiation x0 is hint for Prefetch if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destiation x0 is hint for Prefetch
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally /* verilator lint_off CASEINCOMPLETE */
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally
5'b00000: IFUPrefetchD = 1'b1; // prefetch.i 5'b00000: IFUPrefetchD = 1'b1; // prefetch.i
5'b00001: LSUPrefetchD = 1'b1; // prefetch.r 5'b00001: LSUPrefetchD = 1'b1; // prefetch.r
5'b00011: LSUPrefetchD = 1'b1; // prefetch.w 5'b00011: LSUPrefetchD = 1'b1; // prefetch.w
// default: not a prefetch hint // default: not a prefetch hint
endcase endcase
/* verilator lint_on CASEINCOMPLETE */
if (IFUPrefetchD | LSUPrefetchD) ImmSrcD = 3'b001; // use S-type immediate format for prefetches if (IFUPrefetchD | LSUPrefetchD) ImmSrcD = 3'b001; // use S-type immediate format for prefetches
end end
end end

View File

@ -85,6 +85,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
@ -170,7 +171,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign TLBFlush = sfencevmaM & ~StallMQ; assign TLBFlush = sfencevmaM & ~StallMQ;
mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1)) mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1))
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
.PrivilegeModeW, .DisableTranslation(1'b0), .PrivilegeModeW, .DisableTranslation(1'b0),
.VAdr(PCFExt), .VAdr(PCFExt),
.Size(2'b10), .Size(2'b10),

View File

@ -80,6 +80,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
input logic [1:0] STATUS_MPP, // Machine previous privilege mode input logic [1:0] STATUS_MPP, // Machine previous privilege mode
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
@ -189,7 +190,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
assign DisableTranslation = SelHPTW | FlushDCacheM; assign DisableTranslation = SelHPTW | FlushDCacheM;
assign WriteAccessM = PreLSURWM[0] | (|CMOpM); assign WriteAccessM = PreLSURWM[0] | (|CMOpM);
mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0)) mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
.PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]), .PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
.PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM), .PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM),
.PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM), .PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM),

View File

@ -155,7 +155,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE);
flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
assign SaveHPTWAdr = WalkerState == L0_ADR; assign SaveHPTWAdr = WalkerState == L0_ADR;
assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0]; assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0];
mux2 #(P.PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr); mux2 #(P.PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr);

View File

@ -34,6 +34,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
@ -70,6 +71,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
logic TLBHit; // Hit in TLB logic TLBHit; // Hit in TLB
logic TLBPageFault; // Page fault from TLB logic TLBPageFault; // Page fault from TLB
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
logic [1:0] PBMemoryType; // PBMT field of PTE during TLB hit, or 00 otherwise
// only instantiate TLB if Virtual Memory is supported // only instantiate TLB if Virtual Memory is supported
if (P.VIRTMEM_SUPPORTED) begin:tlb if (P.VIRTMEM_SUPPORTED) begin:tlb
@ -80,16 +82,17 @@ module mmu import cvw::*; #(parameter cvw_t P,
.clk, .reset, .clk, .reset,
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), .SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]), .SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .PrivilegeModeW, .ReadAccess, .WriteAccess,
.DisableTranslation, .PTE, .PageTypeWriteVal, .DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault, .UpdateDA); .Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
end else begin:tlb // just pass address through as physical end else begin:tlb // just pass address through as physical
assign Translate = 0; assign Translate = 0;
assign TLBMiss = 0; assign TLBMiss = 0;
assign TLBHit = 1; // *** is this necessary assign TLBHit = 1; // *** is this necessary
assign TLBPageFault = 0; assign TLBPageFault = 0;
assign PBMemoryType = 2'b00;
end end
// If translation is occuring, select translated physical address from TLB // If translation is occuring, select translated physical address from TLB
@ -103,8 +106,8 @@ module mmu import cvw::*; #(parameter cvw_t P,
/////////////////////////////////////////// ///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, pmachecker #(P) pmachecker(.PhysicalAddress, .Size,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
if (P.PMP_ENTRIES > 0) begin : pmp if (P.PMP_ENTRIES > 0) begin : pmp

View File

@ -35,6 +35,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic ExecuteAccessF, // Execute access input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access input logic WriteAccessM, // Write access
input logic ReadAccessM, // Read access input logic ReadAccessM, // Read access
input logic [1:0] PBMemoryType, // PBMT field of PTE during TLB hit, or 00 otherwise
output logic Cacheable, Idempotent, SelTIM, output logic Cacheable, Idempotent, SelTIM,
output logic PMAInstrAccessFaultF, output logic PMAInstrAccessFaultF,
output logic PMALoadAccessFaultM, output logic PMALoadAccessFaultM,
@ -45,6 +46,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWX, AccessRX;
logic [10:0] SelRegions; logic [10:0] SelRegions;
logic AtomicAllowed; logic AtomicAllowed;
logic CacheableRegion, IdempotentRegion;
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; assign AccessRW = ReadAccessM | WriteAccessM;
@ -54,11 +56,15 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions); adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
// Only non-core RAM/ROM memory regions are cacheable // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
assign Cacheable = SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-cachable assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6];
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // exclusion-tag: unused-cachable
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
// I/O is nonidempotent. // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent
assign Idempotent = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-idempotent assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6];
assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // exclusion-tag: unused-idempotent
// Atomic operations are only allowed on RAM // Atomic operations are only allowed on RAM
assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic
// Check if tightly integrated memories are selected // Check if tightly integrated memories are selected

View File

@ -57,12 +57,13 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic [P.ASID_BITS-1:0] SATP_ASID, input logic [P.ASID_BITS-1:0] SATP_ASID,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic ReadAccess, input logic ReadAccess,
input logic WriteAccess, input logic WriteAccess,
input logic DisableTranslation, input logic DisableTranslation,
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual) input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
input logic [P.XLEN-1:0] PTE, input logic [P.XLEN-1:0] PTE, // page table entry to write
input logic [1:0] PageTypeWriteVal, input logic [1:0] PageTypeWriteVal,
input logic TLBWrite, input logic TLBWrite,
input logic TLBFlush, input logic TLBFlush,
@ -71,20 +72,22 @@ module tlb import cvw::*; #(parameter cvw_t P,
output logic TLBHit, output logic TLBHit,
output logic Translate, output logic Translate,
output logic TLBPageFault, output logic TLBPageFault,
output logic UpdateDA output logic UpdateDA,
output logic [1:0] PBMemoryType // PBMT field of PTE during TLB hit, or 00 otherwise
); );
logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs; // used as the one-hot encoding of WriteIndex logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs, PTE_NAPOTs; // used as the one-hot encoding of WriteIndex
// Sections of the virtual and physical addresses // Sections of the virtual and physical addresses
logic [P.VPN_BITS-1:0] VPN; logic [P.VPN_BITS-1:0] VPN;
logic [P.PPN_BITS-1:0] PPN; logic [P.PPN_BITS-1:0] PPN;
// Sections of the page table entry // Sections of the page table entry
logic [7:0] PTEAccessBits; logic [11:0] PTEAccessBits;
logic [1:0] HitPageType; logic [1:0] HitPageType;
logic CAMHit; logic CAMHit;
logic SV39Mode; logic SV39Mode;
logic Misaligned; logic Misaligned;
logic MegapageMisaligned; logic MegapageMisaligned;
logic PTE_N; // NAPOT page table entry
if(P.XLEN == 32) begin if(P.XLEN == 32) begin
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0 assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0
@ -101,20 +104,21 @@ module tlb import cvw::*; #(parameter cvw_t P,
assign VPN = VAdr[P.VPN_BITS+11:12]; assign VPN = VAdr[P.VPN_BITS+11:12];
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush, .PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush,
.PTEAccessBits, .CAMHit, .Misaligned, .TLBMiss, .TLBHit, .TLBPageFault, .PTEAccessBits, .CAMHit, .Misaligned,
.UpdateDA, .SV39Mode, .Translate); .TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables); tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables);
tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS) tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS)
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs,
.SATP_ASID, .Matches, .HitPageType, .CAMHit); .SATP_ASID, .Matches, .HitPageType, .CAMHit);
tlbram #(P, TLB_ENTRIES) tlbram(.clk, .reset, .PTE, .Matches, .WriteEnables, .PPN, .PTEAccessBits, .PTE_Gs); tlbram #(P, TLB_ENTRIES) tlbram(.clk, .reset, .PTE, .Matches, .WriteEnables, .PPN, .PTEAccessBits, .PTE_Gs, .PTE_NAPOTs);
// Replace segments of the virtual page number with segments of the physical // Replace segments of the virtual page number with segments of the physical
// page number. For 4 KB pages, the entire virtual page number is replaced. // page number. For 4 KB pages, the entire virtual page number is replaced.
// For superpages, some segments are considered offsets into a larger page. // For superpages, some segments are considered offsets into a larger page.
tlbmixer #(P) Mixer(.VPN, .PPN, .HitPageType, .Offset(VAdr[11:0]), .TLBHit, .TLBPAdr); tlbmixer #(P) Mixer(.VPN, .PPN, .HitPageType, .Offset(VAdr[11:0]), .TLBHit, .PTE_N, .TLBPAdr);
endmodule endmodule

View File

@ -38,7 +38,8 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
input logic TLBFlush, input logic TLBFlush,
input logic [TLB_ENTRIES-1:0] WriteEnables, input logic [TLB_ENTRIES-1:0] WriteEnables,
input logic [TLB_ENTRIES-1:0] PTE_Gs, input logic [TLB_ENTRIES-1:0] PTE_Gs,
input logic [P.ASID_BITS-1:0] SATP_ASID, input logic [TLB_ENTRIES-1:0] PTE_NAPOTs, // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
input logic [P.ASID_BITS-1:0] SATP_ASID,
output logic [TLB_ENTRIES-1:0] Matches, output logic [TLB_ENTRIES-1:0] Matches,
output logic [1:0] HitPageType, output logic [1:0] HitPageType,
output logic CAMHit output logic CAMHit
@ -53,7 +54,7 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
// page number segments. // page number segments.
tlbcamline #(P, KEY_BITS, SEGMENT_BITS) camlines[TLB_ENTRIES-1:0]( tlbcamline #(P, KEY_BITS, SEGMENT_BITS) camlines[TLB_ENTRIES-1:0](
.clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .PTE_G(PTE_Gs), .PageTypeWriteVal, .TLBFlush, .clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs), .PageTypeWriteVal, .TLBFlush,
.WriteEnable(WriteEnables), .PageTypeRead, .Match(Matches)); .WriteEnable(WriteEnables), .PageTypeRead, .Match(Matches));
assign CAMHit = |Matches & ~TLBFlush; assign CAMHit = |Matches & ~TLBFlush;
or_rows #(TLB_ENTRIES,2) PageTypeOr(PageTypeRead, HitPageType); or_rows #(TLB_ENTRIES,2) PageTypeOr(PageTypeRead, HitPageType);

View File

@ -37,6 +37,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
input logic SV39Mode, input logic SV39Mode,
input logic WriteEnable, // Write a new entry to this line input logic WriteEnable, // Write a new entry to this line
input logic PTE_G, input logic PTE_G,
input logic PTE_NAPOT, // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
input logic [1:0] PageTypeWriteVal, input logic [1:0] PageTypeWriteVal,
input logic TLBFlush, // Flush this line (set valid to 0) input logic TLBFlush, // Flush this line (set valid to 0)
output logic [1:0] PageTypeRead, // *** should this be the stored version or the always updated one? output logic [1:0] PageTypeRead, // *** should this be the stored version or the always updated one?
@ -76,7 +77,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
end else begin: match end else begin: match
logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3; logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3;
logic Match2, Match3; logic Match2, Match3, MatchNAPOT;
assign {Query3, Query2, Query1, Query0} = VPN; assign {Query3, Query2, Query1, Query0} = VPN;
assign {Key_ASID, Key3, Key2, Key1, Key0} = Key; assign {Key_ASID, Key3, Key2, Key1, Key0} = Key;
@ -84,7 +85,9 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
// Calculate the actual match value based on the input vpn and the page type. // Calculate the actual match value based on the input vpn and the page type.
// For example, a gigapage in SV39 only cares about VPN[2], so VPN[0] and VPN[1] // For example, a gigapage in SV39 only cares about VPN[2], so VPN[0] and VPN[1]
// should automatically match. // should automatically match.
assign Match0 = (Query0 == Key0) | (PageType > 2'd0); // least signifcant section // In Svnapot, if N bit is set and bottom 4 bits of PPN = 1000, then these bits don't need to match
assign MatchNAPOT = P.SVNAPOT_SUPPORTED & PTE_NAPOT & (Query0[SEGMENT_BITS-1:4] == Key0[SEGMENT_BITS-1:4]);
assign Match0 = (Query0 == Key0) | (PageType > 2'd0) | MatchNAPOT; // least significant section
assign Match1 = (Query1 == Key1) | (PageType > 2'd1); assign Match1 = (Query1 == Key1) | (PageType > 2'd1);
assign Match2 = (Query2 == Key2) | (PageType > 2'd2); assign Match2 = (Query2 == Key2) | (PageType > 2'd2);
assign Match3 = (Query3 == Key3) | SV39Mode; // this should always match in sv39 because they aren't used assign Match3 = (Query3 == Key3) | SV39Mode; // this should always match in sv39 because they aren't used

View File

@ -29,30 +29,37 @@
module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) ( module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
input logic [P.SVMODE_BITS-1:0] SATP_MODE, input logic [P.SVMODE_BITS-1:0] SATP_MODE,
input logic [P.XLEN-1:0] VAdr, input logic [P.XLEN-1:0] VAdr,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic ReadAccess, WriteAccess, input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic DisableTranslation, input logic ReadAccess, WriteAccess,
input logic TLBFlush, // Invalidate all TLB entries input logic DisableTranslation,
input logic [7:0] PTEAccessBits, input logic TLBFlush, // Invalidate all TLB entries
input logic CAMHit, input logic [11:0] PTEAccessBits,
input logic Misaligned, input logic CAMHit,
output logic TLBMiss, input logic Misaligned,
output logic TLBHit, output logic TLBMiss,
output logic TLBPageFault, output logic TLBHit,
output logic UpdateDA, output logic TLBPageFault,
output logic SV39Mode, output logic UpdateDA,
output logic Translate output logic SV39Mode,
output logic Translate,
output logic PTE_N, // NAPOT page table entry
output logic [1:0] PBMemoryType // PBMT field of PTE during TLB hit, or 00 otherwise
); );
// Sections of the page table entry // Sections of the page table entry
logic [1:0] EffectivePrivilegeMode; logic [1:0] EffectivePrivilegeMode;
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits logic [1:0] PTE_PBMT;
logic PTE_RESERVED, PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
logic UpperBitsUnequal; logic UpperBitsUnequal;
logic TLBAccess; logic TLBAccess;
logic ImproperPrivilege; logic ImproperPrivilege;
logic BadPBMT, BadNAPOT, BadReserved;
logic InvalidAccess;
logic PreUpdateDA, PrePageFault;
// Grab the sv mode from SATP and determine whether translation should occur // Grab the sv mode from SATP and determine whether translation should occur
assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1 assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1
@ -65,8 +72,20 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal); vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal);
// unswizzle useful PTE bits // unswizzle useful PTE bits
assign PTE_N = PTEAccessBits[11];
assign PTE_PBMT = PTEAccessBits[10:9];
assign PTE_RESERVED = PTEAccessBits[8];
assign {PTE_D, PTE_A} = PTEAccessBits[7:6]; assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0]; assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0];
// Send PMA a 2-bit MemoryType that is PBMT during leaf page table accesses and 0 otherwise
assign PBMemoryType = PTE_PBMT & {2{Translate & TLBHit & P.SVPBMT_SUPPORTED}};
// check if reserved, N, or PBMT bits are malformed w in RV64
assign BadPBMT = PTE_PBMT != 0 & (~(P.SVPBMT_SUPPORTED & ENVCFG_PBMTE) |
{PTE_X, PTE_W, PTE_R} == 3'b000) | PTE_PBMT == 3; // PBMT must be zero if not supported or for non-leaf PTEs;
assign BadNAPOT = PTE_N & ~P.SVNAPOT_SUPPORTED; // N must be be 0 if CVNAPOT is not supported
assign BadReserved = PTE_RESERVED; // Reserved bits must be zero
// Check whether the access is allowed, page faulting if not. // Check whether the access is allowed, page faulting if not.
if (ITLB == 1) begin:itlb // Instruction TLB fault checking if (ITLB == 1) begin:itlb // Instruction TLB fault checking
@ -74,14 +93,46 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
// only execute non-user mode pages. // only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) | assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == P.S_MODE) & PTE_U); ((EffectivePrivilegeMode == P.S_MODE) & PTE_U);
if(P.SVADU_SUPPORTED) begin : hptwwrites assign PreUpdateDA = ~PTE_A;
assign UpdateDA = Translate & TLBHit & ~PTE_A & ~TLBPageFault; assign InvalidAccess = ~PTE_X;
assign TLBPageFault = Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequal | Misaligned | ~PTE_V); end else begin:dtlb // Data TLB fault checking
end else begin logic InvalidRead, InvalidWrite;
// fault for software handling if access bit is off
assign UpdateDA = ~PTE_A; // User mode may only load/store from user mode pages, and supervisor mode
assign TLBPageFault = Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpdateDA | UpperBitsUnequal | Misaligned | ~PTE_V); // may only access user mode pages when STATUS_SUM is low.
end assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == P.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 & ~PTE_R & (~STATUS_MXR | ~PTE_X);
// Check for write error. Writes are invalid when the page's write bit is
// low.
assign InvalidWrite = WriteAccess & ~PTE_W;
assign InvalidAccess = InvalidRead | InvalidWrite;
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
end
// Determine wheter to update DA bits. With SVADU, it is done in hardware
if (P.SVADU_SUPPORTED) assign UpdateDA = PreUpdateDA & Translate & TLBHit & ~TLBPageFault;
else assign UpdateDA = PreUpdateDA;
// Determine whether page fault occurs
assign PrePageFault = UpperBitsUnequal | Misaligned | ~PTE_V | ImproperPrivilege | (P.XLEN == 64 & (BadPBMT | BadNAPOT | BadReserved)) | (PreUpdateDA & ~P.SVADU_SUPPORTED);
assign TLBPageFault = Translate & TLBHit & (PrePageFault | InvalidAccess);
/*
// Check whether the access is allowed, page faulting if not.
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
// User mode may only execute user mode pages, and supervisor mode may
// only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == P.S_MODE) & PTE_U);
assign CausePageFault = ImproperPrivilege | ~PTE_X | UpperBitsUnequal | BadPTE | BadPBMT | Misaligned | ~PTE_V | (~PTE_A & P.SVADU_SUPPORTED);
assign TLBPageFault = Translate & TLBHit & CausePageFault;
// Determine wheter to update DA bits
if(P.SVADU_SUPPORTED) assign UpdateDA = Translate & TLBHit & ~PTE_A & ~TLBPageFault;
else assign UpdateDA = ~PTE_A;
end else begin:dtlb // Data TLB fault checking end else begin:dtlb // Data TLB fault checking
logic InvalidRead, InvalidWrite; logic InvalidRead, InvalidWrite;
@ -98,13 +149,14 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
assign InvalidWrite = WriteAccess & ~PTE_W; assign InvalidWrite = WriteAccess & ~PTE_W;
if(P.SVADU_SUPPORTED) begin : hptwwrites if(P.SVADU_SUPPORTED) begin : hptwwrites
assign UpdateDA = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D) & ~TLBPageFault; assign UpdateDA = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D) & ~TLBPageFault;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequal | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequal | Misaligned | ~PTE_V)); // *** update to match
end else begin end else begin
// Fault for software handling if access bit is off or writing a page with dirty bit off // Fault for software handling if access bit is off or writing a page with dirty bit off
assign UpdateDA = ~PTE_A | WriteAccess & ~PTE_D; assign UpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpdateDA | UpperBitsUnequal | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpdateDA | UpperBitsUnequal | Misaligned | ~PTE_V));
end end
end end
*/
assign TLBHit = CAMHit & TLBAccess; assign TLBHit = CAMHit & TLBAccess;
assign TLBMiss = ~CAMHit & TLBAccess & Translate ; assign TLBMiss = ~CAMHit & TLBAccess & Translate ;

View File

@ -30,18 +30,19 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module tlbmixer import cvw::*; #(parameter cvw_t P) ( module tlbmixer import cvw::*; #(parameter cvw_t P) (
input logic [P.VPN_BITS-1:0] VPN, input logic [P.VPN_BITS-1:0] VPN,
input logic [P.PPN_BITS-1:0] PPN, input logic [P.PPN_BITS-1:0] PPN,
input logic [1:0] HitPageType, input logic [1:0] HitPageType,
input logic [11:0] Offset, input logic [11:0] Offset,
input logic TLBHit, input logic TLBHit,
output logic [P.PA_BITS-1:0] TLBPAdr input logic PTE_N, // NAPOT page table entry
output logic [P.PA_BITS-1:0] TLBPAdr
); );
localparam EXTRA_BITS = P.PPN_BITS - P.VPN_BITS; localparam EXTRA_BITS = P.PPN_BITS - P.VPN_BITS;
logic [P.PPN_BITS-1:0] ZeroExtendedVPN; logic [P.PPN_BITS-1:0] ZeroExtendedVPN;
logic [P.PPN_BITS-1:0] PageNumberMask; logic [P.PPN_BITS-1:0] PageNumberMask;
logic [P.PPN_BITS-1:0] PPNMixed; logic [P.PPN_BITS-1:0] PPNMixed, PPNMixed2;
// produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages // produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages
if (P.XLEN == 32) if (P.XLEN == 32)
@ -57,11 +58,45 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
// merge low segments of VPN with high segments of PPN decided by the pagetype. // merge low segments of VPN with high segments of PPN decided by the pagetype.
assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN.
assign PPNMixed = PPN | ZeroExtendedVPN & PageNumberMask; // assign PPNMixed = PPN | ZeroExtendedVPN & PageNumberMask; // low bits of PPN are already zero
//mux2 #(1) mixmux[P.PPN_BITS-1:0](ZeroExtendedVPN, PPN, PageNumberMask, PPNMixed);
//assign PPNMixed = (ZeroExtendedVPN & ~PageNumberMask) | (PPN & PageNumberMask); // In Svnapot, when N=1, use bottom bits of VPN for contiugous translations
if (P.SVNAPOT_SUPPORTED) begin
// 64 KiB contiguous NAPOT translations suported
logic [3:0] PPNMixedBot;
mux2 #(4) napotmux(PPNMixed[3:0], VPN[3:0], PTE_N, PPNMixedBot);
assign PPNMixed2 = {PPNMixed[P.PPN_BITS-1:4], PPNMixedBot};
/* // Generalized NAPOT implementation supporting various sized contiguous regions
// This would also require a priority encoder in the tlbcam
// Not yet tested
logic [8:0] NAPOTMask, NAPOTPN, PPNMixedBot;
always_comb begin
casez(PPN[8:0])
9'b100000000: NAPOTMask = 9'b111111111;
9'b?10000000: NAPOTMask = 9'b011111111;
9'b??1000000: NAPOTMask = 9'b001111111;
9'b???100000: NAPOTMask = 9'b000111111;
9'b????10000: NAPOTMask = 9'b000011111;
9'b?????1000: NAPOTMask = 9'b000001111;
9'b??????100: NAPOTMask = 9'b000000111;
9'b???????10: NAPOTMask = 9'b000000011;
9'b????????1: NAPOTMask = 9'b000000001;
default: NAPOTMask = 9'b000000000;
endcase
end
// check malformed NAPOT PPN, which should cause page fault
// Replace PPN with VPN in lower bits of page number based on mask
assign NAPOTPN = VPN & NAPOTMask | PPN & ~NAPOTMask;
mux2 #(9) napotmux(PPNMixed[8:0], NAPOTPN, PTE_N, PPNMixedBot);
assign PPNMixed2 = {PPNMixed[PPN_BITS-1:9], PPNMixedBot}; */
end else begin // no Svnapot
assign PPNMixed2 = PPNMixed;
end
// Output the hit physical address if translation is currently on. // Output the hit physical address if translation is currently on.
// Provide physical address of zero if not TLBHits, to cause segmentation error if miss somehow percolated through signal // Provide physical address of zero if not TLBHits, to cause segmentation error if miss somehow percolated through signal
mux2 #(P.PA_BITS) hitmux('0, {PPNMixed, Offset}, TLBHit, TLBPAdr); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system mux2 #(P.PA_BITS) hitmux('0, {PPNMixed2, Offset}, TLBHit, TLBPAdr); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
endmodule endmodule

View File

@ -32,23 +32,24 @@
module tlbram import cvw::*; #(parameter cvw_t P, module tlbram import cvw::*; #(parameter cvw_t P,
parameter TLB_ENTRIES = 8) ( parameter TLB_ENTRIES = 8) (
input logic clk, reset, input logic clk, reset,
input logic [P.XLEN-1:0] PTE, input logic [P.XLEN-1:0] PTE,
input logic [TLB_ENTRIES-1:0] Matches, WriteEnables, input logic [TLB_ENTRIES-1:0] Matches, WriteEnables,
output logic [P.PPN_BITS-1:0] PPN, output logic [P.PPN_BITS-1:0] PPN,
output logic [7:0] PTEAccessBits, output logic [11:0] PTEAccessBits,
output logic [TLB_ENTRIES-1:0] PTE_Gs output logic [TLB_ENTRIES-1:0] PTE_Gs,
output logic [TLB_ENTRIES-1:0] PTE_NAPOTs // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
); );
logic [P.PPN_BITS+9:0] RamRead[TLB_ENTRIES-1:0]; logic [P.XLEN-1:0] RamRead[TLB_ENTRIES-1:0]; // stores the page table entries
logic [P.PPN_BITS+9:0] PageTableEntry; logic [P.XLEN-1:0] PageTableEntry;
// RAM implemented with array of flops and AND/OR read logic // RAM implemented with array of flops and AND/OR read logic
tlbramline #(P.PPN_BITS+10) tlbramline[TLB_ENTRIES-1:0] tlbramline #(P) tlbramline[TLB_ENTRIES-1:0]
(.clk, .reset, .re(Matches), .we(WriteEnables), (.clk, .reset, .re(Matches), .we(WriteEnables),
.d(PTE[P.PPN_BITS+9:0]), .q(RamRead), .PTE_G(PTE_Gs)); .d(PTE), .q(RamRead), .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs));
or_rows #(TLB_ENTRIES, P.PPN_BITS+10) PTEOr(RamRead, PageTableEntry); or_rows #(TLB_ENTRIES, P.XLEN) PTEOr(RamRead, PageTableEntry);
// Rename the bits read from the TLB RAM // Rename the bits read from the TLB RAM
assign PTEAccessBits = PageTableEntry[7:0]; assign PTEAccessBits = {PageTableEntry[P.XLEN-1:P.XLEN-4] & {4{P.XLEN == 64}}, PageTableEntry[7:0]}; // for RV64 include N and PBMT bits and OR of reserved bitss
assign PPN = PageTableEntry[P.PPN_BITS+9:10]; assign PPN = PageTableEntry[P.PPN_BITS+9:10];
endmodule endmodule

View File

@ -26,16 +26,28 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module tlbramline #(parameter WIDTH = 22) module tlbramline import cvw::*; #(parameter cvw_t P)
(input logic clk, reset, (input logic clk, reset,
input logic re, we, input logic re, we,
input logic [WIDTH-1:0] d, input logic [P.XLEN-1:0] d,
output logic [WIDTH-1:0] q, output logic [P.XLEN-1:0] q,
output logic PTE_G); output logic PTE_G,
output logic PTE_NAPOT // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
);
logic [WIDTH-1:0] line; logic [P.XLEN-1:0] line;
if (P.XLEN == 64) begin // save 7 reserved bits
// could optimize out N and PBMT from d[63:61] if they aren't supported
logic [57:0] ptereg;
logic reserved;
assign reserved = |d[60:54]; // are any of the reserved bits nonzero?
flopenr #(58) pteflop(clk, reset, we, {d[63:61], reserved, d[53:0]}, ptereg);
assign line = {ptereg[57:54], 6'b0, ptereg[53:0]};
end else // rv32
flopenr #(P.XLEN) pteflop(clk, reset, we, d, line);
flopenr #(WIDTH) pteflop(clk, reset, we, d, line);
assign q = re ? line : 0; assign q = re ? line : 0;
assign PTE_G = line[5]; // send global bit to CAM as part of ASID matching assign PTE_G = line[5]; // send global bit to CAM as part of ASID matching
assign PTE_NAPOT = P.SVNAPOT_SUPPORTED & line[P.XLEN-1] & (line[13:10] == 4'b1000); // send NAPOT bit to CAM as part of matching lsbs of VPN
endmodule endmodule

View File

@ -85,6 +85,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
output logic [3:0] ENVCFG_CBE, output logic [3:0] ENVCFG_CBE,
output logic ENVCFG_PBMTE, // Page-based memory type enable
// //
output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns
@ -127,7 +128,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
logic [63:0] MENVCFG_REGW; logic [63:0] MENVCFG_REGW;
logic [P.XLEN-1:0] SENVCFG_REGW; logic [P.XLEN-1:0] SENVCFG_REGW;
logic ENVCFG_STCE; // supervisor timer counter enable logic ENVCFG_STCE; // supervisor timer counter enable
logic ENVCFG_PBMTE; // page-based memory types enable
logic ENVCFG_FIOM; // fence implies io (presently not used) logic ENVCFG_FIOM; // fence implies io (presently not used)
// only valid unflushed instructions can access CSRs // only valid unflushed instructions can access CSRs

View File

@ -60,7 +60,7 @@ module csri import cvw::*; #(parameter cvw_t P) (
// SSIP is writable in SIP if S mode exists // SSIP is writable in SIP if S mode exists
if (P.S_SUPPORTED) begin:mask if (P.S_SUPPORTED) begin:mask
if (P.SSTC_SUPPORTED) begin if (P.SSTC_SUPPORTED) begin
assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec) assign MIP_WRITE_MASK = ENVCFG_STCE ? 12'h202 : 12'h222; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec)
assign STIP = ENVCFG_STCE ? STimerInt : MIP_REGW_writeable[5]; assign STIP = ENVCFG_STCE ? STimerInt : MIP_REGW_writeable[5];
end else begin end else begin
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)

View File

@ -88,8 +88,12 @@ module csrs import cvw::*; #(parameter cvw_t P) (
assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)); assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC));
assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)); assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE));
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL));
if(P.XLEN == 64) assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM) & (CSRWriteValM[63:60] != 4'hA); if(P.XLEN == 64) begin
else assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); logic LegalSatpModeM;
assign LegalSatpModeM = P.VIRTMEM_SUPPORTED & (CSRWriteValM[63:60] == 0 | CSRWriteValM[63:60] == P.SV39 | CSRWriteValM[63:60] == P.SV48); // supports SV39 and 48
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM) & LegalSatpModeM;
end else // RV32
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM) & P.VIRTMEM_SUPPORTED;
assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN);
assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG); assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG);
assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & STCE; assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & STCE;

View File

@ -83,6 +83,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU
output logic [2:0] FRM_REGW, // FPU rounding mode output logic [2:0] FRM_REGW, // FPU rounding mode
output logic [3:0] ENVCFG_CBE, // Cache block operation enables output logic [3:0] ENVCFG_CBE, // Cache block operation enables
output logic ENVCFG_PBMTE, // Page-based memory type enable
// PC logic output in privileged unit // PC logic output in privileged unit
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
// control outputs // control outputs
@ -137,7 +138,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
.MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
.SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE,
.CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM); .CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM);
// pipeline early-arriving trap sources // pipeline early-arriving trap sources

View File

@ -78,6 +78,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW; logic SquashSCW;
logic MDUActiveE; // Mul/Div instruction being executed logic MDUActiveE; // Mul/Div instruction being executed
logic ENVCFG_PBMTE; // Page-based memory type enable
logic [3:0] ENVCFG_CBE; // Cache Block operation enables logic [3:0] ENVCFG_CBE; // Cache Block operation enables
logic [3:0] CMOpM; // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero logic [3:0] CMOpM; // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
logic IFUPrefetchE, LSUPrefetchM; // instruction / data prefetch hints logic IFUPrefetchE, LSUPrefetchM; // instruction / data prefetch hints
@ -184,7 +185,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
// mmu management // mmu management
.PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV,
.STATUS_MPP, .ITLBWriteF, .sfencevmaM, .ITLBMissF, .STATUS_MPP, .ENVCFG_PBMTE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
// pmp/pma (inside mmu) signals. // pmp/pma (inside mmu) signals.
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF);
@ -231,7 +232,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.STATUS_MXR, // from csr .STATUS_MXR, // from csr
.STATUS_SUM, // from csr .STATUS_SUM, // from csr
.STATUS_MPRV, // from csr .STATUS_MPRV, // from csr
.STATUS_MPP, // from csr .STATUS_MPP, // from csr
.ENVCFG_PBMTE, // from csr
.sfencevmaM, // connects to privilege .sfencevmaM, // connects to privilege
.DCacheStallM, // connects to privilege .DCacheStallM, // connects to privilege
.LoadPageFaultM, // connects to privilege .LoadPageFaultM, // connects to privilege
@ -294,7 +296,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PrivilegeModeW, .SATP_REGW, .PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.FRM_REGW, .ENVCFG_CBE, .BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
end else begin end else begin
assign CSRReadValW = 0; assign CSRReadValW = 0;
assign UnalignedPCNextF = PC2NextF; assign UnalignedPCNextF = PC2NextF;

View File

@ -0,0 +1,56 @@
///////////////////////////////////////////
// wallypipelinedcorewrapper.sv
//
// Written: Kevin Kim kekim@hmc.edu 21 August 2023
// Modified:
//
// Purpose: A wrapper to set parameters. Vivado cannot set the top level parameters because it only supports verilog,
// not system verilog.
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
//`include "BranchPredictorType.vh"
`include "config.vh"
import cvw::*;
`include "parameter-defs.vh"
module wallypipelinedcorewrapper (
input logic clk, reset,
// Privileged
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
input logic [63:0] MTIME_CLINT,
// Bus Interface
input logic [P.XLEN-1:0] HRDATA,
input logic HREADY, HRESP,
output logic HCLK, HRESETn,
output logic [P.PA_BITS-1:0] HADDR,
output logic [32-1:0] HWDATA,
output logic [32/8-1:0] HWSTRB,
output logic HWRITE,
output logic [2:0] HSIZE,
output logic [2:0] HBURST,
output logic [3:0] HPROT,
output logic [1:0] HTRANS,
output logic HMASTLOCK
);
wallypipelinedcore #(P) core(.*);
endmodule

View File

@ -94,10 +94,10 @@ endif
ifneq ($(MOD), orig) ifneq ($(MOD), orig)
# PMP 0 # PMP 0
sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/config.vh sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES = 0;/' $(CONFIGDIR)/config.vh
ifneq ($(MOD), PMP0) ifneq ($(MOD), PMP0)
# no priv # no priv
sed -i 's/ZICSR_SUPPORTED *1/ZICSR_SUPPORTED 0/' $(CONFIGDIR)/config.vh sed -i 's/ZICSR_SUPPORTED *1/ZICSR_SUPPORTED = 0;/' $(CONFIGDIR)/config.vh
ifneq ($(MOD), noPriv) ifneq ($(MOD), noPriv)
# turn off FPU # turn off FPU
sed -i 's/1 *<< *3/0 << 3/' $(CONFIGDIR)/config.vh sed -i 's/1 *<< *3/0 << 3/' $(CONFIGDIR)/config.vh
@ -128,7 +128,7 @@ mkdirecs:
@mkdir -p $(OUTPUTDIR)/mapped @mkdir -p $(OUTPUTDIR)/mapped
@mkdir -p $(OUTPUTDIR)/unmapped @mkdir -p $(OUTPUTDIR)/unmapped
synth: mkdirecs configs rundc clean synth: mkdirecs configs rundc # clean
rundc: rundc:
ifeq ($(TECH), tsmc28psyn) ifeq ($(TECH), tsmc28psyn)

View File

@ -25,7 +25,8 @@ set maxopt $::env(MAXOPT)
set drive $::env(DRIVE) set drive $::env(DRIVE)
eval file copy -force [glob ${cfg}/*.vh] {$outputDir/hdl/} eval file copy -force [glob ${cfg}/*.vh] {$outputDir/hdl/}
eval file copy -force [glob ${hdl_src}/*.sv] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/cvw.sv] {$outputDir/hdl/}
#eval file copy -force [glob ${hdl_src}/../fpga/src/wallypipelinedsocwrapper.sv] {$outputDir/hdl/}
eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/}
eval file copy -force [glob ${hdl_src}/*/*/*.sv] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/*/*/*.sv] {$outputDir/hdl/}

View File

@ -0,0 +1,74 @@
"""
wrapperGen.py
kekim@hmc.edu
script that generates top-level wrappers for verilog modules to synthesize
"""
import argparse
import os
#create argument parser
parser = argparse.ArgumentParser()
parser.add_argument("fin")
args=parser.parse_args()
fin = open(args.fin, "r")
lines = fin.readlines()
# keeps track of what line number the module header begins
lineModuleStart = 0
# keeps track of what line number the module header ends
lineModuleEnd = 0
# keeps track of module name
moduleName = ""
# string that will keep track of the running module header
buf = "import cvw::*;\n`include \"config.vh\"\n`include \"parameter-defs.vh\"\n"
# are we writing into the buffer
writeBuf=False
index=0
# string copy logic
for l in lines:
if l.find("module") == 0:
lineModuleStart = index
moduleName = l.split()[1]
writeBuf = True
buf += f"module {moduleName}wrapper (\n"
continue
if (writeBuf):
buf += l
if l.find (");") == 0:
lineModuleEnd = index
break
index+=1
# post-processing buffer: add DUT and endmodule lines
buf += f"\t{moduleName} #(P) dut(.*);\nendmodule"
# path to wrapper
wrapperPath = f"{os.getenv('WALLY')}/src/wrappers/{moduleName}wrapper.sv"
# clear wrappers directory
os.system(f"rm {os.getenv('WALLY')}/src/wrappers/*")
fout = open(wrapperPath, "w")
fout.write(buf)
fin.close()
fout.close()
print(buf)

View File

@ -58,9 +58,11 @@ module riscvassertions import cvw::*; #(parameter cvw_t P);
assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled"); assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled");
assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED"); assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED");
assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $error("ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED"); assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $error("ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED");
assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOM required DCACHE_SUPPORTED"); assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOM requires DCACHE_SUPPORTED");
assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOZ required DCACHE_SUPPORTED"); assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOZ requires DCACHE_SUPPORTED");
assert ((P.ZICBOP_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOP required DCACHE_SUPPORTED"); assert ((P.ZICBOP_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOP requires DCACHE_SUPPORTED");
assert ((P.SVPBMT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVPBMT requires VIRTMEM_SUPPORTED and RV64");
assert ((P.SVNAPOT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVNAPOT requires VIRTMEM_SUPPORTED and RV64");
end end
endmodule endmodule

View File

@ -1944,7 +1944,7 @@ string arch64zbs[] = '{
"rv64i_m/privilege/src/WALLY-misa-01.S", "rv64i_m/privilege/src/WALLY-misa-01.S",
// "rv64i_m/privilege/src/WALLY-mmu-sv39-01.S", // run this if SVADU_SUPPORTED = 0 // "rv64i_m/privilege/src/WALLY-mmu-sv39-01.S", // run this if SVADU_SUPPORTED = 0
// "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S", // run this if SVADU_SUPPORTED = 0 // "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S", // run this if SVADU_SUPPORTED = 0
"rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S", // run this if SVADU_SUPPORTED = 1 "rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-svnapot-svpbmt-01.S", // run this if SVADU_SUPPORTED = 1
"rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S", // run this if SVADU_SUPPORTED = 1 "rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S", // run this if SVADU_SUPPORTED = 1
"rv64i_m/privilege/src/WALLY-mtvec-01.S", "rv64i_m/privilege/src/WALLY-mtvec-01.S",
"rv64i_m/privilege/src/WALLY-pma-01.S", "rv64i_m/privilege/src/WALLY-pma-01.S",

View File

@ -72,7 +72,7 @@ sretdone:
li a0, 3 li a0, 3
ecall # in M-mode ecall # in M-mode
li t0, 32 li t0, 32
csrs sip, t0 csrs mip, t0
li a0, 1 li a0, 1
ecall # in S-mode and expects stimer interrupt to occur ecall # in S-mode and expects stimer interrupt to occur
li a0, 3 li a0, 3

View File

@ -41,11 +41,11 @@ beef0110
00000bad 00000bad
0000000f 0000000f
beef0bb0 beef0bb0
beef0077 # Test 12.3.1.4.1: successful read back of saved value with new memory mapping beef0077 # Test 11.3.1.4.1: successful read back of saved value with new memory mapping
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 # previous value of mprv before being set 00000000 # previous value of mprv before being set
beef0099 # Read success from translated address when mprv=1, mpp=S and priv mode = m beef0099 # Read success from translated address when mprv=1, mpp=S and priv mode = m
0000000b # Test 12.3.1.5.2: ecall from going to S mode from m mode 0000000b # Test 11.3.1.5.2: ecall from going to S mode from m mode
00000009 # ecall from going straight back to m mode to access mstatus 00000009 # ecall from going straight back to m mode to access mstatus
00000000 # previous zeroed out value of mprv 00000000 # previous zeroed out value of mprv
0000000b # ecall from terminating tests in m mode 0000000b # ecall from terminating tests in m mode

View File

@ -35,13 +35,13 @@ beef0110
0000000f 0000000f
0000000c 0000000c
00000bad 00000bad
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1 beef0770 # Test 11.3.1.3.5: check successful read/write when A=0 and SVADU=1
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1 beef0aa0 # Test 11.3.1.3.6: check successful read/write when D=0 and SVADU=1
beef0077 # Test 12.3.1.4.1: successful read back of saved value with new memory mapping beef0077 # Test 11.3.1.4.1: successful read back of saved value with new memory mapping
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 # previous value of mprv before being set 00000000 # previous value of mprv before being set
beef0099 # Read success from translated address when mprv=1, mpp=S and priv mode = m beef0099 # Read success from translated address when mprv=1, mpp=S and priv mode = m
0000000b # Test 12.3.1.5.2: ecall from going to S mode from m mode 0000000b # Test 11.3.1.5.2: ecall from going to S mode from m mode
00000009 # ecall from going straight back to m mode to access mstatus 00000009 # ecall from going straight back to m mode to access mstatus
00000000 # previous zeroed out value of mprv 00000000 # previous zeroed out value of mprv
0000000b # ecall from terminating tests in m mode 0000000b # ecall from terminating tests in m mode

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV32
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -52,9 +52,9 @@ test_cases:
# #
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv32 Page table (See Figure 12.12***): # sv32 Page table (See Figure 12.12***):
# Level 1 page table, situated at 0x8000D000 # Level 1 page table, situated at 0x8000D000
.4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A .4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A
@ -78,19 +78,19 @@ test_cases:
.4byte 0x8000F000, 0x200000CF, write32_test # Vaddr 0x0 Paddr 0x80000000: aligned megapage .4byte 0x8000F000, 0x200000CF, write32_test # Vaddr 0x0 Paddr 0x80000000: aligned megapage
.4byte 0x8000F800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory) .4byte 0x8000F800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.4byte 0x800AAAA8, 0xBEEF0055, write32_test # 8.3.1.1.4 megapage .4byte 0x800AAAA8, 0xBEEF0055, write32_test # 11.3.1.1.4 megapage
.4byte 0x800FFAC0, 0xBEEF0033, write32_test # 8.3.1.3.2 .4byte 0x800FFAC0, 0xBEEF0033, write32_test # 11.3.1.3.2
.4byte 0x800E3130, 0xBEEF0077, write32_test # 8.3.1.3.2 .4byte 0x800E3130, 0xBEEF0077, write32_test # 11.3.1.3.2
.4byte 0x808017E0, 0xBEEF0099, write32_test # 8.3.1.1.4 kilopage .4byte 0x808017E0, 0xBEEF0099, write32_test # 11.3.1.1.4 kilopage
.4byte 0x80805EA0, 0xBEEF0440, write32_test # 8.3.1.3.3 .4byte 0x80805EA0, 0xBEEF0440, write32_test # 11.3.1.3.3
.4byte 0x80803AA0, 0xBEEF0BB0, write32_test # 8.3.1.3.7 .4byte 0x80803AA0, 0xBEEF0BB0, write32_test # 11.3.1.3.7
.4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region. .4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region.
.4byte 0x8000FFA4, 0x00008067, write32_test # Used for 8.3.1.3.1, 8.3.1.3.2 .4byte 0x8000FFA4, 0x00008067, write32_test # Used for 11.3.1.3.1, 11.3.1.3.2
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. .4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.4byte 0x800AAAA8, 0xBEEF0055, read32_test .4byte 0x800AAAA8, 0xBEEF0055, read32_test
@ -102,38 +102,38 @@ test_cases:
.4byte 0x8000FFA0, 0x11100393, read32_test .4byte 0x8000FFA0, 0x11100393, read32_test
.4byte 0x8000FFA4, 0x00008067, read32_test .4byte 0x8000FFA4, 0x00008067, read32_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.4byte 0x8000D, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output .4byte 0x8000D, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output
.4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000 .4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000
.4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000 .4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 load page fault if upper bits of Vaddr are not the same
# Not tested in rv32/sv32 # Not tested in rv32/sv32
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero # test 11.3.1.2.2 load page fault when reading an address where the valid flag is zero
.4byte 0x6000, 0x0, read32_test .4byte 0x6000, 0x0, read32_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set # test 11.3.1.2.3 store page fault if PTE has W and ~R flags set
.4byte 0x2000, 0x0, write32_test .4byte 0x2000, 0x0, write32_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.4byte 0x0200, 0x0, read32_test .4byte 0x0200, 0x0, read32_test
# test 8.3.1.2.5 load page fault on misaligned pages # test 11.3.1.2.5 load page fault on misaligned pages
.4byte 0xC00000, 0x0, read32_test # misaligned megapage .4byte 0xC00000, 0x0, read32_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4 # *** reads on pages with U=0 already tested in 11.3.1.1.4
.4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S .4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S
.4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output .4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output
.4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U .4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U
.4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U .4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U .4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U
.4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output .4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -142,61 +142,61 @@ test_cases:
.4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0 .4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4 # *** reads on pages with R=1 already tested in 11.3.1.1.4
.4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0 .4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1 .4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1 .4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1
.4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading .4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading
.4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0 .4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1 # *** fetches on pages with X = 1 already tested in 11.3.1.3.1
.4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0 .4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0
# In the following two tests, SVADU is not supported, so the software handles the A/D bits # In the following two tests, SVADU is not supported, so the software handles the A/D bits
# Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits # Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.4byte 0x3020, 0xBEEF0770, write32_test # store page fault when A=0 .4byte 0x3020, 0xBEEF0770, write32_test # store page fault when A=0
.4byte 0x3808, 0xBEEF0990, read32_test # load page fault when A=0 .4byte 0x3808, 0xBEEF0990, read32_test # load page fault when A=0
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.4byte 0x4658, 0xBEEF0AA0, write32_test # store page fault when D=0 .4byte 0x4658, 0xBEEF0AA0, write32_test # store page fault when D=0
.4byte 0x4AA0, 0xBEEF0BB0, read32_test # read success when D=0 .4byte 0x4AA0, 0xBEEF0BB0, read32_test # read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # =========== test 11.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .4byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write32_test # write identical value to global PTE to make sure it's still in the TLB // *** .4byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write32_test # write identical value to global PTE to make sure it's still in the TLB
.4byte 0x8000F, 0x11, goto_sv32 # go to SV39 on a second, very minimal page table .4byte 0x8000F, 0x11, goto_sv32 # go to SV39 on a second, very minimal page table
.4byte 0xE3130, 0xBEEF0077, read32_test # Read success of old written value from a new page table mapping .4byte 0xE3130, 0xBEEF0077, read32_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.4byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read32_test # read success of global PTE undefined in current mapping. // ***.4byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read32_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.4byte 0x8000D, 0x0, goto_sv32 // go back to old, extensive page table .4byte 0x8000D, 0x0, goto_sv32 // go back to old, extensive page table
.4byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .4byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.4byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .4byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.4byte 0xBFF7E0, 0xBEEF0099, read32_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .4byte 0xBFF7E0, 0xBEEF0099, read32_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.4byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .4byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.4byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .4byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.4byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .4byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV32
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -52,9 +52,9 @@ test_cases:
# #
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv32 Page table (See Figure 12.12***): # sv32 Page table (See Figure 12.12***):
# Level 1 page table, situated at 0x8000D000 # Level 1 page table, situated at 0x8000D000
.4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A .4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A
@ -78,18 +78,18 @@ test_cases:
.4byte 0x8000F000, 0x200000CF, write32_test # Vaddr 0x0 Paddr 0x80000000: aligned megapage .4byte 0x8000F000, 0x200000CF, write32_test # Vaddr 0x0 Paddr 0x80000000: aligned megapage
.4byte 0x8000F800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory) .4byte 0x8000F800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.4byte 0x800AAAA8, 0xBEEF0055, write32_test # 8.3.1.1.4 megapage .4byte 0x800AAAA8, 0xBEEF0055, write32_test # 11.3.1.1.4 megapage
.4byte 0x800FFAC0, 0xBEEF0033, write32_test # 8.3.1.3.2 .4byte 0x800FFAC0, 0xBEEF0033, write32_test # 11.3.1.3.2
.4byte 0x800E3130, 0xBEEF0077, write32_test # 8.3.1.3.2 .4byte 0x800E3130, 0xBEEF0077, write32_test # 11.3.1.3.2
.4byte 0x808017E0, 0xBEEF0099, write32_test # 8.3.1.1.4 kilopage .4byte 0x808017E0, 0xBEEF0099, write32_test # 11.3.1.1.4 kilopage
.4byte 0x80805EA0, 0xBEEF0440, write32_test # 8.3.1.3.3 .4byte 0x80805EA0, 0xBEEF0440, write32_test # 11.3.1.3.3
.4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region. .4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region.
.4byte 0x8000FFA4, 0x00008067, write32_test # Used for 8.3.1.3.1, 8.3.1.3.2 .4byte 0x8000FFA4, 0x00008067, write32_test # Used for 11.3.1.3.1, 11.3.1.3.2
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. .4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.4byte 0x800AAAA8, 0xBEEF0055, read32_test .4byte 0x800AAAA8, 0xBEEF0055, read32_test
@ -100,38 +100,38 @@ test_cases:
.4byte 0x8000FFA0, 0x11100393, read32_test .4byte 0x8000FFA0, 0x11100393, read32_test
.4byte 0x8000FFA4, 0x00008067, read32_test .4byte 0x8000FFA4, 0x00008067, read32_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.4byte 0x8000D, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output .4byte 0x8000D, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output
.4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000 .4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000
.4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000 .4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 load page fault if upper bits of Vaddr are not the same
# Not tested in rv32/sv32 # Not tested in rv32/sv32
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero # test 11.3.1.2.2 load page fault when reading an address where the valid flag is zero
.4byte 0x6000, 0x0, read32_test .4byte 0x6000, 0x0, read32_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set # test 11.3.1.2.3 store page fault if PTE has W and ~R flags set
.4byte 0x2000, 0x0, write32_test .4byte 0x2000, 0x0, write32_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.4byte 0x0200, 0x0, read32_test .4byte 0x0200, 0x0, read32_test
# test 8.3.1.2.5 load page fault on misaligned pages # test 11.3.1.2.5 load page fault on misaligned pages
.4byte 0xC00000, 0x0, read32_test # misaligned megapage .4byte 0xC00000, 0x0, read32_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4 # *** reads on pages with U=0 already tested in 11.3.1.1.4
.4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S .4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S
.4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output .4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output
.4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U .4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U
.4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U .4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U .4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U
.4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output .4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -140,61 +140,61 @@ test_cases:
.4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0 .4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4 # *** reads on pages with R=1 already tested in 11.3.1.1.4
.4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0 .4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1 .4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1 .4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1
.4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading .4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading
.4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0 .4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1 # *** fetches on pages with X = 1 already tested in 11.3.1.3.1
.4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0 .4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits # In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0 # Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.4byte 0x3020, 0xBEEF0770, write32_test # Write success when A=0 and SVADU is enabled .4byte 0x3020, 0xBEEF0770, write32_test # Write success when A=0 and SVADU is enabled
.4byte 0x3020, 0xBEEF0770, read32_test # Read success when A=0 and SVADU is enabled .4byte 0x3020, 0xBEEF0770, read32_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.4byte 0x4658, 0xBEEF0AA0, write32_test # write successs when D=0 and SVADU is enabled .4byte 0x4658, 0xBEEF0AA0, write32_test # write successs when D=0 and SVADU is enabled
.4byte 0x4658, 0xBEEF0AA0, read32_test # read success when D=0 .4byte 0x4658, 0xBEEF0AA0, read32_test # read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # =========== test 11.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .4byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write32_test # write identical value to global PTE to make sure it's still in the TLB // *** .4byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write32_test # write identical value to global PTE to make sure it's still in the TLB
.4byte 0x8000F, 0x11, goto_sv32 # go to SV39 on a second, very minimal page table .4byte 0x8000F, 0x11, goto_sv32 # go to SV39 on a second, very minimal page table
.4byte 0xE3130, 0xBEEF0077, read32_test # Read success of old written value from a new page table mapping .4byte 0xE3130, 0xBEEF0077, read32_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.4byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read32_test # read success of global PTE undefined in current mapping. // ***.4byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read32_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.4byte 0x8000D, 0x0, goto_sv32 // go back to old, extensive page table .4byte 0x8000D, 0x0, goto_sv32 // go back to old, extensive page table
.4byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .4byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.4byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .4byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.4byte 0xBFF7E0, 0xBEEF0099, read32_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .4byte 0xBFF7E0, 0xBEEF0099, read32_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.4byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .4byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.4byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .4byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.4byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .4byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -1,4 +1,4 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode 0000000b # Test 11.3.1.1.3: ecall from going to S mode from M mode
00000000 00000000
beef0000 # Read test success from confirming writes of known values beef0000 # Read test success from confirming writes of known values
0000dead 0000dead
@ -14,13 +14,13 @@ beef0440 # Read test success from confirming writes of known values
0330dead 0330dead
beef0bb0 # Read test success from confirming writes of known values beef0bb0 # Read test success from confirming writes of known values
0440dead 0440dead
beef0000 # Test 12.3.1.1.4: Read test success from checking translation works beef0000 # Test 11.3.1.1.4: Read test success from checking translation works
0000dead 0000dead
beef0055 # Read test success from checking translation works beef0055 # Read test success from checking translation works
0880dead 0880dead
beef0099 # Read test success from checking translation works beef0099 # Read test success from checking translation works
0220dead 0220dead
0000000d # Test 12.3.1.2.1: Read test with page fault from upper vaddr bits not the same 0000000d # Test 11.3.1.2.1: Read test with page fault from upper vaddr bits not the same
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -28,17 +28,17 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.2: read test with page fault 0000000d # Test 11.3.1.2.2: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.2.3: write test with page fault 0000000f # Test 11.3.1.2.3: write test with page fault
00000000 00000000
0000000d # Test 12.3.1.2.4: read test with page fault 0000000d # Test 11.3.1.2.4: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.5: 2 read tests with page faults 0000000d # Test 11.3.1.2.5: 2 read tests with page faults
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -46,7 +46,7 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
00000111 # Test 12.3.1.3.1: execute test success 00000111 # Test 11.3.1.3.1: execute test success
00000000 00000000
00000009 # ecall from going to U mode from S mode 00000009 # ecall from going to U mode from S mode
00000000 00000000
@ -58,7 +58,7 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0033 # Test 12.3.1.3.2: read test success beef0033 # Test 11.3.1.3.2: read test success
0990dead 0990dead
00000008 # ecall from going to S mode from U mode 00000008 # ecall from going to S mode from U mode
00000000 00000000
@ -72,39 +72,43 @@ beef0077 # read test success
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.3.3: read test with page fault 0000000d # Test 11.3.1.3.3: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0440 # read test success beef0440 # read test success
0330dead 0330dead
beef0110 # Test 12.3.1.3.4: read test success beef0110 # Test 11.3.1.3.4: read test success
0440dead 0440dead
0000000f # write test with page fault 0000000f # write test with page fault
00000000 00000000
0000000c # Test 12.3.1.3.5: execute test with page fault 0000000c # Test 11.3.1.3.5: execute test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.3.6: write test with page fault 0000000f # Test 11.3.1.3.6: write test with page fault
00000000 00000000
0000000d # read test with page fault 0000000d # read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.3.7: write test with page fault 0000000f # Test 11.3.1.3.7: write test with page fault
00000000 00000000
beef0bb0 # read test success beef0bb0 # read test success
0440dead 0440dead
beef0000 # Test 12.3.1.4.1: read test success from new page table mapping 0000000c # Test 11.3.1.3.8: read test with page fault for nonzero reserved bit
00000000
00000bad
00000000
beef0000 # Test 11.3.1.4.1: read test success from new page table mapping
0000dead 0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 00000000
00000000 # previous mprv value before writing 1 to it. 00000000 # previous mprv value before writing 1 to it.
00000000 00000000
beef0099 # Read test success when mprv=1 So translation should occur beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off 0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv) 0000000b # Test 11.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000 00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus) 00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000 00000000

View File

@ -1,4 +1,4 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode 0000000b # Test 11.3.1.1.3: ecall from going to S mode from M mode
00000000 00000000
beef0000 # Read test success from confirming writes of known values beef0000 # Read test success from confirming writes of known values
0000dead 0000dead
@ -12,13 +12,13 @@ beef0099 # Read test success from confirming writes of known values
0220dead 0220dead
beef0440 # Read test success from confirming writes of known values beef0440 # Read test success from confirming writes of known values
0330dead 0330dead
beef0000 # Test 12.3.1.1.4: Read test success from checking translation works beef0000 # Test 11.3.1.1.4: Read test success from checking translation works
0000dead 0000dead
beef0055 # Read test success from checking translation works beef0055 # Read test success from checking translation works
0880dead 0880dead
beef0099 # Read test success from checking translation works beef0099 # Read test success from checking translation works
0220dead 0220dead
0000000d # Test 12.3.1.2.1: Read test with page fault from upper vaddr bits not the same 0000000d # Test 11.3.1.2.1: Read test with page fault from upper vaddr bits not the same
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -26,17 +26,17 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.2: read test with page fault 0000000d # Test 11.3.1.2.2: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.2.3: write test with page fault 0000000f # Test 11.3.1.2.3: write test with page fault
00000000 00000000
0000000d # Test 12.3.1.2.4: read test with page fault 0000000d # Test 11.3.1.2.4: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.5: 2 read tests with page faults 0000000d # Test 11.3.1.2.5: 2 read tests with page faults
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -44,7 +44,7 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
00000111 # Test 12.3.1.3.1: execute test success 00000111 # Test 11.3.1.3.1: execute test success
00000000 00000000
00000009 # ecall from going to U mode from S mode 00000009 # ecall from going to U mode from S mode
00000000 00000000
@ -56,7 +56,7 @@ beef0099 # Read test success from checking translation works
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0033 # Test 12.3.1.3.2: read test success beef0033 # Test 11.3.1.3.2: read test success
0990dead 0990dead
00000008 # ecall from going to S mode from U mode 00000008 # ecall from going to S mode from U mode
00000000 00000000
@ -70,33 +70,51 @@ beef0077 # read test success
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.3.3: read test with page fault 0000000d # Test 11.3.1.3.3: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0440 # read test success beef0440 # read test success
0330dead 0330dead
beef0110 # Test 12.3.1.3.4: read test success beef0110 # Test 11.3.1.3.4: read test success
0440dead 0440dead
0000000f # write test with page fault 0000000f # write test with page fault
00000000 00000000
0000000c # Test 12.3.1.3.5: execute test with page fault 0000000c # Test 11.3.1.3.5: execute test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1 beef0770 # Test 11.3.1.3.6: check successful read/write when A=0 and SVADU=1
0990dead 0990dead
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1 beef0aa0 # Test 11.3.1.3.7: check successful read/write when D=0 and SVADU=1
0440dead 0440dead
beef0000 # Test 12.3.1.4.1: read test success from new page table mapping 0000000d # Test 11.3.1.3.8: read test with page fault for nonzero reserved bit
00000000
00000bad
00000000
BEEF0660 # Test 11.3.1.3.9: NAPOT read
0550DEAD
0000000f # Test 11.3.1.3.10: PBMT; write page fault because menvcfg.PBMTE = 0
00000000
00000009 # ecall from going to M mode from S mode
00000000
0000000B # ecall from going to S mode from M mode
00000000
56567878 # write with PBMT = 1
12123434
56567878 # write with PBMT = 2
23123434
0000000f # write page fault because PBMT = 3
00000000
beef0000 # Test 11.3.1.4.1: read test success from new page table mapping
0000dead 0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 00000000
00000000 # previous mprv value before writing 1 to it. 00000000 # previous mprv value before writing 1 to it.
00000000 00000000
beef0099 # Read test success when mprv=1 So translation should occur beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off 0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv) 0000000b # Test 11.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000 00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus) 00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000 00000000

View File

@ -1,4 +1,4 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode 0000000b # Test 11.3.1.1.3: ecall from going to S mode from M mode
00000000 00000000
beef0cc0 # 8 read test successes beef0cc0 # 8 read test successes
0ee0dead 0ee0dead
@ -16,7 +16,7 @@ beef0440 # read 7
0330dead 0330dead
beef0bb0 # read 8 beef0bb0 # read 8
0440dead 0440dead
beef0cc0 # Test 12.3.1.1.4: 4 read test successes beef0cc0 # Test 11.3.1.1.4: 4 read test successes
0ee0dead 0ee0dead
beef0000 # read 2 beef0000 # read 2
0000dead 0000dead
@ -24,7 +24,7 @@ beef0055 # read 3
0880dead 0880dead
beef0099 # read 4 beef0099 # read 4
0220dead 0220dead
0000000d # Test 12.3.1.2.1: 2 read tests with page fault 0000000d # Test 11.3.1.2.1: 2 read tests with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -32,17 +32,17 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.2: read test with page fault 0000000d # Test 11.3.1.2.2: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.2.3: write test with page fault 0000000f # Test 11.3.1.2.3: write test with page fault
00000000 00000000
0000000d # Test 12.3.1.2.4: read test with page fault 0000000d # Test 11.3.1.2.4: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.5: 3 read tests with page fault 0000000d # Test 11.3.1.2.5: 3 read tests with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -54,7 +54,7 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
00000111 # Test 12.3.1.3.1: Execute test success 00000111 # Test 11.3.1.3.1: Execute test success
00000000 00000000
00000009 # ecall from going to U mode from S mode 00000009 # ecall from going to U mode from S mode
00000000 00000000
@ -66,7 +66,7 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0033 # Test 12.3.1.3.2: read test success beef0033 # Test 11.3.1.3.2: read test success
0990dead 0990dead
00000008 # ecall from going to S mode from U mode 00000008 # ecall from going to S mode from U mode
00000000 00000000
@ -80,39 +80,39 @@ beef0077 # read test success
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.3.3: read test with page fault 0000000d # Test 11.3.1.3.3: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0440 # read test success beef0440 # read test success
0330dead 0330dead
beef0110 # Test 12.3.1.3.4: read test success beef0110 # Test 11.3.1.3.4: read test success
0440dead 0440dead
0000000f # write test with page fault 0000000f # write test with page fault
00000000 00000000
0000000c # Test 12.3.1.3.5: executable test with page fault 0000000c # Test 11.3.1.3.5: executable test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.3.6: write test with page fault 0000000f # Test 11.3.1.3.6: write test with page fault
00000000 00000000
0000000d # read test with page fault 0000000d # read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.3.7: write test with page fault 0000000f # Test 11.3.1.3.7: write test with page fault
00000000 00000000
beef0bb0 # read test success beef0bb0 # read test success
0440dead 0440dead
beef0000 # Test 12.3.1.4.1: read test success on new page table mapping beef0000 # Test 11.3.1.4.1: read test success on new page table mapping
0000dead 0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 00000000
00000000 # previous value of mprv before write 00000000 # previous value of mprv before write
00000000 00000000
beef0099 # Read test success when mprv=1 So translation should occur beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off 0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv) 0000000b # Test 11.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000 00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus) 00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000 00000000

View File

@ -1,4 +1,4 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode 0000000b # Test 11.3.1.1.3: ecall from going to S mode from M mode
00000000 00000000
beef0cc0 # 8 read test successes beef0cc0 # 8 read test successes
0ee0dead 0ee0dead
@ -14,7 +14,7 @@ beef0099 # read 6
0220dead 0220dead
beef0440 # read 7 beef0440 # read 7
0330dead 0330dead
beef0cc0 # Test 12.3.1.1.4: 4 read test successes beef0cc0 # Test 11.3.1.1.4: 4 read test successes
0ee0dead 0ee0dead
beef0000 # read 2 beef0000 # read 2
0000dead 0000dead
@ -22,7 +22,7 @@ beef0055 # read 3
0880dead 0880dead
beef0099 # read 4 beef0099 # read 4
0220dead 0220dead
0000000d # Test 12.3.1.2.1: 2 read tests with page fault 0000000d # Test 11.3.1.2.1: 2 read tests with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -30,17 +30,17 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.2: read test with page fault 0000000d # Test 11.3.1.2.2: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000f # Test 12.3.1.2.3: write test with page fault 0000000f # Test 11.3.1.2.3: write test with page fault
00000000 00000000
0000000d # Test 12.3.1.2.4: read test with page fault 0000000d # Test 11.3.1.2.4: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.2.5: 3 read tests with page fault 0000000d # Test 11.3.1.2.5: 3 read tests with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
@ -52,7 +52,7 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
00000111 # Test 12.3.1.3.1: Execute test success 00000111 # Test 11.3.1.3.1: Execute test success
00000000 00000000
00000009 # ecall from going to U mode from S mode 00000009 # ecall from going to U mode from S mode
00000000 00000000
@ -64,7 +64,7 @@ beef0099 # read 4
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0033 # Test 12.3.1.3.2: read test success beef0033 # Test 11.3.1.3.2: read test success
0990dead 0990dead
00000008 # ecall from going to S mode from U mode 00000008 # ecall from going to S mode from U mode
00000000 00000000
@ -78,33 +78,33 @@ beef0077 # read test success
00000000 00000000
00000bad 00000bad
00000000 00000000
0000000d # Test 12.3.1.3.3: read test with page fault 0000000d # Test 11.3.1.3.3: read test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0440 # read test success beef0440 # read test success
0330dead 0330dead
beef0110 # Test 12.3.1.3.4: read test success beef0110 # Test 11.3.1.3.4: read test success
0440dead 0440dead
0000000f # write test with page fault 0000000f # write test with page fault
00000000 00000000
0000000c # Test 12.3.1.3.5: executable test with page fault 0000000c # Test 11.3.1.3.5: executable test with page fault
00000000 00000000
00000bad 00000bad
00000000 00000000
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1 beef0770 # Test 11.3.1.3.5: check successful read/write when A=0 and SVADU=1
0990dead 0990dead
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1 beef0aa0 # Test 11.3.1.3.6: check successful read/write when D=0 and SVADU=1
0440dead 0440dead
beef0000 # Test 12.3.1.4.1: read test success on new page table mapping beef0000 # Test 11.3.1.4.1: read test success on new page table mapping
0000dead 0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode 00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
00000000 00000000
00000000 # previous value of mprv before write 00000000 # previous value of mprv before write
00000000 00000000
beef0099 # Read test success when mprv=1 So translation should occur beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off 0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv) 0000000b # Test 11.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000 00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus) 00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000 00000000

View File

@ -1362,6 +1362,12 @@ write_mideleg:
csrw mideleg, t4 csrw mideleg, t4
j test_loop j test_loop
write_menvcfg:
// writes the value in t4 to the menvcfg register
// Doesn't log anything
csrw menvcfg, t4
j test_loop
executable_test: executable_test:
// Execute the code at the address in t3, returning the value in t2. // Execute the code at the address in t3, returning the value in t2.
// Assumes the code modifies t2, to become the value stored in t4 for this test. // Assumes the code modifies t2, to become the value stored in t4 for this test.

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV39
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -52,9 +52,9 @@ test_cases:
# #
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv39 page table (See Figure 12.12***): # sv39 page table (See Figure 12.12***):
# Level 2 page table, situated at 0x8000D000 # Level 2 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A .8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A
@ -82,6 +82,7 @@ test_cases:
.8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault .8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault
.8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault .8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault
.8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page .8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page
.8byte 0x0000000080018038, 0x01000000200800DF, write64_test# Vaddr 0x7000, Paddr = 0x80200000, bad reserved bit
# Level 0 page table B # Level 0 page table B
.8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage .8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage
@ -89,20 +90,20 @@ test_cases:
.8byte 0x8FFFF000, 0x200000CF, write64_test# Vaddr 0x0, Paddr 0x80000000 aligned gigapage .8byte 0x8FFFF000, 0x200000CF, write64_test# Vaddr 0x0, Paddr 0x80000000 aligned gigapage
.8byte 0x8FFFF010, 0x200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory so we can execute without jumping around) .8byte 0x8FFFF010, 0x200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory so we can execute without jumping around)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test# 8.3.1.1.4 and 8.3.1.4.1 .8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test# 11.3.1.1.4 and 11.3.1.4.1
.8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test# 8.3.1.1.4 .8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test# 11.3.1.1.4
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test# 8.3.1.3.2 .8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test# 11.3.1.3.2
.8byte 0x80203130, 0x0110DEADBEEF0077, write64_test# 8.3.1.3.2 .8byte 0x80203130, 0x0110DEADBEEF0077, write64_test# 11.3.1.3.2
.8byte 0x80099000, 0x0000806711100393, write64_test# 8.3.1.3.1 and 8.3.1.3.2 write executable code for "li x7, 0x111; ret" .8byte 0x80099000, 0x0000806711100393, write64_test# 11.3.1.3.1 and 11.3.1.3.2 write executable code for "li x7, 0x111; ret"
.8byte 0x80205AA0, 0x0000806711100393, write64_test# 8.3.1.3.5 write same executable code .8byte 0x80205AA0, 0x0000806711100393, write64_test# 11.3.1.3.5 write same executable code
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test# 8.3.1.1.4 .8byte 0x80201888, 0x0220DEADBEEF0099, write64_test# 11.3.1.1.4
.8byte 0x84212348, 0x0330DEADBEEF0440, write64_test# 8.3.1.3.3 .8byte 0x84212348, 0x0330DEADBEEF0440, write64_test# 11.3.1.3.3
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test# 8.3.1.3.7 .8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test# 11.3.1.3.7
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation. .8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test .8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test
@ -113,42 +114,42 @@ test_cases:
.8byte 0x84212348, 0x0330DEADBEEF0440, read64_test .8byte 0x84212348, 0x0330DEADBEEF0440, read64_test
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test .8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test
# test 8.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv39 # satp.MODE = sv39, with base page table PPN = 0x8000D and ASID = 0. current VPN: gigapage at 0x80000000. .8byte 0x8000D, 0x0, goto_sv39 # satp.MODE = sv39, with base page table PPN = 0x8000D and ASID = 0. current VPN: gigapage at 0x80000000.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000 .8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000 .8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 load page fault if upper bits of Vaddr are not the same
.8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits .8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits .8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero # test 11.3.1.2.2 load page fault when reading an address where the valid flag is zero
.8byte 0x6000, 0x0, read64_test .8byte 0x6000, 0x0, read64_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set # test 11.3.1.2.3 store page fault if PTE has W and ~R flags set
.8byte 0x2000, 0x0, write64_test .8byte 0x2000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x0020, 0x0, read64_test .8byte 0x0020, 0x0, read64_test
# test 8.3.1.2.5 load page fault on misaligned pages # test 11.3.1.2.5 load page fault on misaligned pages
.8byte 0xC0000000, 0x0, read64_test# misaligned gigapage .8byte 0xC0000000, 0x0, read64_test# misaligned gigapage
.8byte 0x40200000, 0x0, read64_test# misaligned megapage .8byte 0x40200000, 0x0, read64_test# misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4 # *** reads on pages with U=0 already tested in 11.3.1.1.4
.8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S .8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output .8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U .8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U
.8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U .8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U .8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output .8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -157,61 +158,64 @@ test_cases:
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0 .8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4 # *** reads on pages with R=1 already tested in 11.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0 .8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 .8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1 .8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address .8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address
.8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0 .8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1 # *** fetches on pages with X = 1 already tested in 11.3.1.3.1
.8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0 .8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0
# In the following two tests, SVADU is not supported, so the software handles the A/D bits # In the following two tests, SVADU is not supported, so the software handles the A/D bits
# Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits # Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.8byte 0x36D0, 0x0990DEADBEEF0770, write64_test# store page fault when A=0 .8byte 0x36D0, 0x0990DEADBEEF0770, write64_test# store page fault when A=0
.8byte 0x3AB8, 0x0990DEADBEEF0990, read64_test# load page fault when A=0 .8byte 0x3AB8, 0x0990DEADBEEF0990, read64_test# load page fault when A=0
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test# store page fault when D=0 .8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test# store page fault when D=0
.8byte 0x4AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0 .8byte 0x4AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # test 11.3.1.3.8 Reserved bits nonzero
.8byte 0x7AA0, 0x123456789ABCDEF, read64_test # load page fault because reserved is nonzero
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # =========== test 11.3.1.4 SATP Register ===========
# test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB // *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8FFFF, 0x11, goto_sv39 # go to SV39 on a second, very minimal page table .8byte 0x8FFFF, 0x11, goto_sv39 # go to SV39 on a second, very minimal page table
.8byte 0x200AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping .8byte 0x200AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping. // ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv39 // go back to old, extensive page table .8byte 0x8000D, 0x0, goto_sv39 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV39-SVADU
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -52,9 +52,9 @@ test_cases:
# #
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv39 page table (See Figure 12.12***): # sv39 page table (See Figure 12.12***):
# Level 2 page table, situated at 0x8000D000 # Level 2 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A .8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A
@ -82,6 +82,27 @@ test_cases:
.8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault .8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault
.8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault .8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault
.8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page .8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page
.8byte 0x0000000080018038, 0x01000000200800DF, write64_test# Vaddr 0x7000, Paddr = 0x80200000, bad reserved bit
.8byte 0x0000000080018040, 0x20000000200800DF, write64_test# Vaddr 0x8000, Paddr = 0x80200000, PBMT = 1
.8byte 0x0000000080018048, 0x40000000200800DF, write64_test# Vaddr 0x9000, Paddr = 0x80200000, PMBT = 2
.8byte 0x0000000080018050, 0x60000000200800DF, write64_test# Vaddr 0xA000, Paddr = 0x80200000, PMBT = 3
.8byte 0x0000000080018080, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x0000000080018088, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x0000000080018090, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x0000000080018098, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180A0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180A8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180B0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180B8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180C0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180C8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180D0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180D8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180E0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180E8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180F0, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
.8byte 0x00000000800180F8, 0x80000000200800DF, write64_test# Vaddr 0x10000, Paddr = 0x80200000, NAPOT
# Level 0 page table B # Level 0 page table B
.8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage .8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage
@ -89,19 +110,21 @@ test_cases:
.8byte 0x8FFFF000, 0x200000CF, write64_test# Vaddr 0x0, Paddr 0x80000000 aligned gigapage .8byte 0x8FFFF000, 0x200000CF, write64_test# Vaddr 0x0, Paddr 0x80000000 aligned gigapage
.8byte 0x8FFFF010, 0x200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory so we can execute without jumping around) .8byte 0x8FFFF010, 0x200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory so we can execute without jumping around)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test# 8.3.1.1.4 and 8.3.1.4.1 .8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test # 11.3.1.1.4 and 11.3.1.4.1
.8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test# 8.3.1.1.4 .8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test # 11.3.1.1.4
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test# 8.3.1.3.2 .8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 11.3.1.3.2
.8byte 0x80203130, 0x0110DEADBEEF0077, write64_test# 8.3.1.3.2 .8byte 0x80203130, 0x0110DEADBEEF0077, write64_test # 11.3.1.3.2
.8byte 0x80099000, 0x0000806711100393, write64_test# 8.3.1.3.1 and 8.3.1.3.2 write executable code for "li x7, 0x111; ret" .8byte 0x80099000, 0x0000806711100393, write64_test # 11.3.1.3.1 and 11.3.1.3.2 write executable code for "li x7, 0x111; ret"
.8byte 0x80205AA0, 0x0000806711100393, write64_test# 8.3.1.3.5 write same executable code .8byte 0x80205AA0, 0x0000806711100393, write64_test # 11.3.1.3.5 write same executable code
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test# 8.3.1.1.4 .8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 11.3.1.1.4
.8byte 0x84212348, 0x0330DEADBEEF0440, write64_test# 8.3.1.3.3 .8byte 0x84212348, 0x0330DEADBEEF0440, write64_test # 11.3.1.3.3
.8byte 0x8020A400, 0x0550DEADBEEF0660, write64_test # 11.3.1.3.9
.8byte 0x80205000, 0x0770DEADBEEF0880, write64_test # 11.3.1.2.2 junk in memory location corresponding to invalid page
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation. .8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test .8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test
@ -111,42 +134,42 @@ test_cases:
.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test .8byte 0x80201888, 0x0220DEADBEEF0099, read64_test
.8byte 0x84212348, 0x0330DEADBEEF0440, read64_test .8byte 0x84212348, 0x0330DEADBEEF0440, read64_test
# test 8.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv39 # satp.MODE = sv39, with base page table PPN = 0x8000D and ASID = 0. current VPN: gigapage at 0x80000000. .8byte 0x8000D, 0x0, goto_sv39 # satp.MODE = sv39, with base page table PPN = 0x8000D and ASID = 0. current VPN: gigapage at 0x80000000.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000 .8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000 .8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 load page fault if upper bits of Vaddr are not the same
.8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits .8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits .8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero # test 11.3.1.2.2 load page fault when reading an address where the valid flag is zero
.8byte 0x6000, 0x0, read64_test .8byte 0x6000, 0x0, read64_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set # test 11.3.1.2.3 store page fault if PTE has W and ~R flags set
.8byte 0x2000, 0x0, write64_test .8byte 0x2000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x0020, 0x0, read64_test .8byte 0x0020, 0x0, read64_test
# test 8.3.1.2.5 load page fault on misaligned pages # test 11.3.1.2.5 load page fault on misaligned pages
.8byte 0xC0000000, 0x0, read64_test# misaligned gigapage .8byte 0xC0000000, 0x0, read64_test# misaligned gigapage
.8byte 0x40200000, 0x0, read64_test# misaligned megapage .8byte 0x40200000, 0x0, read64_test# misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4 # *** reads on pages with U=0 already tested in 11.3.1.1.4
.8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S .8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output .8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U .8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U
.8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U .8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U .8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output .8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -155,60 +178,77 @@ test_cases:
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0 .8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4 # *** reads on pages with R=1 already tested in 11.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0 .8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 .8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1 .8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address .8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address
.8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0 .8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1 # *** fetches on pages with X = 1 already tested in 11.3.1.3.1
.8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0 .8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits # In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0 # Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.8byte 0x36D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled .8byte 0x36D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled
.8byte 0x36D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled .8byte 0x36D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled .8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled
.8byte 0x4658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0 .8byte 0x4658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # test 11.3.1.3.8 Reserved bits nonzero
.8byte 0x7AA0, 0x123456789ABCDEF, read64_test # load page fault because reserved is nonzero
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # test 11.3.1.3.9 NAPOT read
.8byte 0x1A400, 0x0550DEADBEEF0660, read64_test # read from NAPOT 64 KiB page
# test 11.3.1.3.10 PBMT checks
.8byte 0x8040, 0x1212343456567878, write64_test # Write fault with PBMT when menvcfg.PBMTE = 0
.8byte 0x0, 0x0, goto_m_mode # change to M mode, 0x9 written to output
.8byte 0x0, 0x4000000000000000, write_menvcfg # set menvcfg.PBMTE = 1
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x8040, 0x1212343456567878, write64_test # Write success with PBMT = 1
.8byte 0x8040, 0x1212343456567878, read64_test # Read back success with PBMT = 1
.8byte 0x9050, 0x2312343456567878, write64_test # Write success with PBMT = 2
.8byte 0x9050, 0x2312343456567878, read64_test # Read back success with PBMT = 2
.8byte 0xA060, 0x3412343456567878, write64_test # Write faults with PBMT = 3
# =========== test 11.3.1.4 SATP Register ===========
# test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB // *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8FFFF, 0x11, goto_sv39 # go to SV39 on a second, very minimal page table .8byte 0x8FFFF, 0x11, goto_sv39 # go to SV39 on a second, very minimal page table
.8byte 0x200AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping .8byte 0x200AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping. // ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv39 // go back to old, extensive page table .8byte 0x8000D, 0x0, goto_sv39 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV48
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -54,9 +54,9 @@ test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv48 page table (See Figure 12.12***): # sv48 page table (See Figure 12.12***):
# Level 3 page table, situated at 0x8000D000 # Level 3 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A .8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A
@ -101,22 +101,22 @@ test_cases:
.8byte 0x8002F010, 0x200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned gigapage (data and instr memory) .8byte 0x8002F010, 0x200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned gigapage (data and instr memory)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 8.3.1.1.4 terapage .8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 11.3.1.1.4 terapage
.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 8.3.1.1.4 gigapage .8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 11.3.1.1.4 gigapage
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 8.3.1.1.4 megapage .8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 11.3.1.1.4 megapage
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 8.3.1.1.4 kilopage .8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 11.3.1.1.4 kilopage
.8byte 0x80099000, 0x0000806711100393, write64_test # 8.3.1.3.1 write executable code for "li x7, 0x111; ret" .8byte 0x80099000, 0x0000806711100393, write64_test # 11.3.1.3.1 write executable code for "li x7, 0x111; ret"
.8byte 0x80200400, 0x0000806711100393, write64_test # 8.3.1.3.2 write same executable code .8byte 0x80200400, 0x0000806711100393, write64_test # 11.3.1.3.2 write same executable code
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 8.3.1.3.2 .8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 11.3.1.3.2
.8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 8.3.1.3.2 .8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 11.3.1.3.2
.8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 8.3.1.3.3 .8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 11.3.1.3.3
.8byte 0x88888000, 0x0000806711100393, write64_test # 8.3.1.3.5 write same executable code .8byte 0x88888000, 0x0000806711100393, write64_test # 11.3.1.3.5 write same executable code
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test # 8.3.1.3.7 .8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test # 11.3.1.3.7
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. .8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test .8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test
@ -128,43 +128,43 @@ test_cases:
.8byte 0x85212348, 0x0330DEADBEEF0440, read64_test .8byte 0x85212348, 0x0330DEADBEEF0440, read64_test
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test .8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv48 # satp.MODE = sv48, with base page table PPN = 0x8000D and ASID = 0. current VPN: megapage at 0x80000000. Nothing written to output .8byte 0x8000D, 0x0, goto_sv48 # satp.MODE = sv48, with base page table PPN = 0x8000D and ASID = 0. current VPN: megapage at 0x80000000. Nothing written to output
.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0 .8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0
.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000 .8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000 .8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 page fault if upper bits of Vaddr are not the same
.8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits .8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits .8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 read fault when reading an address where the valid flag is zero # test 11.3.1.2.2 read fault when reading an address where the valid flag is zero
.8byte 0x80205000, 0x0, read64_test .8byte 0x80205000, 0x0, read64_test
# test 8.3.1.2.3 write fault if PTE has W and ~R flags set # test 11.3.1.2.3 write fault if PTE has W and ~R flags set
.8byte 0x80202000, 0x0, write64_test .8byte 0x80202000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x80200000, 0x0, read64_test .8byte 0x80200000, 0x0, read64_test
# test 8.3.1.2.5 read fault on misaligned pages # test 11.3.1.2.5 read fault on misaligned pages
.8byte 0x18000000000, 0x0, read64_test # misaligned terapage .8byte 0x18000000000, 0x0, read64_test # misaligned terapage
.8byte 0x8080000000, 0x0, read64_test # misaligned gigapage .8byte 0x8080000000, 0x0, read64_test # misaligned gigapage
.8byte 0x80400000, 0x0, read64_test # misaligned megapage .8byte 0x80400000, 0x0, read64_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# reads on pages with U=0 already tested in 8.3.1.1.4 # reads on pages with U=0 already tested in 11.3.1.1.4
.8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S .8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output .8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U .8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U
.8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U .8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U .8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x2, goto_s_mode .8byte 0x80000000, 0x2, goto_s_mode
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -173,61 +173,61 @@ test_cases:
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0 .8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# reads on pages with R=1 already tested in 8.3.1.1.4 # reads on pages with R=1 already tested in 11.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0 .8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 .8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8) .8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8)
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back .8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back
.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0 .8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# executes on pages with X = 1 already tested in 8.3.1.3.1 # executes on pages with X = 1 already tested in 11.3.1.3.1
.8byte 0x010088888000, 0x2, executable_test # execute fault when X=0 .8byte 0x010088888000, 0x2, executable_test # execute fault when X=0
# In the following two tests, SVADU is not supported, so the software handles the A/D bits # In the following two tests, SVADU is not supported, so the software handles the A/D bits
# Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits # Since SVADU is 0, Accesses to A/D=0 causes a fault for the trap handler to fix those bits
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # write fault when A=0 .8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # write fault when A=0
.8byte 0x80203AB8, 0x0990DEADBEEF0990, read64_test# read fault when A=0 .8byte 0x80203AB8, 0x0990DEADBEEF0990, read64_test# read fault when A=0
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # write fault when D=0 .8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # write fault when D=0
.8byte 0x80204AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0 .8byte 0x80204AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # =========== test 11.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB // *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8000F, 0x11, goto_sv48 # go to SV39 on a second, very minimal page table .8byte 0x8000F, 0x11, goto_sv48 # go to SV39 on a second, very minimal page table
.8byte 0x5BC0AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping .8byte 0x5BC0AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping. // ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv48 // go back to old, extensive page table .8byte 0x8000D, 0x0, goto_sv48 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// //
// WALLY-MMU // WALLY-MMU-SV48-SVADU
// //
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
@ -54,9 +54,9 @@ test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation =========== # =========== test 11.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory # test 11.3.1.1.1 write page tables / entries to phyiscal memory
# sv48 page table (See Figure 12.12***): # sv48 page table (See Figure 12.12***):
# Level 3 page table, situated at 0x8000D000 # Level 3 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A .8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A
@ -101,21 +101,21 @@ test_cases:
.8byte 0x8002F010, 0x200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned gigapage (data and instr memory) .8byte 0x8002F010, 0x200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned gigapage (data and instr memory)
# test 8.3.1.1.2 write values to Paddrs in each page # test 11.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments. # each of these values is used for 11.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 8.3.1.1.4 terapage .8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 11.3.1.1.4 terapage
.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 8.3.1.1.4 gigapage .8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 11.3.1.1.4 gigapage
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 8.3.1.1.4 megapage .8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 11.3.1.1.4 megapage
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 8.3.1.1.4 kilopage .8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 11.3.1.1.4 kilopage
.8byte 0x80099000, 0x0000806711100393, write64_test # 8.3.1.3.1 write executable code for "li x7, 0x111; ret" .8byte 0x80099000, 0x0000806711100393, write64_test # 11.3.1.3.1 write executable code for "li x7, 0x111; ret"
.8byte 0x80200400, 0x0000806711100393, write64_test # 8.3.1.3.2 write same executable code .8byte 0x80200400, 0x0000806711100393, write64_test # 11.3.1.3.2 write same executable code
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 8.3.1.3.2 .8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 11.3.1.3.2
.8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 8.3.1.3.2 .8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 11.3.1.3.2
.8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 8.3.1.3.3 .8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 11.3.1.3.3
.8byte 0x88888000, 0x0000806711100393, write64_test # 8.3.1.3.5 write same executable code .8byte 0x88888000, 0x0000806711100393, write64_test # 11.3.1.3.5 write same executable code
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) # test 11.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. .8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output .8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test .8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test
@ -126,43 +126,43 @@ test_cases:
.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test .8byte 0x80201888, 0x0220DEADBEEF0099, read64_test
.8byte 0x85212348, 0x0330DEADBEEF0440, read64_test .8byte 0x85212348, 0x0330DEADBEEF0440, read64_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs # test 11.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv48 # satp.MODE = sv48, with base page table PPN = 0x8000D and ASID = 0. current VPN: megapage at 0x80000000. Nothing written to output .8byte 0x8000D, 0x0, goto_sv48 # satp.MODE = sv48, with base page table PPN = 0x8000D and ASID = 0. current VPN: megapage at 0x80000000. Nothing written to output
.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0 .8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0
.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000 .8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000 .8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests =========== # =========== test 11.3.1.2 page fault tests ===========
# test 8.3.1.2.1 page fault if upper bits of Vaddr are not the same # test 11.3.1.2.1 page fault if upper bits of Vaddr are not the same
.8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits .8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits .8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 read fault when reading an address where the valid flag is zero # test 11.3.1.2.2 read fault when reading an address where the valid flag is zero
.8byte 0x80205000, 0x0, read64_test .8byte 0x80205000, 0x0, read64_test
# test 8.3.1.2.3 write fault if PTE has W and ~R flags set # test 11.3.1.2.3 write fault if PTE has W and ~R flags set
.8byte 0x80202000, 0x0, write64_test .8byte 0x80202000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer # test 11.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x80200000, 0x0, read64_test .8byte 0x80200000, 0x0, read64_test
# test 8.3.1.2.5 read fault on misaligned pages # test 11.3.1.2.5 read fault on misaligned pages
.8byte 0x18000000000, 0x0, read64_test # misaligned terapage .8byte 0x18000000000, 0x0, read64_test # misaligned terapage
.8byte 0x8080000000, 0x0, read64_test # misaligned gigapage .8byte 0x8080000000, 0x0, read64_test # misaligned gigapage
.8byte 0x80400000, 0x0, read64_test # misaligned megapage .8byte 0x80400000, 0x0, read64_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags =========== # =========== test 11.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0 # test 11.3.1.3.1 User flag == 0
# reads on pages with U=0 already tested in 8.3.1.1.4 # reads on pages with U=0 already tested in 11.3.1.1.4
.8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S .8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output .8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U .8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U
.8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U .8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1 # test 11.3.1.3.2 User flag == 1
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U .8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x2, goto_s_mode .8byte 0x80000000, 0x2, goto_s_mode
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
@ -171,61 +171,61 @@ test_cases:
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. .8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0 .8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag # test 11.3.1.3.3 Read flag
# reads on pages with R=1 already tested in 8.3.1.1.4 # reads on pages with R=1 already tested in 11.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. .8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0 .8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. .8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 .8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag # test 11.3.1.3.4 Write flag
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8) .8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8)
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back .8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back
.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0 .8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0
# test 8.3.1.3.5 eXecute flag # test 11.3.1.3.5 eXecute flag
# executes on pages with X = 1 already tested in 8.3.1.3.1 # executes on pages with X = 1 already tested in 11.3.1.3.1
.8byte 0x010088888000, 0x2, executable_test # execute fault when X=0 .8byte 0x010088888000, 0x2, executable_test # execute fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits # In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0 # Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0 # test 11.3.1.3.6 Accessed flag == 0
.8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled .8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled
.8byte 0x802036D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled .8byte 0x802036D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0 # test 11.3.1.3.7 Dirty flag == 0
.8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled .8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled
.8byte 0x80204658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0 .8byte 0x80204658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0
# =========== test 8.3.1.4 SATP Register =========== # =========== test 11.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID) # test 11.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB // *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8000F, 0x11, goto_sv48 # go to SV39 on a second, very minimal page table .8byte 0x8000F, 0x11, goto_sv48 # go to SV39 on a second, very minimal page table
.8byte 0x5BC0AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping .8byte 0x5BC0AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping # test 11.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping. // ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers =========== # =========== test 11.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation # test 11.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this. # *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv48 // go back to old, extensive page table .8byte 0x8000D, 0x0, goto_sv48 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus .8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S .8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1 .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing # test 11.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret # mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to .8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus. .8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero. .8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read # test 11.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3 # this bitfield already tested in 11.3.1.3.3
# terminate tests # terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. .8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.