#include <stdint.h>
#include "common.h"

static void failure(unsigned v)
{
  SUPERVISOR->dram_scrub_period = v;
  while (1)
    SUPERVISOR->wd_key = WD_KEY;
}

int
main (void)
{
  unsigned cyc;

  SUPERVISOR->wd_period = 5000;

  /* Clear recovery bit.  */
  SUPERVISOR->cpu = 0;

  if (SUPERVISOR->reset_cause == 0)
    {
      /* Enable scrubber */
      SUPERVISOR->scrub_cfg = HYDRA_SUPERVISOR_REGS_SCRUB_CFG_IRAM_EN
        | HYDRA_SUPERVISOR_REGS_SCRUB_CFG_DRAM_EN;
    }


  /* Test ecc ram.  */
  if (SUPERVISOR->dram_scrub_se != 0 || SUPERVISOR->dram_scrub_de_last != 0)
    failure(__LINE__);

  /* Single ECC error  */
  SUPERVISOR->dram_ecc_mask = 1;
  *(volatile unsigned *)0x40100 = 123;
  SUPERVISOR->dram_ecc_mask = 0;

  cyc = SUPERVISOR->dram_scrub_cycle;
  while (SUPERVISOR->dram_scrub_cycle < cyc + 2)
    SUPERVISOR->wd_key = WD_KEY;

  if (SUPERVISOR->dram_scrub_se != 1 || SUPERVISOR->dram_scrub_de_last != 0)
    failure(__LINE__);

  /* Double ECC error  */
  SUPERVISOR->dram_ecc_mask = 6;
  *(volatile unsigned *)0x40104 = 456;
  SUPERVISOR->dram_ecc_mask = 0;

  cyc = SUPERVISOR->dram_scrub_cycle;
  while (SUPERVISOR->dram_scrub_cycle < cyc + 2)
    SUPERVISOR->wd_key = WD_KEY;

  if (SUPERVISOR->dram_scrub_se != 1 || SUPERVISOR->dram_scrub_de_last != 1)
    failure(__LINE__);

  failure(-1);
}
