1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-05-03 06:49:17 +00:00

Restore debug access to SPRs

This provides access to the SPRs via the JTAG DMI interface.  For now
they are still accessed as if they were GPR/FPRs using the same
numbering as before (GPRs at 0 - 0x1f, SPRs at 0x20 - 0x2d, FPRs at
0x40 - 0x5f).

For XER, debug reads now report the full value, not just the bits that
were previously stored in the register file.  The "slow" SPR mux is
not used for debug reads.

Decode2 determines on each cycle whether a debug SPR access will
happen next cycle, based on whether there is a request and whether the
current instruction accesses the SPR RAM.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
Paul Mackerras
2022-02-25 16:46:34 +11:00
parent fdb3ef6874
commit d0f319290f
6 changed files with 144 additions and 11 deletions

View File

@@ -43,6 +43,10 @@ entity decode2 is
execute2_cr_bypass : in cr_bypass_data_t;
writeback_bypass : in bypass_data_t;
-- Access to SPRs from core_debug module
dbg_spr_req : in std_ulogic;
dbg_spr_addr : in std_ulogic_vector(7 downto 0);
log_out : out std_ulogic_vector(9 downto 0)
);
end entity decode2;
@@ -60,6 +64,7 @@ architecture behaviour of decode2 is
reg_o_valid : std_ulogic;
input_ov : std_ulogic;
output_ov : std_ulogic;
read_rspr : std_ulogic;
end record;
constant reg_type_init : reg_type :=
(e => Decode2ToExecute1Init, repeat => NONE, others => '0');
@@ -347,6 +352,13 @@ begin
" tag=" & integer'image(dc2in.e.instr_tag.tag) & std_ulogic'image(dc2in.e.instr_tag.valid);
end if;
dc2 <= dc2in;
elsif dc2.read_rspr = '0' then
-- Update debug SPR access signals even when stalled
-- if the instruction in dc2.e doesn't read any SPRs.
dc2.e.dbg_spr_access <= dc2in.e.dbg_spr_access;
dc2.e.ramspr_even_rdaddr <= dc2in.e.ramspr_even_rdaddr;
dc2.e.ramspr_odd_rdaddr <= dc2in.e.ramspr_odd_rdaddr;
dc2.e.ramspr_rd_odd <= dc2in.e.ramspr_rd_odd;
end if;
end if;
end process;
@@ -381,6 +393,7 @@ begin
variable op : insn_type_t;
variable valid_in : std_ulogic;
variable decctr : std_ulogic;
variable sprs_busy : std_ulogic;
begin
v := dc2;
@@ -389,6 +402,8 @@ begin
if dc2.busy = '0' then
v.e := Decode2ToExecute1Init;
sprs_busy := '0';
if d_in.valid = '1' then
v.prev_sgl := dc2.sgl_pipe;
v.sgl_pipe := d_in.decode.sgl_pipe;
@@ -467,6 +482,7 @@ begin
v.e.ramspr_odd_rdaddr := RAMSPR_CTR;
v.e.ramspr_wraddr := RAMSPR_CTR;
v.e.ramspr_write_odd := '1';
sprs_busy := '1';
end if;
if v.e.lr = '1' then
-- write LR
@@ -484,11 +500,13 @@ begin
else
v.e.ramspr_even_rdaddr := RAMSPR_TAR;
end if;
sprs_busy := '1';
when OP_MFSPR =>
v.e.ramspr_even_rdaddr := d_in.ram_spr.index;
v.e.ramspr_odd_rdaddr := d_in.ram_spr.index;
v.e.ramspr_rd_odd := d_in.ram_spr.isodd;
v.e.spr_is_ram := d_in.ram_spr.valid;
sprs_busy := d_in.ram_spr.valid;
when OP_MTSPR =>
v.e.ramspr_wraddr := d_in.ram_spr.index;
v.e.ramspr_write_even := d_in.ram_spr.valid and not d_in.ram_spr.isodd;
@@ -497,8 +515,10 @@ begin
when OP_RFID =>
v.e.ramspr_even_rdaddr := RAMSPR_SRR0;
v.e.ramspr_odd_rdaddr := RAMSPR_SRR1;
sprs_busy := '1';
when others =>
end case;
v.read_rspr := sprs_busy and d_in.valid;
case d_in.decode.length is
when is1B =>
@@ -545,8 +565,6 @@ begin
-- Privileged mfspr to invalid/unimplemented SPR numbers
-- writes the contents of RT back to RT (i.e. it's a no-op)
v.e.result_sel := "001"; -- logical_result
elsif d_in.spr_info.ispmu = '1' then
v.e.result_sel := "100"; -- pmuspr_result
end if;
end if;
@@ -649,6 +667,13 @@ begin
stall_out <= dc2.busy or deferred;
v.e.dbg_spr_access := dbg_spr_req and not v.read_rspr;
if v.e.dbg_spr_access = '1' then
v.e.ramspr_even_rdaddr := to_integer(unsigned(dbg_spr_addr(3 downto 1)));
v.e.ramspr_odd_rdaddr := to_integer(unsigned(dbg_spr_addr(3 downto 1)));
v.e.ramspr_rd_odd := dbg_spr_addr(0);
end if;
-- Update registers
dc2in <= v;