diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index c304219aa..05d5f2e00 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -211,7 +211,8 @@ module fpu import cvw::*; #(parameter cvw_t P) ( {{P.FLEN-P.D_LEN{1'b1}}, 2'b0, {P.D_NE-1{1'b1}}, (P.D_NF)'(0)}, {{P.FLEN-P.H_LEN{1'b1}}, 2'b0, {P.H_NE-1{1'b1}}, (P.H_NF)'(0)}, {2'b0, {P.NE-1{1'b1}}, (P.NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes - assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10); + assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(PostProcSelE==2'b10); + // ***simplified from appearently redundant assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10); mux2 #(P.FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract // Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z @@ -352,7 +353,8 @@ module fpu import cvw::*; #(parameter cvw_t P) ( .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); // FPU flag selection - to privileged - mux2 #(5) FPUFlgMux({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); + //mux2 #(5) FPUFlgMux({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); + mux2 #(5) FPUFlgMux({PreNVM, 4'b0}, PostProcFlgM, (FResSelM == 2'b01), SetFflagsM); mux2 #(P.FLEN) FPUResMux(PreFpResM, PostProcResM, FResSelM[0], FpResM); // M/W pipe registers diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index dffa7be76..6957ed315 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -74,6 +74,8 @@ module mmu import cvw::*; #(parameter cvw_t P, logic TLBPageFault; // Page fault from TLB 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 + logic AmoMisalignedCausesAccessFaultM; // Misaligned AMO is not handled by hardware even with ZICCLSM, so it throws an access fault instead of misaligned with ZICCLSM + logic AmoAccessM; // AMO access detected when ReadAccessM and WriteAccessM are simultaneously asserted // only instantiate TLB if Virtual Memory is supported if (P.VIRTMEM_SUPPORTED) begin:tlb @@ -123,24 +125,30 @@ module mmu import cvw::*; #(parameter cvw_t P, assign PMPLoadAccessFaultM = 0; end - assign ReadNoAmoAccessM = ReadAccessM & ~WriteAccessM;// AMO causes StoreAmo rather than Load fault - - // Access faults - // If TLB miss and translating we want to not have faults from the PMA and PMP checkers. - assign InstrAccessFaultF = (PMAInstrAccessFaultF | PMPInstrAccessFaultF) & ~TLBMiss; - assign LoadAccessFaultM = (PMALoadAccessFaultM | PMPLoadAccessFaultM) & ~TLBMiss; - assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM) & ~TLBMiss; + assign ReadNoAmoAccessM = ReadAccessM & ~WriteAccessM;// AMO causes StoreAmo rather than Load fault + assign AmoAccessM = ReadAccessM & WriteAccessM; // Misaligned faults - always_comb // exclusion-tag: immu-wordaccess + always_comb // exclusion-tag: immu-wordaccess case(Size[1:0]) 2'b00: DataMisalignedM = 0; // lb, sb, lbu 2'b01: DataMisalignedM = VAdr[0]; // lh, sh, lhu 2'b10: DataMisalignedM = VAdr[1] | VAdr[0]; // lw, sw, flw, fsw, lwu 2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd endcase + // When ZiCCLSM_SUPPORTED, misalgined cachable loads and stores are handled in hardware so they do not throw a misaligned fault assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable); - assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & (~(P.ZICCLSM_SUPPORTED & Cacheable) | ReadAccessM); // Misaligned AMO faults even if ZICCLSM supported + assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable); // Store and AMO both assert WriteAccess + + // Access faults + // If TLB miss and translating we want to not have faults from the PMA and PMP checkers. + assign InstrAccessFaultF = (PMAInstrAccessFaultF | PMPInstrAccessFaultF) & ~TLBMiss; + assign LoadAccessFaultM = (PMALoadAccessFaultM | PMPLoadAccessFaultM) & ~TLBMiss; + // a misaligned AMO causes an access fault rather than a misaligned fault if a misaligned load/store is handled in hardware + // this is subtle - see privileged spec 3.6.3.3 + // AMO is detected as ReadAccess & WriteAccess + assign AmoMisalignedCausesAccessFaultM = DataMisalignedM & AmoAccessM & (P.ZICCLSM_SUPPORTED & Cacheable); + assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM | AmoMisalignedCausesAccessFaultM) & ~TLBMiss; // Specify which type of page fault is occurring assign InstrPageFaultF = TLBPageFault & ExecuteAccessF; diff --git a/tests/coverage/tlbmisc.S b/tests/coverage/tlbmisc.S index db1435008..d62a4f2d6 100644 --- a/tests/coverage/tlbmisc.S +++ b/tests/coverage/tlbmisc.S @@ -95,7 +95,7 @@ main: sw t1, 0(t0) # write to page jalr ra, t0 # jump to page - # Nonleaf PTE has PBMT != 0 # this should cause a page fault during page walking. However, as of issue 546 1/1/24, both ImperasDV and Wally don't detect this + # Nonleaf PTE has PBMT != 0 causes a page fault during page walking. H li t0, 0x80600000 lw t1, 0(t0) # read from page sw t1, 0(t0) # write to page @@ -104,14 +104,21 @@ main: # jump to address for TLB miss to trigger HPTW to make access with DisableTranslation = 1, Translate = 0 li t0, 0x80805000 jalr ra, t0 + li t0, 0x80807000 # again, triggering setting access bit + jalr ra, t0 + + # atomic access to uncachable memory + #li t0, 0x80806000 + #sd zero, 0(t0) + #amoadd.w t1, t0, (t0) # Good PBMT with menvcfg.PBMTE = 0 - li t0, 3 + li a0, 3 ecall # switch to machine mode li t5, 0x1 slli t5, t5, 62 csrc menvcfg, t5 # menvcfg.PBMTE = 0 - li t0, 1 + li a0, 1 ecall # switch back to supervisor mode li t0, 0x80806000 jalr ra, t0 # jump to page to exercise ITLB with PBMT !=0 when ENVCFG_PMTE=0 @@ -365,6 +372,7 @@ pagetable: .8byte 0x00000000200000C3 # valid r for VA 80802000 .8byte 0x00000000200000C9 # valid x for VA 80803000 .8byte 0x00000000200000CD # valid wx for VA 80804000 (illegal combination, but used to test tlbcontrol) - .8byte 0x000000002000000F # valid rwx for VA 80805000 for covering ITLB translate and UpdateDA + .8byte 0x00000000200000CF # valid rwx for VA 80805000 for covering ITLB translate .8byte 0x20000000200000CF # PBMT=1 for VA 80806000 for covering ITLB BadPBMT + .8byte 0x000000002000000F # valid rwx for VA 80807000 for covering UpdateDA