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.

This commit is contained in:
Rose Thompson 2025-05-06 19:24:05 -05:00
parent 69889cb31f
commit 52c5e515b7
4 changed files with 10 additions and 6 deletions

View file

@ -57,6 +57,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
input logic BigEndianM, // Swap byte order to big endian input logic BigEndianM, // Swap byte order to big endian
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic DCacheStallM, // D$ busy with multicycle operation 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 // fpu
input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU
input logic FpLoadStoreM, // Selects FPU as store for write data 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); flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
if(MISALIGN_SUPPORT) begin : ziccslm_align 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, align #(P) align(.clk, .reset, .StallM, .FlushM, .IEUAdrE, .IEUAdrM, .Funct3M, .FpLoadStoreM,
.MemRWM, .MemRWM,
.DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW, .DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW,
@ -175,6 +176,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
assign LSUWriteDataSpillM = LSUWriteDataM; assign LSUWriteDataSpillM = LSUWriteDataM;
assign MemRWSpillM = MemRWM; assign MemRWSpillM = MemRWM;
assign {SpillStallM} = 1'b0; assign {SpillStallM} = 1'b0;
assign IEUAdrSpillM = IEUAdrM;
end end
if(P.ZICBOZ_SUPPORTED) begin : cboz if(P.ZICBOZ_SUPPORTED) begin : cboz

View file

@ -36,7 +36,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
input logic [31:0] InstrM, // current instruction 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 [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] 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 CSRReadM, CSRWriteM, // read or write CSR
input logic TrapM, // trap is occurring input logic TrapM, // trap is occurring
input logic mretM, sretM, // return instruction input logic mretM, sretM, // return instruction
@ -142,7 +142,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
else case (CauseM) else case (CauseM)
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint 12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault 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 default: NextFaultMtvalM = '0; // Ecall, interrupts
endcase endcase

View file

@ -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 [P.XLEN-1:0] SrcAM, // GPR register to write
input logic [31:0] InstrM, // Instruction 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 [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 input logic [P.XLEN-1:0] PCM, // program counter
// control signals // control signals
input logic InstrValidM, // Current instruction is valid (not flushed) 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 // Control and Status Registers
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, 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, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,

View file

@ -130,6 +130,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] IEUAdrE; logic [P.XLEN-1:0] IEUAdrE;
logic [P.XLEN-1:0] WriteDataM; logic [P.XLEN-1:0] WriteDataM;
logic [P.XLEN-1:0] IEUAdrM; logic [P.XLEN-1:0] IEUAdrM;
logic [P.XLEN-1:0] IEUAdrSpillM;
logic [P.LLEN-1:0] ReadDataW; logic [P.LLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
@ -242,6 +243,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.ENVCFG_ADUE, // from csr .ENVCFG_ADUE, // from csr
.sfencevmaM, // connects to privilege .sfencevmaM, // connects to privilege
.DCacheStallM, // connects to privilege .DCacheStallM, // connects to privilege
.IEUAdrSpillM, // connects to privilege
.LoadPageFaultM, // connects to privilege .LoadPageFaultM, // connects to privilege
.StoreAmoPageFaultM, // connects to privilege .StoreAmoPageFaultM, // connects to privilege
.LoadMisalignedFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege
@ -299,7 +301,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.InstrMisalignedFaultM, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, .IllegalIEUFPUInstrD,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .IEUAdrM, .SetFflagsM, .MTIME_CLINT, .IEUAdrSpillM, .SetFflagsM,
.InstrAccessFaultF, .HPTWInstrAccessFaultF, .HPTWInstrPageFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, .InstrAccessFaultF, .HPTWInstrAccessFaultF, .HPTWInstrPageFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
.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,