From bb1720757d0cd32d2fd7d4febe9ececb9caa22a7 Mon Sep 17 00:00:00 2001 From: Tristan Gingold <tristan.gingold@cern.ch> Date: Mon, 9 May 2022 13:32:08 +0200 Subject: [PATCH] Add cycle counter for iram ecc --- hdl/rtl/hydra_core.vhd | 22 +++++-- hdl/rtl/hydra_iram.vhd | 34 +++++++---- hdl/rtl/hydra_supervisor_regs.cheby | 24 ++++++-- hdl/rtl/hydra_supervisor_regs.vhd | 90 +++++++++++++++++++---------- sw/include/hydra_supervisor_regs.h | 87 ++++++++++++++++++---------- sw/sf2-test/main.c | 18 +++--- 6 files changed, 185 insertions(+), 90 deletions(-) diff --git a/hdl/rtl/hydra_core.vhd b/hdl/rtl/hydra_core.vhd index d2d489f..20e9332 100644 --- a/hdl/rtl/hydra_core.vhd +++ b/hdl/rtl/hydra_core.vhd @@ -124,13 +124,15 @@ architecture arch of hydra_core is signal nbr_dram_ecc_corr : std_logic_vector (31 downto 0); signal nbr_iram_scrub_corr : std_logic_vector (31 downto 0); signal nbr_dram_scrub_corr : std_logic_vector (31 downto 0); - signal nbr_iram_scrub_uncorr : std_logic_vector (31 downto 0); + signal nbr_iram_scrub_uncorr_curr, nbr_iram_scrub_uncorr_last : std_logic_vector (15 downto 0); signal nbr_dram_scrub_uncorr : std_logic_vector (31 downto 0); + signal nbr_iram_scrub_cycle : std_logic_vector (7 downto 0); signal iram_ecc_err, iram_ecc_fatal : std_logic; signal iram_scrub_se, iram_scrub_de : std_logic; signal dram_ecc_err, dram_ecc_fatal : std_logic; signal dram_scrub_se, dram_scrub_de : std_logic; signal iram_scrub_en, dram_scrub_en : std_logic; + signal iram_scrub_cycle : std_logic; signal scrub_cfg_wr, scrub_cfg_iram_val, scrub_cfg_dram_val : std_logic; signal nbr_cpu_data_err : std_logic_vector (31 downto 0); signal nbr_cpu_iaddr_err : std_logic_vector (31 downto 0); @@ -238,6 +240,7 @@ begin ecc_fatal_addr_o => iram_de_addr(g_IRAM_LOG_SIZE - 1 downto 2), scrub_se_o => iram_scrub_se, scrub_de_o => iram_scrub_de, + scrub_cycle_o => iram_scrub_cycle, scrubber_period_i => iram_scrub_period ); @@ -423,7 +426,9 @@ begin nbr_dram_ecc_corr <= (others => '0'); nbr_iram_scrub_corr <= (others => '0'); nbr_dram_scrub_corr <= (others => '0'); - nbr_iram_scrub_uncorr <= (others => '0'); + nbr_iram_scrub_uncorr_curr <= (others => '0'); + nbr_iram_scrub_uncorr_last <= (others => '0'); + nbr_iram_scrub_cycle <= (others => '0'); nbr_dram_scrub_uncorr <= (others => '0'); else if iram_ecc_err = '1' then @@ -432,8 +437,13 @@ begin if iram_scrub_se = '1' then nbr_iram_scrub_corr <= std_logic_vector(unsigned(nbr_iram_scrub_corr) + 1); end if; - if iram_scrub_de = '1' then - nbr_iram_scrub_uncorr <= std_logic_vector(unsigned(nbr_iram_scrub_uncorr) + 1); + if iram_scrub_de = '1' and nbr_iram_scrub_uncorr_curr(15) /= '1' then + nbr_iram_scrub_uncorr_curr <= std_logic_vector(unsigned(nbr_iram_scrub_uncorr_curr) + 1); + end if; + if iram_scrub_cycle = '1' then + nbr_iram_scrub_uncorr_last <= nbr_iram_scrub_uncorr_curr; + nbr_iram_scrub_uncorr_curr <= (others => '0'); + nbr_iram_scrub_cycle <= std_logic_vector(unsigned(nbr_iram_scrub_cycle) + 1); end if; if dram_ecc_err = '1' then nbr_dram_ecc_corr <= std_logic_vector(unsigned(nbr_dram_ecc_corr) + 1); @@ -523,7 +533,9 @@ begin wd_key_wr_o => wd_key_wr, iram_ecc_se_i => nbr_iram_ecc_corr, iram_scrub_se_i => nbr_iram_scrub_corr, - iram_scrub_de_i => nbr_iram_scrub_uncorr, + iram_scrub_de_curr_i => nbr_iram_scrub_uncorr_curr, + iram_scrub_de_last_i => nbr_iram_scrub_uncorr_last, + iram_scrub_cycle_i => nbr_iram_scrub_cycle, dram_ecc_se_i => nbr_dram_ecc_corr, dram_scrub_se_i => nbr_dram_scrub_corr, dram_scrub_de_i => nbr_dram_scrub_uncorr, diff --git a/hdl/rtl/hydra_iram.vhd b/hdl/rtl/hydra_iram.vhd index edf6c25..9fb6e8c 100644 --- a/hdl/rtl/hydra_iram.vhd +++ b/hdl/rtl/hydra_iram.vhd @@ -66,11 +66,12 @@ entity hydra_iram is wdone_o : out std_logic; -- For statistics - ecc_one_o : out std_logic; - ecc_fatal_o : out std_logic; + ecc_one_o : out std_logic; + ecc_fatal_o : out std_logic; ecc_fatal_addr_o : out std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2); - scrub_se_o : out std_logic; - scrub_de_o : out std_logic; + scrub_se_o : out std_logic; + scrub_de_o : out std_logic; + scrub_cycle_o : out std_logic; -- Scrubber scrubber_period_i : in std_logic_vector(15 downto 0) @@ -92,7 +93,13 @@ architecture arch of hydra_iram is signal wdone, n_wdone : std_logic; signal n_ecc_one, n_ecc_fatal : std_logic; - signal last_raddr, n_last_raddr, scrub_addr : std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2); + signal last_raddr, n_last_raddr : std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2); + + -- The scrubber counter has an extra bit to signal a new cycle. + signal scrub_addr_ext : std_logic_vector(g_RAM_LOG_SIZE - 1 + 1 downto 2); + alias scrub_cycle : std_logic is scrub_addr_ext (g_RAM_LOG_SIZE); + alias scrub_addr : std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2) is scrub_addr_ext (g_RAM_LOG_SIZE - 1 downto 2); + signal scrub_cycle_d1, scrub_cycle_d2 : std_logic; signal scrub_counter : unsigned(15 downto 0); signal scrub_rd, scrub_done, n_scrub_done : std_logic; @@ -150,17 +157,24 @@ begin r2_done_o <= r2_done; wdone_o <= wdone; + -- We need to delay scrub_cycle_o so that it happens after a possible + -- error on the last address. + scrub_cycle_o <= scrub_cycle_d2; + p_scrub: process (clk_i) begin if rising_edge(clk_i) then - if rst_n_i = '0' then + if rst_n_i = '0' or scrub_cycle_d2 = '1' then scrub_counter <= unsigned(scrubber_period_i); - scrub_addr <= (others => '0'); + scrub_addr_ext <= (others => '0'); scrub_rd <= '0'; + scrub_cycle_d2 <= '0'; + scrub_cycle_d1 <= '0'; else + scrub_cycle_d1 <= scrub_cycle; + scrub_cycle_d2 <= scrub_cycle_d1; if n_scrub_done = '1' then - scrub_counter <= unsigned(scrubber_period_i); - scrub_addr <= std_logic_vector(unsigned(scrub_addr) + 1); + scrub_addr_ext <= std_logic_vector(unsigned(scrub_addr_ext) + 1); scrub_rd <= '0'; elsif scrub_en_i = '1' then if scrub_counter = (scrub_counter'range => '0') then @@ -239,7 +253,7 @@ begin ren <= '1'; n_r2_done <= '1'; n_last_raddr <= r2_addr_i; - elsif scrub_en_i = '1' then + elsif scrub_en_i = '1' and scrub_cycle = '0' then -- scrub if idle (but not during reset, as write is high priority -- and is a single pulse). raddr <= scrub_addr; diff --git a/hdl/rtl/hydra_supervisor_regs.cheby b/hdl/rtl/hydra_supervisor_regs.cheby index c87b88c..2f7351e 100644 --- a/hdl/rtl/hydra_supervisor_regs.cheby +++ b/hdl/rtl/hydra_supervisor_regs.cheby @@ -76,15 +76,29 @@ memory-map: description: Number of ECC correctable errors for iram width: 32 access: ro + - reg: + name: iram_scrub_cycle + description: IRAM scrubber cycle number. + width: 8 + access: ro - reg: name: iram_scrub_se description: Number of ECC corrected errors by scrubber in iram width: 32 access: ro - reg: - name: iram_scrub_de - description: Number of ECC uncorrected errors by scrubber in iram - width: 32 + name: iram_scrub_de_curr + description: > + Number of ECC uncorrected errors by scrubber in iram in the current + scrubber cycle. Saturate. + width: 16 + access: ro + - reg: + name: iram_scrub_de_last + description: > + Number of ECC uncorrected errors by scrubber in iram during the last + scrubber cycle. Saturate. + width: 16 access: ro - reg: name: dram_ecc_se @@ -132,11 +146,11 @@ memory-map: children: - field: name: iram_en - description: Write 1 to enable iram scrubber + description: Write 1 to enable iram scrubber (cannot be disabled) range: 0 - field: name: dram_en - description: Write 1 to enable dram scrubber + description: Write 1 to enable dram scrubber (cannot be disabled) range: 1 - reg: name: iram_scrub_period diff --git a/hdl/rtl/hydra_supervisor_regs.vhd b/hdl/rtl/hydra_supervisor_regs.vhd index 859e95c..25e172b 100644 --- a/hdl/rtl/hydra_supervisor_regs.vhd +++ b/hdl/rtl/hydra_supervisor_regs.vhd @@ -52,11 +52,19 @@ entity hydra_supervisor_regs is -- Number of ECC correctable errors for iram iram_ecc_se_i : in std_logic_vector(31 downto 0); + -- IRAM scrubber cycle number. + iram_scrub_cycle_i : in std_logic_vector(7 downto 0); + -- Number of ECC corrected errors by scrubber in iram iram_scrub_se_i : in std_logic_vector(31 downto 0); - -- Number of ECC uncorrected errors by scrubber in iram - iram_scrub_de_i : in std_logic_vector(31 downto 0); + -- Number of ECC uncorrected errors by scrubber in iram in the current scrubber cycle. Saturate. + + iram_scrub_de_curr_i : in std_logic_vector(15 downto 0); + + -- Number of ECC uncorrected errors by scrubber in iram during the last scrubber cycle. Saturate. + + iram_scrub_de_last_i : in std_logic_vector(15 downto 0); -- Number of ECC correctable errors for dram dram_ecc_se_i : in std_logic_vector(31 downto 0); @@ -80,10 +88,10 @@ entity hydra_supervisor_regs is iram_de_addr_i : in std_logic_vector(31 downto 0); -- configuration of scrubbers - -- Write 1 to enable iram scrubber + -- Write 1 to enable iram scrubber (cannot be disabled) scrub_cfg_iram_en_i : in std_logic; scrub_cfg_iram_en_o : out std_logic; - -- Write 1 to enable dram scrubber + -- Write 1 to enable dram scrubber (cannot be disabled) scrub_cfg_dram_en_i : in std_logic; scrub_cfg_dram_en_o : out std_logic; scrub_cfg_wr_o : out std_logic; @@ -210,9 +218,13 @@ begin -- Register iram_ecc_se + -- Register iram_scrub_cycle + -- Register iram_scrub_se - -- Register iram_scrub_de + -- Register iram_scrub_de_curr + + -- Register iram_scrub_de_last -- Register dram_ecc_se @@ -315,42 +327,48 @@ begin -- Reg iram_ecc_se wr_ack_int <= wr_req_d0; when "00111" => - -- Reg iram_scrub_se + -- Reg iram_scrub_cycle wr_ack_int <= wr_req_d0; when "01000" => - -- Reg iram_scrub_de + -- Reg iram_scrub_se wr_ack_int <= wr_req_d0; when "01001" => - -- Reg dram_ecc_se + -- Reg iram_scrub_de_curr wr_ack_int <= wr_req_d0; when "01010" => - -- Reg dram_scrub_se + -- Reg iram_scrub_de_last wr_ack_int <= wr_req_d0; when "01011" => - -- Reg dram_scrub_de + -- Reg dram_ecc_se wr_ack_int <= wr_req_d0; when "01100" => - -- Reg cpu_data_err + -- Reg dram_scrub_se wr_ack_int <= wr_req_d0; when "01101" => - -- Reg cpu_iaddr_err + -- Reg dram_scrub_de wr_ack_int <= wr_req_d0; when "01110" => + -- Reg cpu_data_err + wr_ack_int <= wr_req_d0; + when "01111" => + -- Reg cpu_iaddr_err + wr_ack_int <= wr_req_d0; + when "10000" => -- Reg dram_ecc_mask dram_ecc_mask_wreq <= wr_req_d0; wr_ack_int <= dram_ecc_mask_wack; - when "01111" => + when "10001" => -- Reg iram_de_addr wr_ack_int <= wr_req_d0; - when "10000" => + when "10010" => -- Reg scrub_cfg scrub_cfg_wreq <= wr_req_d0; wr_ack_int <= wr_req_d0; - when "10001" => + when "10011" => -- Reg iram_scrub_period iram_scrub_period_wreq <= wr_req_d0; wr_ack_int <= iram_scrub_period_wack; - when "10010" => + when "10100" => -- Reg dram_scrub_period dram_scrub_period_wreq <= wr_req_d0; wr_ack_int <= dram_scrub_period_wack; @@ -363,7 +381,8 @@ begin process (adr_int, rd_req_int, reset_cause_cpu_i, reset_cause_iram_ecc_i, reset_cause_dram_ecc_i, reset_cause_watchdog_i, cpu_reset_i, cpu_recovery_i, force_divergence_i, wd_period_i, wd_count_i, - iram_ecc_se_i, iram_scrub_se_i, iram_scrub_de_i, dram_ecc_se_i, + iram_ecc_se_i, iram_scrub_cycle_i, iram_scrub_se_i, + iram_scrub_de_curr_i, iram_scrub_de_last_i, dram_ecc_se_i, dram_scrub_se_i, dram_scrub_de_i, cpu_data_err_i, cpu_iaddr_err_i, dram_ecc_mask_reg, iram_de_addr_i, scrub_cfg_iram_en_i, scrub_cfg_dram_en_i, iram_scrub_period_reg, dram_scrub_period_reg) begin @@ -407,54 +426,65 @@ begin rd_ack_d0 <= rd_req_int; rd_dat_d0 <= iram_ecc_se_i; when "00111" => - -- Reg iram_scrub_se + -- Reg iram_scrub_cycle rd_ack_d0 <= rd_req_int; - rd_dat_d0 <= iram_scrub_se_i; + rd_dat_d0(7 downto 0) <= iram_scrub_cycle_i; + rd_dat_d0(31 downto 8) <= (others => '0'); when "01000" => - -- Reg iram_scrub_de + -- Reg iram_scrub_se rd_ack_d0 <= rd_req_int; - rd_dat_d0 <= iram_scrub_de_i; + rd_dat_d0 <= iram_scrub_se_i; when "01001" => + -- Reg iram_scrub_de_curr + rd_ack_d0 <= rd_req_int; + rd_dat_d0(15 downto 0) <= iram_scrub_de_curr_i; + rd_dat_d0(31 downto 16) <= (others => '0'); + when "01010" => + -- Reg iram_scrub_de_last + rd_ack_d0 <= rd_req_int; + rd_dat_d0(15 downto 0) <= iram_scrub_de_last_i; + rd_dat_d0(31 downto 16) <= (others => '0'); + when "01011" => -- Reg dram_ecc_se rd_ack_d0 <= rd_req_int; rd_dat_d0 <= dram_ecc_se_i; - when "01010" => + when "01100" => -- Reg dram_scrub_se rd_ack_d0 <= rd_req_int; rd_dat_d0 <= dram_scrub_se_i; - when "01011" => + when "01101" => -- Reg dram_scrub_de rd_ack_d0 <= rd_req_int; rd_dat_d0 <= dram_scrub_de_i; - when "01100" => + when "01110" => -- Reg cpu_data_err rd_ack_d0 <= rd_req_int; rd_dat_d0 <= cpu_data_err_i; - when "01101" => + when "01111" => -- Reg cpu_iaddr_err rd_ack_d0 <= rd_req_int; rd_dat_d0 <= cpu_iaddr_err_i; - when "01110" => + when "10000" => -- Reg dram_ecc_mask rd_ack_d0 <= rd_req_int; rd_dat_d0(7 downto 0) <= dram_ecc_mask_reg; rd_dat_d0(31 downto 8) <= (others => '0'); - when "01111" => + when "10001" => -- Reg iram_de_addr rd_ack_d0 <= rd_req_int; rd_dat_d0 <= iram_de_addr_i; - when "10000" => + when "10010" => -- Reg scrub_cfg rd_ack_d0 <= rd_req_int; rd_dat_d0(0) <= scrub_cfg_iram_en_i; rd_dat_d0(1) <= scrub_cfg_dram_en_i; rd_dat_d0(31 downto 2) <= (others => '0'); - when "10001" => + when "10011" => -- Reg iram_scrub_period rd_ack_d0 <= rd_req_int; rd_dat_d0(15 downto 0) <= iram_scrub_period_reg; rd_dat_d0(31 downto 16) <= (others => '0'); - when "10010" => + when "10100" => -- Reg dram_scrub_period rd_ack_d0 <= rd_req_int; rd_dat_d0(15 downto 0) <= dram_scrub_period_reg; diff --git a/sw/include/hydra_supervisor_regs.h b/sw/include/hydra_supervisor_regs.h index a92d887..b74baf7 100644 --- a/sw/include/hydra_supervisor_regs.h +++ b/sw/include/hydra_supervisor_regs.h @@ -1,6 +1,6 @@ #ifndef __CHEBY__HYDRA_SUPERVISOR_REGS__H__ #define __CHEBY__HYDRA_SUPERVISOR_REGS__H__ -#define HYDRA_SUPERVISOR_REGS_SIZE 74 /* 0x4a */ +#define HYDRA_SUPERVISOR_REGS_SIZE 82 /* 0x52 */ /* Cause of a reset */ #define HYDRA_SUPERVISOR_REGS_RESET_CAUSE 0x0UL @@ -30,44 +30,52 @@ /* Number of ECC correctable errors for iram */ #define HYDRA_SUPERVISOR_REGS_IRAM_ECC_SE 0x18UL +/* IRAM scrubber cycle number. */ +#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_CYCLE 0x1cUL + /* Number of ECC corrected errors by scrubber in iram */ -#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_SE 0x1cUL +#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_SE 0x20UL + +/* Number of ECC uncorrected errors by scrubber in iram in the current scrubber cycle. Saturate. + */ +#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_DE_CURR 0x24UL -/* Number of ECC uncorrected errors by scrubber in iram */ -#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_DE 0x20UL +/* Number of ECC uncorrected errors by scrubber in iram during the last scrubber cycle. Saturate. + */ +#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_DE_LAST 0x28UL /* Number of ECC correctable errors for dram */ -#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_SE 0x24UL +#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_SE 0x2cUL /* Number of ECC corrected errors by scrubber in dram */ -#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_SE 0x28UL +#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_SE 0x30UL /* Number of ECC uncorrected errors by scrubber in dram */ -#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_DE 0x2cUL +#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_DE 0x34UL /* Number of CPU errors on data bus */ -#define HYDRA_SUPERVISOR_REGS_CPU_DATA_ERR 0x30UL +#define HYDRA_SUPERVISOR_REGS_CPU_DATA_ERR 0x38UL /* Number of CPU errors on instruction bus */ -#define HYDRA_SUPERVISOR_REGS_CPU_IADDR_ERR 0x34UL +#define HYDRA_SUPERVISOR_REGS_CPU_IADDR_ERR 0x3cUL /* Change ECC bits on dram writes for testing */ -#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_MASK 0x38UL +#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_MASK 0x40UL /* Address of the last fatal error */ -#define HYDRA_SUPERVISOR_REGS_IRAM_DE_ADDR 0x3cUL +#define HYDRA_SUPERVISOR_REGS_IRAM_DE_ADDR 0x44UL /* configuration of scrubbers */ -#define HYDRA_SUPERVISOR_REGS_SCRUB_CFG 0x40UL +#define HYDRA_SUPERVISOR_REGS_SCRUB_CFG 0x48UL #define HYDRA_SUPERVISOR_REGS_SCRUB_CFG_IRAM_EN 0x1UL #define HYDRA_SUPERVISOR_REGS_SCRUB_CFG_DRAM_EN 0x2UL /* Maximum number of cycles between a scrub */ -#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_PERIOD 0x44UL +#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_PERIOD 0x4cUL #define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_PERIOD_PRESET 0x7ffUL /* Maximum number of cycles between a scrub */ -#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD 0x48UL +#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD 0x50UL #define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD_PRESET 0x7ffUL struct hydra_supervisor_regs { @@ -92,46 +100,63 @@ struct hydra_supervisor_regs { /* [0x18]: REG (ro) Number of ECC correctable errors for iram */ uint32_t iram_ecc_se; - /* [0x1c]: REG (ro) Number of ECC corrected errors by scrubber in iram */ + /* [0x1c]: REG (ro) IRAM scrubber cycle number. */ + uint8_t iram_scrub_cycle; + + /* padding to: 32 words */ + uint8_t __padding_0[3]; + + /* [0x20]: REG (ro) Number of ECC corrected errors by scrubber in iram */ uint32_t iram_scrub_se; - /* [0x20]: REG (ro) Number of ECC uncorrected errors by scrubber in iram */ - uint32_t iram_scrub_de; + /* [0x24]: REG (ro) Number of ECC uncorrected errors by scrubber in iram in the current scrubber cycle. Saturate. + */ + uint16_t iram_scrub_de_curr; - /* [0x24]: REG (ro) Number of ECC correctable errors for dram */ + /* padding to: 40 words */ + uint8_t __padding_1[2]; + + /* [0x28]: REG (ro) Number of ECC uncorrected errors by scrubber in iram during the last scrubber cycle. Saturate. + */ + uint16_t iram_scrub_de_last; + + /* padding to: 44 words */ + uint8_t __padding_2[2]; + + /* [0x2c]: REG (ro) Number of ECC correctable errors for dram */ uint32_t dram_ecc_se; - /* [0x28]: REG (ro) Number of ECC corrected errors by scrubber in dram */ + /* [0x30]: REG (ro) Number of ECC corrected errors by scrubber in dram */ uint32_t dram_scrub_se; - /* [0x2c]: REG (ro) Number of ECC uncorrected errors by scrubber in dram */ + /* [0x34]: REG (ro) Number of ECC uncorrected errors by scrubber in dram */ uint32_t dram_scrub_de; - /* [0x30]: REG (ro) Number of CPU errors on data bus */ + /* [0x38]: REG (ro) Number of CPU errors on data bus */ uint32_t cpu_data_err; - /* [0x34]: REG (ro) Number of CPU errors on instruction bus */ + /* [0x3c]: REG (ro) Number of CPU errors on instruction bus */ uint32_t cpu_iaddr_err; - /* [0x38]: REG (rw) Change ECC bits on dram writes for testing */ + /* [0x40]: REG (rw) Change ECC bits on dram writes for testing */ uint8_t dram_ecc_mask; - /* padding to: 60 words */ - uint8_t __padding_0[3]; + /* padding to: 68 words */ + uint8_t __padding_3[3]; - /* [0x3c]: REG (ro) Address of the last fatal error */ + /* [0x44]: REG (ro) Address of the last fatal error */ uint32_t iram_de_addr; - /* [0x40]: REG (rw) configuration of scrubbers */ + /* [0x48]: REG (rw) configuration of scrubbers */ uint32_t scrub_cfg; - /* [0x44]: REG (rw) Maximum number of cycles between a scrub */ + /* [0x4c]: REG (rw) Maximum number of cycles between a scrub */ uint16_t iram_scrub_period; - /* padding to: 72 words */ - uint8_t __padding_1[2]; + /* padding to: 80 words */ + uint8_t __padding_4[2]; - /* [0x48]: REG (rw) Maximum number of cycles between a scrub */ + /* [0x50]: REG (rw) Maximum number of cycles between a scrub */ uint16_t dram_scrub_period; }; diff --git a/sw/sf2-test/main.c b/sw/sf2-test/main.c index 9b50cd4..592f89b 100644 --- a/sw/sf2-test/main.c +++ b/sw/sf2-test/main.c @@ -222,7 +222,7 @@ main (void) if (SUPERVISOR->dram_scrub_se != 0 || SUPERVISOR->dram_scrub_de != 0) unreachable(); - uart_puts("Start DRAM scrubber"); + uart_puts("Scrub DRAM"); SUPERVISOR->scrub_cfg = HYDRA_SUPERVISOR_REGS_SCRUB_CFG_DRAM_EN; next_test = TEST_IRAM_SE; do { @@ -254,23 +254,23 @@ main (void) case TEST_IRAM_SCRUB: if (SUPERVISOR->iram_scrub_se != 0 - || SUPERVISOR->iram_scrub_de != 0) + || SUPERVISOR->iram_scrub_de_curr != 0 + || SUPERVISOR->iram_scrub_de_last != 0 + || SUPERVISOR->iram_scrub_cycle != 0) unreachable(); - uart_puts("Start IRAM scrubber"); + uart_puts("Scrub IRAM"); SUPERVISOR->scrub_cfg = HYDRA_SUPERVISOR_REGS_SCRUB_CFG_IRAM_EN; next_test = TEST_WD; do { - v = SUPERVISOR->iram_scrub_de; SUPERVISOR->wd_key = WD_KEY; - } while (v == 0); - /* Because the scrubber is always running, the counter is always - incrementing. So the original value is kept. */ + } while (SUPERVISOR->iram_scrub_cycle == 0); uart_putc('\n'); - if (SUPERVISOR->iram_scrub_se != 1 || v > 2) { + if (SUPERVISOR->iram_scrub_se != 1 + || SUPERVISOR->iram_scrub_de_last != 2) { uart_puts ("se:"); uart_put_hex8 (SUPERVISOR->iram_scrub_se); uart_puts (", de:"); - uart_put_hex8 (v); + uart_put_hex8 (SUPERVISOR->iram_scrub_de_last); unreachable(); } /* Fallthrough */ -- GitLab