Modified the pmachecker to correctly check the permissions for cmo instructions.

However this isn't fully tested.
This commit is contained in:
Rose Thompson 2023-11-27 17:44:11 -06:00
parent 337903d8dd
commit beb95dd592
6 changed files with 25 additions and 17 deletions

View File

@ -182,7 +182,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.UpdateDA(InstrUpdateDAF), .UpdateDA(InstrUpdateDAF), .CMOp(4'b0),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0), .AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);

View File

@ -228,7 +228,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic DisableTranslation; // During HPTW walk or D$ flush disable virtual memory address translation logic DisableTranslation; // During HPTW walk or D$ flush disable virtual memory address translation
logic WriteAccessM; logic WriteAccessM;
assign DisableTranslation = SelHPTW | FlushDCacheM; assign DisableTranslation = SelHPTW | FlushDCacheM;
assign WriteAccessM = PreLSURWM[0] | (|CMOpM); assign WriteAccessM = PreLSURWM[0];
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, .ENVCFG_PBMTE, .ENVCFG_HADE, dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
.PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]), .PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
@ -238,7 +238,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM, .StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
.StoreAmoPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw. .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
.UpdateDA(DataUpdateDAM), .UpdateDA(DataUpdateDAM), .CMOp(CMOpM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
.WriteAccessM, .ReadAccessM(PreLSURWM[1]), .WriteAccessM, .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -302,7 +302,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic CacheStall; logic CacheStall;
logic [1:0] CacheBusRWTemp; logic [1:0] CacheBusRWTemp;
if(P.ZICBOZ_SUPPORTED) begin
assign BusRW = ~CacheableM & ~SelDTIM ? CMOpM[3] ? 2'b01 : LSURWM : '0;
end else begin
assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0; assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0;
end
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
assign CacheRWM = CacheableM & ~SelDTIM ? LSURWM : '0; assign CacheRWM = CacheableM & ~SelDTIM ? LSURWM : '0;
assign FlushDCache = FlushDCacheM & ~(SelHPTW); assign FlushDCache = FlushDCacheM & ~(SelHPTW);

View File

@ -30,18 +30,18 @@
module adrdecs import cvw::*; #(parameter cvw_t P) ( module adrdecs import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX, input logic AccessRW, AccessRX, AccessRWXZ, AccessRWZ, AccessRXZ,
input logic [1:0] Size, input logic [1:0] Size,
output logic [11:0] SelRegions output logic [11:0] SelRegions
); );
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111); localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[11]); adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRWZ, Size, SUPPORTED_SIZE, SelRegions[11]);
adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[10]); adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRXZ, Size, SUPPORTED_SIZE, SelRegions[10]);
adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[9]); adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWXZ, Size, SUPPORTED_SIZE, SelRegions[9]);
adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]); adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRXZ, Size, SUPPORTED_SIZE, SelRegions[8]);
adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]); adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWXZ, Size, SUPPORTED_SIZE, SelRegions[7]);
adrdec #(P.PA_BITS) clintdec(PhysicalAddress, P.CLINT_BASE[P.PA_BITS-1:0], P.CLINT_RANGE[P.PA_BITS-1:0], P.CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]); adrdec #(P.PA_BITS) clintdec(PhysicalAddress, P.CLINT_BASE[P.PA_BITS-1:0], P.CLINT_RANGE[P.PA_BITS-1:0], P.CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]);
adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]); adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]);
adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]); adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]);

View File

@ -55,6 +55,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
output logic UpdateDA, // page fault due to setting dirty or access bit output logic UpdateDA, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals // PMA checker signals
input logic [3:0] CMOp, // Cache management instructions
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses
@ -106,7 +107,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
// Check physical memory accesses // Check physical memory accesses
/////////////////////////////////////////// ///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOp,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);

View File

@ -31,6 +31,7 @@
module pmachecker import cvw::*; #(parameter cvw_t P) ( module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size, input logic [1:0] Size,
input logic [3:0] CMOp,
input logic AtomicAccessM, // Atomic access input logic AtomicAccessM, // Atomic access
input logic ExecuteAccessF, // Execute access input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access input logic WriteAccessM, // Write access
@ -43,18 +44,20 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
); );
logic PMAAccessFault; logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWXZ, AccessRX, AccessRWZ, AccessRXZ;
logic [11:0] SelRegions; logic [11:0] SelRegions;
logic AtomicAllowed; logic AtomicAllowed;
logic CacheableRegion, IdempotentRegion; 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;
assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF; assign AccessRWZ = AccessRW | (P.ZICBOM_SUPPORTED & (|CMOp[2:0]));
assign AccessRWXZ = ReadAccessM | WriteAccessM | ExecuteAccessF | (P.ZICBOM_SUPPORTED & (|CMOp[2:0])) | (P.ZICBOZ_SUPPORTED & (CMOp[3]));
assign AccessRX = ReadAccessM | ExecuteAccessF; assign AccessRX = ReadAccessM | ExecuteAccessF;
assign AccessRXZ = AccessRX | (P.ZICBOM_SUPPORTED & (|CMOp[2:0]));
// 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, AccessRWXZ, AccessRWZ, AccessRXZ, Size, SelRegions);
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
assign CacheableRegion = SelRegions[9] | SelRegions[8] | SelRegions[7]; // exclusion-tag: unused-cachable assign CacheableRegion = SelRegions[9] | SelRegions[8] | SelRegions[7]; // exclusion-tag: unused-cachable
@ -71,7 +74,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
assign SelTIM = SelRegions[11] | SelRegions[10]; // exclusion-tag: unused-idempotent assign SelTIM = SelRegions[11] | SelRegions[10]; // exclusion-tag: unused-idempotent
// Detect access faults // Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWX | AtomicAccessM & ~AtomicAllowed; assign PMAAccessFault = (SelRegions[0]) & AccessRWXZ | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault; assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault;

View File

@ -88,7 +88,7 @@ module uncore 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
// Use a trimmed down portion of the PMA checker - only the address decoders // Use a trimmed down portion of the PMA checker - only the address decoders
// Set access types to all 1 as don't cares because the MMU has already done access checking // Set access types to all 1 as don't cares because the MMU has already done access checking
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions); adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
// unswizzle HSEL signals // unswizzle HSEL signals
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1]; assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1];