dcache: Generate a DSI on larx/stcx to non-cacheable memory

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/434/head
Paul Mackerras 1 month ago
parent 0fbeaa2a01
commit c2dcf4b334

@ -626,6 +626,7 @@ package common is
store_done : std_ulogic; store_done : std_ulogic;
error : std_ulogic; error : std_ulogic;
cache_paradox : std_ulogic; cache_paradox : std_ulogic;
reserve_nc : std_ulogic;
end record; end record;


type DcacheEventType is record type DcacheEventType is record

@ -353,6 +353,7 @@ architecture rtl of dcache is
mmu_done : std_ulogic; mmu_done : std_ulogic;
mmu_error : std_ulogic; mmu_error : std_ulogic;
cache_paradox : std_ulogic; cache_paradox : std_ulogic;
reserve_nc : std_ulogic;


-- Signal to complete a failed stcx. -- Signal to complete a failed stcx.
stcx_fail : std_ulogic; stcx_fail : std_ulogic;
@ -1125,7 +1126,7 @@ begin
else else
req_op_flush <= '1'; req_op_flush <= '1';
end if; end if;
elsif nc = '1' and is_hit = '1' then elsif nc = '1' and (is_hit = '1' or r0.req.reserve = '1') then
req_op_bad <= '1'; req_op_bad <= '1';
elsif r0.req.load = '0' then elsif r0.req.load = '0' then
req_op_store <= '1'; -- includes dcbz req_op_store <= '1'; -- includes dcbz
@ -1167,6 +1168,7 @@ begin
d_out.store_done <= not r1.stcx_fail; d_out.store_done <= not r1.stcx_fail;
d_out.error <= r1.ls_error; d_out.error <= r1.ls_error;
d_out.cache_paradox <= r1.cache_paradox; d_out.cache_paradox <= r1.cache_paradox;
d_out.reserve_nc <= r1.reserve_nc;


-- Outputs to MMU -- Outputs to MMU
m_out.done <= r1.mmu_done; m_out.done <= r1.mmu_done;
@ -1354,16 +1356,16 @@ begin
r1.hit_load_valid <= req_op_load_hit; r1.hit_load_valid <= req_op_load_hit;
r1.cache_hit <= req_op_load_hit or (req_op_store and req_is_hit); -- causes PLRU update r1.cache_hit <= req_op_load_hit or (req_op_store and req_is_hit); -- causes PLRU update


r1.cache_paradox <= access_ok and req_nc and req_is_hit;
r1.reserve_nc <= access_ok and r0.req.reserve and req_nc;
if req_op_bad = '1' then if req_op_bad = '1' then
report "Signalling ld/st error valid_ra=" & std_ulogic'image(valid_ra) & report "Signalling ld/st error valid_ra=" & std_ulogic'image(valid_ra) &
" rc_ok=" & std_ulogic'image(rc_ok) & " perm_ok=" & std_ulogic'image(perm_ok); " rc_ok=" & std_ulogic'image(rc_ok) & " perm_ok=" & std_ulogic'image(perm_ok);
r1.ls_error <= not r0.mmu_req; r1.ls_error <= not r0.mmu_req;
r1.mmu_error <= r0.mmu_req; r1.mmu_error <= r0.mmu_req;
r1.cache_paradox <= access_ok;
else else
r1.ls_error <= '0'; r1.ls_error <= '0';
r1.mmu_error <= '0'; r1.mmu_error <= '0';
r1.cache_paradox <= '0';
end if; end if;


-- Record TLB hit information for updating TLB PLRU -- Record TLB hit information for updating TLB PLRU

@ -738,7 +738,8 @@ begin
end if; end if;


interrupt := (r2.req.valid and r2.req.align_intr) or interrupt := (r2.req.valid and r2.req.align_intr) or
(d_in.error and d_in.cache_paradox) or m_in.err; (d_in.error and (d_in.cache_paradox or d_in.reserve_nc)) or
m_in.err;
if interrupt = '1' then if interrupt = '1' then
v.req.valid := '0'; v.req.valid := '0';
v.busy := '0'; v.busy := '0';
@ -905,6 +906,7 @@ begin
-- signal an interrupt straight away -- signal an interrupt straight away
exception := '1'; exception := '1';
dsisr(63 - 38) := not r2.req.load; dsisr(63 - 38) := not r2.req.load;
dsisr(63 - 37) := d_in.reserve_nc;
-- XXX there is no architected bit for this -- XXX there is no architected bit for this
-- (probably should be a machine check in fact) -- (probably should be a machine check in fact)
dsisr(63 - 35) := d_in.cache_paradox; dsisr(63 - 35) := d_in.cache_paradox;

Loading…
Cancel
Save