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 <paulus@ozlabs.org>
pull/459/head
Paul Mackerras 2 weeks ago
parent fdd98d88d4
commit 6eaf22ea95

@ -1704,7 +1704,7 @@ begin
end if; end if;


-- If this is a touch, complete the instruction -- 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.full <= '0';
r1.slow_valid <= '1'; r1.slow_valid <= '1';
r1.ls_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 get_row_of_line(r1.store_row) = get_row_of_line(get_row(req.real_addr)) then
r1.full <= '0'; r1.full <= '0';
r1.slow_valid <= '1'; r1.slow_valid <= '1';
if r1.mmu_req = '0' then if req.mmu_req = '0' then
r1.ls_valid <= '1'; r1.ls_valid <= '1';
else else
r1.mmu_done <= '1'; r1.mmu_done <= '1';
@ -1891,7 +1891,7 @@ begin
r1.wb.stb & r1.wb.cyc & r1.wb.stb & r1.wb.cyc &
d_out.error & d_out.error &
d_out.valid & 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 & stall_out &
std_ulogic_vector(resize(tlb_hit_way, 3)) & std_ulogic_vector(resize(tlb_hit_way, 3)) &
valid_ra & valid_ra &

Loading…
Cancel
Save