From 52c5e515b75b85d53d400087125e507f07a80c83 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 6 May 2025 19:24:05 -0500 Subject: [PATCH] Second fix for the zsh bug. Fixes issue #1263. A misaligned load or store page fault generates two virtual memory address translations. If the second page faults, xtval should be updated with the address of the second part of the instruction not the first part. --- src/lsu/lsu.sv | 4 +++- src/privileged/csr.sv | 4 ++-- src/privileged/privileged.sv | 4 ++-- src/wally/wallypipelinedcore.sv | 4 +++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index f6a215a27..2d6e14166 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -57,6 +57,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( input logic BigEndianM, // Swap byte order to big endian input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries output logic DCacheStallM, // D$ busy with multicycle operation + output logic [P.XLEN-1:0] IEUAdrSpillM, // IEUAdrM, but could be spilled onto the next cacheline or virtual page. // fpu input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU input logic FpLoadStoreM, // Selects FPU as store for write data @@ -158,7 +159,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); if(MISALIGN_SUPPORT) begin : ziccslm_align - logic [P.XLEN-1:0] IEUAdrSpillE, IEUAdrSpillM; + logic [P.XLEN-1:0] IEUAdrSpillE; align #(P) align(.clk, .reset, .StallM, .FlushM, .IEUAdrE, .IEUAdrM, .Funct3M, .FpLoadStoreM, .MemRWM, .DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW, @@ -175,6 +176,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( assign LSUWriteDataSpillM = LSUWriteDataM; assign MemRWSpillM = MemRWM; assign {SpillStallM} = 1'b0; + assign IEUAdrSpillM = IEUAdrM; end if(P.ZICBOZ_SUPPORTED) begin : cboz diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index ad3dab32d..f21241f0a 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -36,7 +36,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic [31:0] InstrM, // current instruction input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [P.XLEN-1:0] PCM, // program counter, next PC going to trap/return logic - input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU + input logic [P.XLEN-1:0] SrcAM, IEUAdrSpillM, // SrcA and memory address from IEU input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring input logic mretM, sretM, // return instruction @@ -142,7 +142,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( else case (CauseM) 12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint 2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault - 0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults + 0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrSpillM; // Instruction misaligned, Load/Store Misaligned/page/access faults default: NextFaultMtvalM = '0; // Ecall, interrupts endcase diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 197ab23be..ba7aeb960 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -37,7 +37,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( input logic [P.XLEN-1:0] SrcAM, // GPR register to write input logic [31:0] InstrM, // Instruction input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL - input logic [P.XLEN-1:0] IEUAdrM, // address from IEU + input logic [P.XLEN-1:0] IEUAdrSpillM, // address from IEU input logic [P.XLEN-1:0] PCM, // program counter // control signals input logic InstrValidM, // Current instruction is valid (not flushed) @@ -133,7 +133,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, - .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, + .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrSpillM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index b5a80a24b..2c07d190c 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -130,6 +130,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] IEUAdrE; logic [P.XLEN-1:0] WriteDataM; logic [P.XLEN-1:0] IEUAdrM; + logic [P.XLEN-1:0] IEUAdrSpillM; logic [P.LLEN-1:0] ReadDataW; logic CommittedM; @@ -242,6 +243,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .ENVCFG_ADUE, // from csr .sfencevmaM, // connects to privilege .DCacheStallM, // connects to privilege + .IEUAdrSpillM, // connects to privilege .LoadPageFaultM, // connects to privilege .StoreAmoPageFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege @@ -299,7 +301,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .InstrMisalignedFaultM, .IllegalIEUFPUInstrD, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, - .MTIME_CLINT, .IEUAdrM, .SetFflagsM, + .MTIME_CLINT, .IEUAdrSpillM, .SetFflagsM, .InstrAccessFaultF, .HPTWInstrAccessFaultF, .HPTWInstrPageFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,