From 6eaf22ea95c55d93ad9f594a8bd13c0987233653 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 17 Jan 2026 22:47:14 +1100 Subject: [PATCH] dcache: Fix stalls that occurred occasionally with dcbt followed by ld This fixes a race condition that causes a hang in a situation where the program does a dcbt to a cache line, then hits a TLB miss causing some requests to come in to the dcache from the MMU while the cache line requested by the dcbt has not yet started to come in, then does a load to an address in the same cache line requested by the dcbt. If it happens that the data for the load arrives in the same cycle that the load is doing the cache tag and TLB lookups, the dcache_slow process correctly recognizes that the request can be satisfied immediately but incorrectly sends the done signal to the MMU rather than loadstore1, because the logic looks at r1.mmu_req not req.mmu_req. Fix it to use req.mmu_req. Also make sure that RELOAD_WAIT_ACK state only completes a touch that was the one that caused entry to RELOAD_WAIT_ACK state, not a subsequent touch, which will have r1.req.hit_reload = 0. (A touch to the same line that is already being reloaded would be treated as a hit.) Signed-off-by: Paul Mackerras --- dcache.vhdl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dcache.vhdl b/dcache.vhdl index 58c464b..0d8d354 100644 --- a/dcache.vhdl +++ b/dcache.vhdl @@ -1704,7 +1704,7 @@ begin end if; -- If this is a touch, complete the instruction - if r1.full = '1' and r1.req.touch = '1' then + if r1.full = '1' and r1.req.touch = '1' and r1.req.hit_reload = '1' then r1.full <= '0'; r1.slow_valid <= '1'; r1.ls_valid <= '1'; @@ -1730,7 +1730,7 @@ begin get_row_of_line(r1.store_row) = get_row_of_line(get_row(req.real_addr)) then r1.full <= '0'; r1.slow_valid <= '1'; - if r1.mmu_req = '0' then + if req.mmu_req = '0' then r1.ls_valid <= '1'; else r1.mmu_done <= '1'; @@ -1891,7 +1891,7 @@ begin r1.wb.stb & r1.wb.cyc & d_out.error & d_out.valid & - req_op_load_miss & req_op_store & req_op_bad & + req_op_load_miss & req_op_store & req_hit_reload & stall_out & std_ulogic_vector(resize(tlb_hit_way, 3)) & valid_ra &