diff --git a/hdl/rtl/hydra_core.vhd b/hdl/rtl/hydra_core.vhd
index 20e933223133f73a56fe9d83ca3a27506153b6a5..86651f8079c2f84faacb5075c829fae2e2c3d182 100644
--- a/hdl/rtl/hydra_core.vhd
+++ b/hdl/rtl/hydra_core.vhd
@@ -125,14 +125,15 @@ architecture arch of hydra_core is
   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_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_dram_scrub_uncorr_curr, nbr_dram_scrub_uncorr_last : std_logic_vector (15 downto 0);
   signal nbr_iram_scrub_cycle  : std_logic_vector (7 downto 0);
+  signal nbr_dram_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 iram_scrub_cycle, dram_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);
@@ -283,6 +284,7 @@ begin
       ecc_fatal_o => dram_ecc_fatal,
       scrub_se_o => dram_scrub_se,
       scrub_de_o => dram_scrub_de,
+      scrub_cycle_o => dram_scrub_cycle,
       scrubber_period_i => dram_scrub_period
     );
 
@@ -429,7 +431,9 @@ begin
         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');
+        nbr_dram_scrub_uncorr_curr <= (others => '0');
+        nbr_dram_scrub_uncorr_last <= (others => '0');
+        nbr_dram_scrub_cycle <= (others => '0');
       else
         if iram_ecc_err = '1' then
           nbr_iram_ecc_corr <= std_logic_vector(unsigned(nbr_iram_ecc_corr) + 1);
@@ -451,8 +455,13 @@ begin
         if dram_scrub_se = '1' then
           nbr_dram_scrub_corr <= std_logic_vector(unsigned(nbr_dram_scrub_corr) + 1);
         end if;
-        if dram_scrub_de = '1' then
-          nbr_dram_scrub_uncorr <= std_logic_vector(unsigned(nbr_dram_scrub_uncorr) + 1);
+        if dram_scrub_de = '1' and nbr_dram_scrub_uncorr_curr(15) /= '1' then
+          nbr_dram_scrub_uncorr_curr <= std_logic_vector(unsigned(nbr_dram_scrub_uncorr_curr) + 1);
+        end if;
+        if dram_scrub_cycle = '1' then
+          nbr_dram_scrub_uncorr_last <= nbr_dram_scrub_uncorr_curr;
+          nbr_dram_scrub_uncorr_curr <= (others => '0');
+          nbr_dram_scrub_cycle <= std_logic_vector(unsigned(nbr_dram_scrub_cycle) + 1);
         end if;
       end if;
     end if;
@@ -538,7 +547,9 @@ begin
       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,
+      dram_scrub_de_curr_i => nbr_dram_scrub_uncorr_curr,
+      dram_scrub_de_last_i => nbr_dram_scrub_uncorr_last,
+      dram_scrub_cycle_i => nbr_dram_scrub_cycle,
       cpu_data_err_i => nbr_cpu_data_err,
       cpu_iaddr_err_i => nbr_cpu_iaddr_err,
       dram_ecc_mask_o => dram_ecc_mask,
diff --git a/hdl/rtl/hydra_dram.vhd b/hdl/rtl/hydra_dram.vhd
index 4b52beffdd166835a98bec1f105f6d01136cf67b..be09c73e4db19435ac6193cf49f9397ecad1de7f 100644
--- a/hdl/rtl/hydra_dram.vhd
+++ b/hdl/rtl/hydra_dram.vhd
@@ -58,6 +58,7 @@ entity hydra_dram is
     ecc_fatal_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)
@@ -79,10 +80,16 @@ architecture arch of hydra_dram is
   signal w_done, n_w_done : std_logic;
 
   signal n_ecc_one, n_ecc_fatal : std_logic;
-  signal last_addr, n_last_addr, scrub_addr : std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2);
+  signal last_addr, n_last_addr : std_logic_vector(g_RAM_LOG_SIZE - 1 downto 2);
   signal last_we, n_last_we : std_logic;
   signal last_sel, n_last_sel : std_logic_vector(3 downto 0);
 
+  --  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, scrub_done_d, n_scrub_done : std_logic;
   signal n_scrub_de, n_scrub_se : std_logic;
@@ -135,17 +142,25 @@ begin
   err_o <= rerr_one;
   done_o <= r_done or w_done;
 
+  --  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 scrub_done = '1' and rerr_one = '0' 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
@@ -247,7 +262,7 @@ begin
             ren <= '1';
             n_r_done <= '1';
           end if;
-        elsif scrub_en_i = '1' then
+        elsif scrub_en_i = '1' and scrub_cycle = '0' then
           -- scrub if idle
           addr <= scrub_addr;
           ren <= '1';
diff --git a/hdl/rtl/hydra_supervisor_regs.cheby b/hdl/rtl/hydra_supervisor_regs.cheby
index 2f7351e5f6da636fe5fab4b853b2aca5adb22853..363bade9a54651b98725ef393918f72da0e185f1 100644
--- a/hdl/rtl/hydra_supervisor_regs.cheby
+++ b/hdl/rtl/hydra_supervisor_regs.cheby
@@ -105,15 +105,29 @@ memory-map:
       description: Number of ECC correctable errors for dram
       width: 32
       access: ro
+  - reg:
+      name: dram_scrub_cycle
+      description: DRAM scrubber cycle number.
+      width: 8
+      access: ro
   - reg:
       name: dram_scrub_se
       description: Number of ECC corrected errors by scrubber in dram
       width: 32
       access: ro
   - reg:
-      name: dram_scrub_de
-      description: Number of ECC uncorrected errors by scrubber in dram
-      width: 32
+      name: dram_scrub_de_curr
+      description: >
+        Number of ECC uncorrected errors by scrubber in dram in the current
+        scrubber cycle.  Saturate.
+      width: 16
+      access: ro
+  - reg:
+      name: dram_scrub_de_last
+      description: >
+        Number of ECC uncorrected errors by scrubber in dram during the last
+        scrubber cycle.  Saturate.
+      width: 16
       access: ro
   - reg:
       name: cpu_data_err
diff --git a/hdl/rtl/hydra_supervisor_regs.vhd b/hdl/rtl/hydra_supervisor_regs.vhd
index 25e172baab23c20120bb6400191e6b9d3776f90f..8c3b900e57ab596f1f380e3131ceb884ab8098b8 100644
--- a/hdl/rtl/hydra_supervisor_regs.vhd
+++ b/hdl/rtl/hydra_supervisor_regs.vhd
@@ -69,11 +69,19 @@ entity hydra_supervisor_regs is
     -- Number of ECC correctable errors for dram
     dram_ecc_se_i        : in    std_logic_vector(31 downto 0);
 
+    -- DRAM scrubber cycle number.
+    dram_scrub_cycle_i   : in    std_logic_vector(7 downto 0);
+
     -- Number of ECC corrected errors by scrubber in dram
     dram_scrub_se_i      : in    std_logic_vector(31 downto 0);
 
-    -- Number of ECC uncorrected errors by scrubber in dram
-    dram_scrub_de_i      : in    std_logic_vector(31 downto 0);
+    -- Number of ECC uncorrected errors by scrubber in dram in the current scrubber cycle.  Saturate.
+
+    dram_scrub_de_curr_i : in    std_logic_vector(15 downto 0);
+
+    -- Number of ECC uncorrected errors by scrubber in dram during the last scrubber cycle.  Saturate.
+
+    dram_scrub_de_last_i : in    std_logic_vector(15 downto 0);
 
     -- Number of CPU errors on data bus
     cpu_data_err_i       : in    std_logic_vector(31 downto 0);
@@ -228,9 +236,13 @@ begin
 
   -- Register dram_ecc_se
 
+  -- Register dram_scrub_cycle
+
   -- Register dram_scrub_se
 
-  -- Register dram_scrub_de
+  -- Register dram_scrub_de_curr
+
+  -- Register dram_scrub_de_last
 
   -- Register cpu_data_err
 
@@ -342,33 +354,39 @@ begin
       -- Reg dram_ecc_se
       wr_ack_int <= wr_req_d0;
     when "01100" =>
-      -- Reg dram_scrub_se
+      -- Reg dram_scrub_cycle
       wr_ack_int <= wr_req_d0;
     when "01101" =>
-      -- Reg dram_scrub_de
+      -- Reg dram_scrub_se
       wr_ack_int <= wr_req_d0;
     when "01110" =>
-      -- Reg cpu_data_err
+      -- Reg dram_scrub_de_curr
       wr_ack_int <= wr_req_d0;
     when "01111" =>
-      -- Reg cpu_iaddr_err
+      -- Reg dram_scrub_de_last
       wr_ack_int <= wr_req_d0;
     when "10000" =>
+      -- Reg cpu_data_err
+      wr_ack_int <= wr_req_d0;
+    when "10001" =>
+      -- Reg cpu_iaddr_err
+      wr_ack_int <= wr_req_d0;
+    when "10010" =>
       -- Reg dram_ecc_mask
       dram_ecc_mask_wreq <= wr_req_d0;
       wr_ack_int <= dram_ecc_mask_wack;
-    when "10001" =>
+    when "10011" =>
       -- Reg iram_de_addr
       wr_ack_int <= wr_req_d0;
-    when "10010" =>
+    when "10100" =>
       -- Reg scrub_cfg
       scrub_cfg_wreq <= wr_req_d0;
       wr_ack_int <= wr_req_d0;
-    when "10011" =>
+    when "10101" =>
       -- Reg iram_scrub_period
       iram_scrub_period_wreq <= wr_req_d0;
       wr_ack_int <= iram_scrub_period_wack;
-    when "10100" =>
+    when "10110" =>
       -- Reg dram_scrub_period
       dram_scrub_period_wreq <= wr_req_d0;
       wr_ack_int <= dram_scrub_period_wack;
@@ -383,7 +401,8 @@ begin
            cpu_recovery_i, force_divergence_i, wd_period_i, wd_count_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_scrub_cycle_i, dram_scrub_se_i, dram_scrub_de_curr_i,
+           dram_scrub_de_last_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
     -- By default ack read requests
@@ -449,42 +468,53 @@ begin
       rd_ack_d0 <= rd_req_int;
       rd_dat_d0 <= dram_ecc_se_i;
     when "01100" =>
-      -- Reg dram_scrub_se
+      -- Reg dram_scrub_cycle
       rd_ack_d0 <= rd_req_int;
-      rd_dat_d0 <= dram_scrub_se_i;
+      rd_dat_d0(7 downto 0) <= dram_scrub_cycle_i;
+      rd_dat_d0(31 downto 8) <= (others => '0');
     when "01101" =>
-      -- Reg dram_scrub_de
+      -- Reg dram_scrub_se
       rd_ack_d0 <= rd_req_int;
-      rd_dat_d0 <= dram_scrub_de_i;
+      rd_dat_d0 <= dram_scrub_se_i;
     when "01110" =>
+      -- Reg dram_scrub_de_curr
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(15 downto 0) <= dram_scrub_de_curr_i;
+      rd_dat_d0(31 downto 16) <= (others => '0');
+    when "01111" =>
+      -- Reg dram_scrub_de_last
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(15 downto 0) <= dram_scrub_de_last_i;
+      rd_dat_d0(31 downto 16) <= (others => '0');
+    when "10000" =>
       -- Reg cpu_data_err
       rd_ack_d0 <= rd_req_int;
       rd_dat_d0 <= cpu_data_err_i;
-    when "01111" =>
+    when "10001" =>
       -- Reg cpu_iaddr_err
       rd_ack_d0 <= rd_req_int;
       rd_dat_d0 <= cpu_iaddr_err_i;
-    when "10000" =>
+    when "10010" =>
       -- 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 "10001" =>
+    when "10011" =>
       -- Reg iram_de_addr
       rd_ack_d0 <= rd_req_int;
       rd_dat_d0 <= iram_de_addr_i;
-    when "10010" =>
+    when "10100" =>
       -- 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 "10011" =>
+    when "10101" =>
       -- 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 "10100" =>
+    when "10110" =>
       -- 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 b74baf723a97318bbc7995dd8f8aef83c89acd52..54c4ab3cf713a3ee91432afc919d19d7aab268f0 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 82 /* 0x52 */
+#define HYDRA_SUPERVISOR_REGS_SIZE 90 /* 0x5a */
 
 /* Cause of a reset */
 #define HYDRA_SUPERVISOR_REGS_RESET_CAUSE 0x0UL
@@ -47,35 +47,43 @@
 /* Number of ECC correctable errors for dram */
 #define HYDRA_SUPERVISOR_REGS_DRAM_ECC_SE 0x2cUL
 
+/* DRAM scrubber cycle number. */
+#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_CYCLE 0x30UL
+
 /* Number of ECC corrected errors by scrubber in dram */
-#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_SE 0x30UL
+#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_SE 0x34UL
+
+/* Number of ECC uncorrected errors by scrubber in dram in the current scrubber cycle.  Saturate.
+ */
+#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_DE_CURR 0x38UL
 
-/* Number of ECC uncorrected errors by scrubber in dram */
-#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_DE 0x34UL
+/* Number of ECC uncorrected errors by scrubber in dram during the last scrubber cycle.  Saturate.
+ */
+#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_DE_LAST 0x3cUL
 
 /* Number of CPU errors on data bus */
-#define HYDRA_SUPERVISOR_REGS_CPU_DATA_ERR 0x38UL
+#define HYDRA_SUPERVISOR_REGS_CPU_DATA_ERR 0x40UL
 
 /* Number of CPU errors on instruction bus */
-#define HYDRA_SUPERVISOR_REGS_CPU_IADDR_ERR 0x3cUL
+#define HYDRA_SUPERVISOR_REGS_CPU_IADDR_ERR 0x44UL
 
 /* Change ECC bits on dram writes for testing */
-#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_MASK 0x40UL
+#define HYDRA_SUPERVISOR_REGS_DRAM_ECC_MASK 0x48UL
 
 /* Address of the last fatal error */
-#define HYDRA_SUPERVISOR_REGS_IRAM_DE_ADDR 0x44UL
+#define HYDRA_SUPERVISOR_REGS_IRAM_DE_ADDR 0x4cUL
 
 /* configuration of scrubbers */
-#define HYDRA_SUPERVISOR_REGS_SCRUB_CFG 0x48UL
+#define HYDRA_SUPERVISOR_REGS_SCRUB_CFG 0x50UL
 #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 0x4cUL
+#define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_PERIOD 0x54UL
 #define HYDRA_SUPERVISOR_REGS_IRAM_SCRUB_PERIOD_PRESET 0x7ffUL
 
 /* Maximum number of cycles between a scrub */
-#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD 0x50UL
+#define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD 0x58UL
 #define HYDRA_SUPERVISOR_REGS_DRAM_SCRUB_PERIOD_PRESET 0x7ffUL
 
 struct hydra_supervisor_regs {
@@ -126,37 +134,54 @@ struct hydra_supervisor_regs {
   /* [0x2c]: REG (ro) Number of ECC correctable errors for dram */
   uint32_t dram_ecc_se;
 
-  /* [0x30]: REG (ro) Number of ECC corrected errors by scrubber in dram */
+  /* [0x30]: REG (ro) DRAM scrubber cycle number. */
+  uint8_t dram_scrub_cycle;
+
+  /* padding to: 52 words */
+  uint8_t __padding_3[3];
+
+  /* [0x34]: REG (ro) Number of ECC corrected errors by scrubber in dram */
   uint32_t dram_scrub_se;
 
-  /* [0x34]: REG (ro) Number of ECC uncorrected errors by scrubber in dram */
-  uint32_t dram_scrub_de;
+  /* [0x38]: REG (ro) Number of ECC uncorrected errors by scrubber in dram in the current scrubber cycle.  Saturate.
+ */
+  uint16_t dram_scrub_de_curr;
 
-  /* [0x38]: REG (ro) Number of CPU errors on data bus */
+  /* padding to: 60 words */
+  uint8_t __padding_4[2];
+
+  /* [0x3c]: REG (ro) Number of ECC uncorrected errors by scrubber in dram during the last scrubber cycle.  Saturate.
+ */
+  uint16_t dram_scrub_de_last;
+
+  /* padding to: 64 words */
+  uint8_t __padding_5[2];
+
+  /* [0x40]: REG (ro) Number of CPU errors on data bus */
   uint32_t cpu_data_err;
 
-  /* [0x3c]: REG (ro) Number of CPU errors on instruction bus */
+  /* [0x44]: REG (ro) Number of CPU errors on instruction bus */
   uint32_t cpu_iaddr_err;
 
-  /* [0x40]: REG (rw) Change ECC bits on dram writes for testing */
+  /* [0x48]: REG (rw) Change ECC bits on dram writes for testing */
   uint8_t dram_ecc_mask;
 
-  /* padding to: 68 words */
-  uint8_t __padding_3[3];
+  /* padding to: 76 words */
+  uint8_t __padding_6[3];
 
-  /* [0x44]: REG (ro) Address of the last fatal error */
+  /* [0x4c]: REG (ro) Address of the last fatal error */
   uint32_t iram_de_addr;
 
-  /* [0x48]: REG (rw) configuration of scrubbers */
+  /* [0x50]: REG (rw) configuration of scrubbers */
   uint32_t scrub_cfg;
 
-  /* [0x4c]: REG (rw) Maximum number of cycles between a scrub */
+  /* [0x54]: REG (rw) Maximum number of cycles between a scrub */
   uint16_t iram_scrub_period;
 
-  /* padding to: 80 words */
-  uint8_t __padding_4[2];
+  /* padding to: 88 words */
+  uint8_t __padding_7[2];
 
-  /* [0x50]: REG (rw) Maximum number of cycles between a scrub */
+  /* [0x58]: 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 592f89bb673098b42f5cf15090ae41e979d0323d..d981060cfd9bc9f91fa8febcaa9f442594112346 100644
--- a/sw/sf2-test/main.c
+++ b/sw/sf2-test/main.c
@@ -30,7 +30,7 @@ static enum t_test
    TEST_CPU3_RECOVER,
    TEST_CPU1_FATAL,
    TEST_RAM,
-   TEST_DONE
+   TEST_DONE,
 } next_test;
 
 static void
@@ -62,15 +62,14 @@ uart_raw_putc (unsigned char c)
   *(volatile unsigned *)UART_TX = c;
 }
 
-static unsigned char
+static int
 uart_raw_getc (void)
 {
-  /* Wait until DR (data ready, bit 0) is set.  */
-  do {
-    SUPERVISOR->wd_key = WD_KEY;
-  } while (!(*(volatile unsigned*)UART_LSR & 0x1));
-
-  return *(volatile unsigned *)UART_RX;
+  /* Check if DR (data ready, bit 0) is set.  */
+  if (*(volatile unsigned*)UART_LSR & 0x1)
+    return *(volatile unsigned *)UART_RX;
+  else
+    return -1;
 }
 
 static void
@@ -163,6 +162,7 @@ int
 main (void)
 {
   unsigned v;
+  int c;
 
   SUPERVISOR->wd_key = WD_KEY;
   uart_init ();
@@ -219,24 +219,27 @@ main (void)
     break;
 
   case TEST_DRAM_SCRUB:
+    uart_putc('*');
     if (SUPERVISOR->dram_scrub_se != 0
-        || SUPERVISOR->dram_scrub_de != 0)
+        || SUPERVISOR->dram_scrub_de_curr != 0
+        || SUPERVISOR->dram_scrub_de_last != 0
+        || SUPERVISOR->dram_scrub_cycle != 0)
       unreachable();
     uart_puts("Scrub DRAM");
     SUPERVISOR->scrub_cfg = HYDRA_SUPERVISOR_REGS_SCRUB_CFG_DRAM_EN;
     next_test = TEST_IRAM_SE;
     do {
-      v = SUPERVISOR->dram_scrub_de;
       SUPERVISOR->wd_key = WD_KEY;
-    } while (v == 0);
+    } while (SUPERVISOR->dram_scrub_cycle == 0);
     /* Because the scrubber is always running, the counter is always
        incrementing.  So the original value is kept. */
     uart_putc('\n');
-    if (SUPERVISOR->dram_scrub_se != 1 || v > 2) {
+    if (SUPERVISOR->dram_scrub_se != 1
+        || SUPERVISOR->dram_scrub_de_last != 2) {
       uart_puts ("se:");
       uart_put_hex8 (SUPERVISOR->dram_scrub_se);
       uart_puts (", de:");
-      uart_put_hex8 (v);
+      uart_put_hex8 (SUPERVISOR->dram_scrub_de_last);
       unreachable();
     }
     /* Remove the errors */
@@ -330,8 +333,40 @@ main (void)
     next_test++;
     SUPERVISOR->wd_key = WD_KEY;
     SUPERVISOR->wd_period = 100000000;
-    uart_puts ("Hello diot.\n");
-    while (1)
+    break;
+  }
+
+  while (1) {
+    uart_puts ("i-nfo, r-ecover, l-oop\n");
+    while ((c = uart_raw_getc()) == -1)
       ;
+    switch (c) {
+    case 'i':
+      v = SUPERVISOR->wd_count;
+      uart_puts ("wd count: ");
+      uart_put_hex8 (v);
+      uart_putc ('\n');
+      uart_puts ("ecc dram: se:");
+      uart_put_hex8 (SUPERVISOR->dram_scrub_se);
+      uart_puts (", de:");
+      uart_put_hex8 (SUPERVISOR->dram_scrub_de_last);
+      uart_putc ('\n');
+      uart_puts ("ecc iram: se:");
+      uart_put_hex8 (SUPERVISOR->iram_scrub_se);
+      uart_puts (", de:");
+      uart_put_hex8 (SUPERVISOR->iram_scrub_de_last);
+      uart_putc ('\n');
+      break;
+    case 'r':
+      /* Generate reset for recovery */
+      SUPERVISOR->cpu = HYDRA_SUPERVISOR_REGS_CPU_RECOVERY;
+
+      unreachable();
+    case 'l':
+      while (1)
+        ;
+    default:
+      break;
+    }
   }
 }