#include "common.h"
#include "sysinit.h"
#include "ecc_tests.h"
#include "dma.h"
#include "ecc.h"

/* Array used to store the syndrome numbers - one for valid and one for invalid */
uint8 syndromes[25];
//uint8 inv_syndromes[0x80];

#define ECC_ENABLE 0
#define OCRAMECC 0

void ecc_ocram_init(void)
{
 uint32 memStart = 0x3F040000;
 uint32 memSize = 0x040000;
	uint32 i;

#if OCRAMECC
  /* ste bit ER1BR & ERNCR */ 
  reg32_write(OCMECR, 0x00000101);	
  
  /*  */
  reg32_write(OCRMDR1, 0x00000001);	
  
 
  printf("Writing initial values to OCRAM\n");
#endif 			
  for ( i=0; i<memSize; i=i+4 )
  {
    *(uint32 *) (memStart + i) = memStart + i;
  }
#if OCRAMECC	
   reg32_write(OCRMDR1, 0x00000003);

  printf("SDRAM Initialization Complete!\n");      
#endif 	
}

void user_testcase()
{  
    int test_failed;
    char ch;
        
    //printf("\nRunning the ECC test project\n\n");
    
    /* initialize number of failed tests counter to zero */
    test_failed = 0;
  
    /* Initialize the ddr with ECC disabled */
    ddr_iomux();
    ddr_init2(CLK_ON_ALL_MODES);
    
    /* Initialize syndromes array */
    init_syndromes();
    
    /* Test the DDR with ECC - disabled */    
//      test_failed += memtest(0x02000000);
//    test_failed += memtest(0x00002000);
    
//    test_failed += basic_ecc_test();  
     
    //test_failed += sbe_detect_test();     
    //test_failed += sbe_correct_test();   
    //test_failed += ecc_dis_wcrer_test();  
    //test_failed += ecc_no_storage_mode_test();
    
    test_failed += ecc_16bit_test();
    test_failed += ecc_8bit_test();
 
    /* Test causes bus errors - do not run with other tests */
//    test_failed += dbe_detect_test(); 

   test_failed += ecc_32bit_test();            
    
    if (test_failed)
    {
      printf("\n\nTEST FAILED!!!\n");
      printf("\n\n%d test(s) failed.\n", test_failed);
    }
    else
      printf("\n\nAll tests PASS!\n\n");

    while(1);  
}
/********************************************************************/
/* Clear ECC errors.
 * Helper function that acknowledges all ECC errors. This clears the
 * ECC event parameters and allows future events to be captured.
 */
void clear_ecc_err(void)
{
  reg32_write(DDR_CR081, 0x00000078);	// reduc = 1  
}
/********************************************************************/
/* Initialize syndromes.
 * Helper function that sets up an array of the valid syndrome 
 * values. The array is used to force single bit errors. 
 */
void init_syndromes(void)
{
  syndromes[0] = 0x01;
  syndromes[1] = 0x02;
  syndromes[2] = 0x04;
  syndromes[3] = 0x08;
  syndromes[4] = 0x0B;
  syndromes[5] = 0x0E;
  syndromes[6] = 0x10;
  syndromes[7] = 0x13;
  syndromes[8] = 0x15;
  syndromes[9] = 0x16;
  syndromes[10] = 0x19;
  syndromes[11] = 0x1A;
  syndromes[12] = 0x1C;
  syndromes[13] = 0x57;
  syndromes[14] = 0x58;
  syndromes[15] = 0x5B;
  syndromes[16] = 0x5E;
  syndromes[17] = 0x62;
  syndromes[18] = 0x64;
  syndromes[19] = 0x67;
  syndromes[20] = 0x68;
  syndromes[21] = 0x6B;
  syndromes[22] = 0x6D;
  syndromes[23] = 0x70;
  syndromes[24] = 0x75;

}
/********************************************************************/
/* Basic ECC test.
 * Configures the DDR controller for an 8-bit port with ECC enabled.
 * ECC reporting and correcting are both enabled, but at this point
 * no errors are expected. After configuring the DDR controller, a 
 * memory test is run to look for DDR fails. Afterwards the DDR status
 * is checked to verify that no errors have been detected.
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int basic_ecc_test(void)
{
  uint32 i, error;
  
  printf("\nStarting basic ECC test\n\n");

#if ECC_ENABLE
  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - reporting and correcting on */
  reg32_write(DDR_CR057, 0x03000000);	// ctrl_raw = 11
  
  /* Need to disable checking on partial writes to get test to pass */ 
  reg32_write(DDR_CR058, 0x01000000);	// ctrl_raw = 11
  
#endif   
  /* Run memory test with ECC enabled */
//  error = memtest(0x00001000);
//  error = memtest(0x01000000);
  
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }
  
  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
/* Force single bit error (sbe) - detection only test.
 * Configures the DDR controller for an 8-bit port with ECC enabled
 * (ECC detction only--no correction). The test will use the XOR_CHK_BITS
 * field to force a single bit error on every location in the memory.
 * Next each location will be read verifying that the single bit error
 * was detected.
 *
 * Returns: If all errors are detected as expected and no unexpected double
 * bit errors or non-error locations are found, then the test passes 
 * (returns 0). Otherwise test fails (returns 1).
 */
int sbe_detect_test(void)
{
  uint32 memStart = 0x80000000;
  uint32 memSize = 0x01000;
//  uint32 memSize = 0x01000000;
  uint32 i, j, temp, errmsk, error;
#if ECC_ENABLE 
  printf("\nStarting SBE-Detect test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - reporting only  */
  reg32_write(DDR_CR057, 0x01000000);	// ctrl_raw = 11
  
  /* Need to disable checking on partial writes to get test to pass */ 
  reg32_write(DDR_CR058, 0x01000000);	// ctrl_raw = 11
  
#endif  
  /* Write entire memory while forcing a single bit error */
  j = 0x0;
  
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Write XOR_CHK_BITS to force a single bit error */
    reg32_write(DDR_CR058, 0x01000001|(syndromes[j]<<15)|(syndromes[j]<<8));	// reduc = 1
    
    /* Write to memory */
    *(uint32 *) (memStart + i) = memStart + i;
    
    /* Increment index into syndrome array */
    if (j == 24)
      j = 0x0;
    else
      j++;
  }
  
  /* Now test memory and make sure single bit errors are reported */
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Make sure any previous errors are cleared out first */
    clear_ecc_err();

    /* Read data */
    temp = *(uint32 *)(memStart + i);

    /* Test the data - Correcting is disabled right now, but that means
     * we should actually read back the expected value. We are forcing the
     * error so if correction were enabled it would corrupt the value.
     */
    if (temp != memStart + i)
    {
      printf("ERR! Read: 0x%08x  Expected: 0x%08x\n",temp, memStart+i);		
      error++;
    }

    /* Check status to see if any double bit ECC errors were detected - shouldn't be any */
    if (reg32_read(DDR_CR080) & 0x20)
    {
      error++;
      printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
      printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
      printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
      printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
    }
  
    /* Check status to see if any single bit ECC errors were detected */
    if (!(reg32_read(DDR_CR080) & 0x08))
    {
      error++;
      printf("\nERR! Expected single bit error not found. Address = 0x%08x.\n", memStart + i);
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    }
    else
    {
//      printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
//      printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
//      printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
    }
  }  
  
  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
/* Force double bit error (dbe) - detection only test.
 * Configures the DDR controller for an 8-bit port with ECC enabled
 * (ECC detction only--no correction). The test will use the XOR_CHK_BITS
 * field to force a double bit error on every location in the memory.
 * Next each location will be read verifying that the double bit error
 * was detected.
 *
 * Returns: If all errors are detected as expected and no unexpected single
 * bit errors or non-error locations are found, then the test passes 
 * (returns 0). Otherwise test fails (returns 1).
 */
int dbe_detect_test(void)
{
  uint32 memStart = 0x80000000;
  uint32 memSize = 0x01000;
  uint32 i, temp, errmsk, error;
#if ECC_ENABLE  
  printf("\nStarting DBE-Detect test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - reporting only  */
  reg32_write(DDR_CR057, 0x01000000);	
  
  /* Need to disable checking on partial writes to get test to pass */ 
  reg32_write(DDR_CR058, 0x01000000);	
  
#endif  
  /* Write entire memory while forcing a double bit error */
  errmsk = 0x300;
  
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Write XOR_CHK_BITS to force a single bit error */
    reg32_write(DDR_CR058, 0x01000001|errmsk);	// reduc = 1
    
    /* Write to memory */
    *(uint32 *) (memStart + i) = memStart + i;
    
    /* Increment errmsk */
    if (errmsk == 0x300000)
      errmsk = 0x300;
    else
      errmsk <<= 1;
  }
  
  /* Now test memory and make sure double bit errors are reported */
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Make sure any previous errors are cleared out first */
    clear_ecc_err();
    
    /* Read data - do not test because correction is not enabled */
    temp = *(uint32 *)(memStart + i);

    /* Check status to see if any single bit ECC errors were detected - shouldn't be any */
    if (reg32_read(DDR_CR080) & 0x08)
    {
      error++;
      printf("\nERR! At least one single bit ECC error detected when not expected.\n");
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
      printf("CR59 = 0x%08x\n",reg32_read(DDR_CR062));
      printf("CR60 = 0x%08x\n",reg32_read(DDR_CR063));
      printf("CR61 = 0x%08x\n",reg32_read(DDR_CR064));
    }
  
    /* Check status to see if a double bit ECC error was detected */
    if (!(reg32_read(DDR_CR080) & 0x20))
    {
      error++;
      printf("\nERR! Expected double bit error not found. Address = 0x%08x.\n", memStart + i);
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    }
    else
    {
//      printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
//      printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
//      printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
    }
  }  
  
  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
/* Force single bit error (sbe) - coreection test.
 * Configures the DDR controller for an 8-bit port with ECC enabled
 * (both correction and detection enabled). The test will use the XOR_CHK_BITS
 * field to force a single bit error on every location in the memory.
 * Next each location will be read verifying that the single bit error
 * was detected.
 *
 * Returns: If all errors are detected as expected and no unexpected double
 * bit errors or non-error locations are found, then the test passes 
 * (returns 0). Otherwise test fails (returns 1).
 */
int sbe_correct_test(void)
{
  uint32 memStart = 0x80000000;
//  uint32 memSize = 0x01000000;
  uint32 memSize = 0x01000;
  uint32 i, j, temp, errmsk, error;
#if ECC_ENABLE  
  printf("\nStarting SBE-Correct test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - detection only while writing will change to correction mode later  */
  reg32_write(DDR_CR057, 0x01000000);
  
  /* Need to disable checking on partial writes to get test to pass */ 
  reg32_write(DDR_CR058, 0x01000000);	
#endif  
  
  /* Write entire memory while forcing a single bit error */
  j = 0x0;
  
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Write XOR_CHK_BITS to force a single bit error */
    reg32_write(DDR_CR058, 0x01000001|(syndromes[j]<<15)|(syndromes[j]<<8));	// reduc = 1
    
    /* Write to memory */
    *(uint32 *) (memStart + i) = memStart + i;
    
    /* Increment index into syndrome array */
    if (j == 24)
      j = 0x0;
    else
      j++;
  }
  
  /* Now that the entire memory has been written with forced errors, enable
   * the ECC correction mode. 
   */
  reg32_write(DDR_CR057, 0x03000000); 
  
  /* Now test memory and make sure single bit errors are reported */
  for ( i=0; i<memSize; i=i+4 )
  {
    /* Make sure any previous errors are cleared out first */
    clear_ecc_err();

    /* Read data */
    temp = *(uint32 *)(memStart + i);

    /* Do NOT test the data - Correcting is enabled right now, but that means
     * we should actually read back an incorrect value. We are forcing the
     * error so when correction is enabled it will corrupt the value.
     */
#if 0
    if (temp != memStart + i)
    {
      printf("ERR! Read: 0x%08x  Expected: 0x%08x\n",temp, memStart+i);		
      error++;
    }
#endif
    
    /* Check status to see if any double bit ECC errors were detected - shouldn't be any */
    if (reg32_read(DDR_CR080) & 0x20)
    {
      error++;
      printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
      printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
      printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
      printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
    }
  
    /* Check status to see if any single bit ECC errors were detected */
    if (!(reg32_read(DDR_CR080) & 0x08))
    {
      error++;
      printf("\nERR! Expected single bit error not found. Address = 0x%08x.\n", memStart + i);
      printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    }
    else
    {
//      printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
//      printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
//      printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
    }
  }  
  
  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
/* ECC_DIS_WCRER test.
 *
 * Because of the way the system is handling 32-bit core accesses
 * I need this bit set to get regular ECC enabled tests to pass. 
 * This test will use the DMA to transfer some data. This should
 * keep all of the accesses properly aligned and make running with 
 * the ECC_DIS_WCRER bit cleared work. 
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int ecc_dis_wcrer_test(void)
{
  uint32 array[8];
  uint32 result[8];
  uint32 i, error;
#if ECC_ENABLE  
  printf("\nStarting ECC_DIS_WCRER test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - detection only while writing will change to correction mode later  */
  reg32_write(DDR_CR057, 0x01000000);
  
  /* Clear the ecc_dis_wcrer bit */ 
  reg32_write(DDR_CR058, 0x00000000);	
#endif
  /* Load array with values to use for test */
  array[0] = 0xaaaa5555;
  array[1] = 0x0000ffff;
  array[2] = 0x01234567;
  array[3] = 0x89ABCDEF;
  array[4] = 0xdeadbeef;
  array[5] = 0xbabeface;
  array[6] = 0x0FEDCBA9;
  array[7] = 0x87654321;
  
  /* Configure DMA to write values to DDR */
  reg32_write(DDR_TCD0_SADDR, (uint32) &array);
  reg16_write(DDR_TCD0_SOFF, 0x0004);
  reg16_write(DDR_TCD0_ATTR, 0x0205);
  reg32_write(DDR_TCD0_NBYTES, 0x20);
  reg32_write(DDR_TCD0_SLAST, 0x0);
  reg32_write(DDR_TCD0_DADDR, 0x80000000);
  reg16_write(DDR_TCD0_DOFF, 0x0020);
  reg16_write(DDR_TCD0_CITER, 0x1);
  reg32_write(DDR_TCD0_DLAST, 0x0);
  reg16_write(DDR_TCD0_BITER, 0x0001);
  reg16_write(DDR_TCD0_CSR, 0x0001);
    
  /* Wait for write DMA to complete */
  while (!(reg16_read(DDR_TCD0_CSR) &0x0080));
    
  /* Configure DMA to read values from DDR */
  reg32_write(DDR_TCD0_SADDR, 0x80000000);
  reg16_write(DDR_TCD0_SOFF, 0x0020);
  reg16_write(DDR_TCD0_ATTR, 0x0502);
  reg32_write(DDR_TCD0_NBYTES, 0x20);
  reg32_write(DDR_TCD0_SLAST, 0x0);
  reg32_write(DDR_TCD0_DADDR, (uint32) &result);
  reg16_write(DDR_TCD0_DOFF, 0x0004);
  reg16_write(DDR_TCD0_CITER, 0x1);
  reg32_write(DDR_TCD0_DLAST, 0x0);
  reg16_write(DDR_TCD0_BITER, 0x0001);
  reg16_write(DDR_TCD0_CSR, 0x0001);
    
  /* Wait for read DMA to complete */
  while (!(reg16_read(DDR_TCD0_CSR) &0x0080));

  /* Compare original data to results */
  for( i=0; i < 8; i++)
  {
    if(!(result[i] == array[i]))
    {
      error++;
      printf("ERR! Read: 0x%08x  Wrote: 0x%08x\n", result[i], array[i]);      
    }
  }
  
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }  

  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;      
}
/********************************************************************/
/* No ECC storage test.
 * Configures the DDR controller for an 8-bit port with no ECC storage.
 * This mode should be equivalent to running with no ECC. Function performs
 * basic memory test to make sure things are working. Afterwards the DDR status
 * is checked to verify that no ECC errors have been detected.
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int ecc_no_storage_mode_test(void)
{
  uint32 i, error;
 #if ECC_ENABLE 
  printf("\nStarting ECC-no storage mode test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Configure controller for ECC-no storage mode */
  reg32_write(DDR_CR057, 0x02000000);	
  
  /* Make sure ECC_DIS_WCRER is cleared. I know this will trigger
   * errors if the ECC is active.
   */ 
  reg32_write(DDR_CR058, 0x00000000);	
  
#endif  
  /* Run memory test */
//  error = memtest(0x00001000);
//  error = memtest(0x01000000);
  
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }
  
  clear_ecc_err();
  
  if (error)
  {
    printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
/* 16-bit access test.
 * Configures the DDR controller for an 8-bit port with ECC enabled.
 * ECC reporting and correcting are both enabled. After configuring 
 * the DDR controller, a quick memory test is run using 16-bit reads
 * and writes to look for DDR fails. Afterwards the DDR status
 * is checked to verify that no errors have been detected.
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int ecc_16bit_test(void)
{
  uint32 i, error;
  uint16 temp;
  uint32 memStart = 0x3F040000;
//  uint32 memSize = 0x01000000;
  uint32 memSize = 0x01000;

     uint16 pattern = 0xAA55 ; 
  
  ecc_ocram_init();

  printf("\nStarting ECC 16-bit test\n\n");
#if ECC_ENABLE
  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - reporting and correcting on */
  reg32_write(DDR_CR057, 0x03000000);	// ctrl_raw = 11
  
  /* Need to disable checking on partial writes while initializing the memory */ 
  reg32_write(DDR_CR058, 0x01000000);	// ctrl_raw = 11


  printf("Writing initial values to SDRAM\n");
			
  for ( i=0; i<memSize; i=i+2 )
  {
    *(uint16 *) (memStart + i) = memStart + i;
  }
	
  /* Now that the entire memory has been initialized re-enable RMW checking */ 
  reg32_write(DDR_CR058, 0x00000000);	// ctrl_raw = 11

  printf("SDRAM Initialization Complete!\n");      
  
#endif
  /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
  for ( i=0; i<memSize; i=i+2 )
  {
    temp = *(uint16 *)(memStart + i);
   
  }
   /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
   /* write loop */
  
  for ( i=0; i<memSize; i=i+2 )
  {
     *(uint16 *) (memStart + i) = pattern;
   

  }
#if ECC_ENABLE      
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }
#endif  
  clear_ecc_err();

  if (error)
  {
   // printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
  
}
/********************************************************************/
/* 8-bit access test.
 * Configures the DDR controller for an 8-bit port with ECC enabled.
 * ECC reporting and correcting are both enabled. After configuring 
 * the DDR controller, a quick memory test is run using 8-bit reads
 * and writes to look for DDR fails. Afterwards the DDR status
 * is checked to verify that no errors have been detected.
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int ecc_8bit_test(void)
{
  uint32 i, error;
  uint8 temp;
  uint32 memStart = 0x3F040000;
//  uint32 memSize = 0x01000000;
  uint32 memSize = 0x01000;
    uint8 pattern = 0xAA55AA55 ; 
 
    ecc_ocram_init();
  
#if ECC_ENABLE  
  printf("\nStarting ECC 8-bit test\n\n");

  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0000010c);	// reduc = 1
  
  /* Enable ECC - reporting and correcting on */
  reg32_write(DDR_CR057, 0x03000000);	// ctrl_raw = 11
  
  /* Need to disable checking on partial writes while initializing the memory */ 
  reg32_write(DDR_CR058, 0x01000000);	// ctrl_raw = 11

  printf("Writing initial values to SDRAM\n");
			
  for ( i=0; i<memSize; i=i+1 )
  {
    *(uint8 *) (memStart + i) = memStart + i;
  }
  
  /* Now that the entire memory has been initialized re-enable RMW checking */ 
  reg32_write(DDR_CR058, 0x00000000);	// ctrl_raw = 11  
	
  printf("SDRAM Initialization Complete!\n");        
#endif
  /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
  for ( i=0; i<memSize; i=i+1 )
  {
    temp = *(uint8 *)(memStart + i);

  }
   /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
   /* write loop */
  for ( i=0; i<memSize; i=i+1 )
  {
     *(uint8 *) (memStart + i) = pattern;
   

  }
#if ECC_ENABLE      
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }
#endif  
  clear_ecc_err();
  
  if (error)
  {
   // printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}
/********************************************************************/
  
  
/********************************************************************/
/* 16-bit access test.
 * Configures the DDR controller for an 8-bit port with ECC enabled.
 * ECC reporting and correcting are both enabled. After configuring 
 * the DDR controller, a quick memory test is run using 16-bit reads
 * and writes to look for DDR fails. Afterwards the DDR status
 * is checked to verify that no errors have been detected.
 *
 * Returns: If there are no errors reported by the memory test and no
 * ECC errors (single or double) reported by the DDR controller, then the
 * test passes (returns 0). Otherwise test fails (returns 1).
 */
int ecc_32bit_test(void)
{
  uint32 i, error;
  uint32 temp;
  uint32 pattern = 0x0 ; 
  uint32 memStart = 0x80000000;
//  uint32 memSize = 0x01000000;
  uint32 memSize = 0x01000;
   
  
  //  ecc_ocram_init();
   

  printf("\nStarting ECC 16-bit test\n\n");

    reg32_write(DDR_CR081, 0x00000078);
    
  /* Re-configure the DDR controller for an 8-bit port width */ 
  reg32_write(DDR_CR078, 0x0700010c);	// reduc = 1
  
  /* Enable ECC - reporting and correcting on */
  reg32_write(DDR_CR057, 0x03000000);	// ctrl_raw = 11
  
  /* Need to disable checking on partial writes while initializing the memory */ 
  reg32_write(DDR_CR058, 0x01000000);	// ctrl_raw = 11

  printf("Writing initial values to SDRAM\n");
			
  for ( i=0; i<memSize; i=i+4 )
  {
    *(uint32 *) (memStart + i) = 0x0;
  }
	
  /* Now that the entire memory has been initialized re-enable RMW checking */ 
  reg32_write(DDR_CR058, 0x00000000);	// ctrl_raw = 11

  printf("SDRAM Initialization Complete!\n");      


  /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
   /* read loop */
  for ( i=0; i<memSize; i=i+4 )
  {
    temp = *(uint32 *)(memStart + i);

  }
  
   /* Now that the whole memory is written with known values.
   * Go back and check the whole memory.
   */
   /* write loop */
  for ( i=0; i<memSize; i=i+4 )
  {
     *(uint32 *) (memStart + i) = pattern;
   

  }
  
  /*Assembler ECC test failure */
  ca5_bench_ecc_test();
 #if ECC_ENABLE   
  /* Check status to see if any double bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x20)
  {
    error++;
    printf("\nERR! At least one uncorrectable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR59 = 0x%08x\n",reg32_read(DDR_CR059));
    printf("CR60 = 0x%08x\n",reg32_read(DDR_CR060));
    printf("CR61 = 0x%08x\n",reg32_read(DDR_CR061));
  }
  
  /* Check status to see if any single bit ECC errors were detected */
  if (reg32_read(DDR_CR080) & 0x08)
  {
    error++;
    printf("\nERR! At least one correctable ECC error detected when not expected.\n");
    printf("CR80 = 0x%08x\n",reg32_read(DDR_CR080));
    printf("CR62 = 0x%08x\n",reg32_read(DDR_CR062));
    printf("CR63 = 0x%08x\n",reg32_read(DDR_CR063));
    printf("CR64 = 0x%08x\n",reg32_read(DDR_CR064));
  }
#endif  
  clear_ecc_err();
  
  if (error)
  {
  //  printf("\n\n%d test(s) failed.\n", error);
    return 1;
  }
  else
    return 0;    
}


