how to enable ECC on OCRAM and DDR3 with TWR-VF65GS10 board

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to enable ECC on OCRAM and DDR3 with TWR-VF65GS10 board

12,326 Views
francoisjuillet
Contributor III

for our application , we need to  enable ECC in OCRAM and DDR3 and  we use Vybrid Tower kit TWR-VF65GS10.

1) On-Chip Memory Controllers

In chapter 65 of Vybrid reference manual version 5 , it is written

"... The OCRAM_sys ECC function can be summarized in the following steps. Consider reads and writes

separately.

For data writes received by the OCRAM_sys memory controller:

• If enabled, the ECC logic generates the 8-bit checkbit field based on the 29-bit address + 64-bit data

• The 64 data bits + 8 checkbits are stored in the memory  ...

&

Note standard ECC operation requires that the entire memory be written during system startup to

“initialize” correct checkbit values for all locations before read operations can be checked. To assist in this

process, the device implements two independent control flags for each OCRAM_sys controller: one that

enables checkbit generation on writes and another to enable checking on read operations. The memory

initialization writes can be performed directly by a processor or an appropriately configured DMA

channel."

When I am reading the paragrah above  , it seem we need to enable and modify some register to activate the ECC but I have searched in reference Manual and I didn't find how initialize the controller to activate ECC

What is the process to enable the ECC on OCRAM ?

2) DDR3

I use the following procedure to enable ECC on DDR3

     - I written the field ctrl-raw with value " ECC reporting is on, but no attempts to correct. or ECC reporting and correcting on"   in register DDRMC_CR_57

     - I set  the field REDUC in register DDRMC_78

     - I initialize the DDR3 with value 0xFFFFFFFF

     - I enable the DDRMC interrupt to catch any issue

When I read the DDR3  memory with the following width32, 64, 128, 256 bits , it's OK

When I written the  DDR3  memory with the following width  128, 256 bits , it's OK

but  I written the  DDR3  memory with the following width 32 or 64 bits , then the cortex A5 crashed and I need push the button reset

is that someone has already had this problem?

Thanks for any help

Regards

FRancois

Labels (6)
45 Replies

5,505 Views
karina_valencia
NXP Apps Support
NXP Apps Support

jiri-b36968 do you  have an update?

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi,

not yet

/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

hi

Do you need more information ?

Br

francois

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

sorry need more time

/Jiri

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

I just want inform you: keep on working.

/Jiri

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,
had to create new project to test the issue. Now DS-5 project is prepared with Caches and MMU setting and I'm testing your use case. You wrote that you have problem with ECC on OCRAM, but in the function ecc_32bit_test() is uint32 memStart = 0x80000000; this is SDRAM (DDR3). Please confirm.
/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

hi jiri

In this benchmark , I create an assembler function to enable ECC OCRAM and initialize the OCRAM . the name of this function is ca5_ocram_ecc_stack_init in cortex_a5_test.s

the stack is located in OCRAM1

When ECC is enable and after execute this function , We have the following behaviour

benchinit()

     ->MMUConfigAndEnable();

     ->ca5_ocram_ecc_stack_init();   ( ECC Enable )

      ->perf_init(PerfMonEventSelect);

                              -> push ( write OCRAM1 )

                                                  -> _pmuInit_()

                                                                -> push ( write OCRAM1 )

                                                                           ...

                                                                  -> pop ( read OCRAM1 )   -> ECC error

In the function  ca5_ocram_ecc_stack_init, when I disable the following instruction , then it's ok

; enable ECC read
mov r3,#0x3
str r3,[r0,#0x4]

Br

francois

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

OK. your error happens when you try to read from the stack. I assume that mov r3,#0x3 and str r3,[r0,#0x4] configure OCMDR1 register and enables ECC read check. When you erase those instructions then ECC read check is not enabled so then ECC read error is not raised. Just for sure: You copied stack into OCRAM1. Did you checked if target space where stack is located is initiated (if stacker points are correctly replaced)?

Let me summarize it:

It happening when

REGION regionOcmc = { MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,  MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_NON_CACHEABLE, MMU_NON_CACHEABLE), MMU_REGION_NON_SECURE,MMU_AP_PRV_RW_USR_RW,

(unsigned int*)pageTable

};

but it is not happening when

REGION regionOcmc = { MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,  MMU_MEMTYPE_DEVICE_NON_SHAREABLE, MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,

  (unsigned int*)pageTable

};

right ?

Are you using just L1 cache (I,D) or also L2 cache ?

Did you try to enable ECC prior to stack creation during init code?

/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

Hi Francois,

OK. your error happens when you try to read from the stack. I assume that mov r3,#0x3 and str r3,[r0,#0x4] configure OCMDR1 register and enables ECC read check. When you erase those instructions then ECC read check is not enabled so then ECC read error is not raised. Just for sure: You copied stack into OCRAM1. Did you checked if target space where stack is located is initiated (if stacker points are correctly replaced)?

FJ->YES

Let me summarize it:

It happening when

REGION regionOcmc = { MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,  MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_NON_CACHEABLE, MMU_NON_CACHEABLE), MMU_REGION_NON_SECURE,MMU_AP_PRV_RW_USR_RW,

(unsigned int*)pageTable

};

but it is not happening when

REGION regionOcmc = { MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC, MMU_MEMTYPE_DEVICE_NON_SHAREABLE, MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,

  (unsigned int*)pageTable

};

right ?

FJ-> YES


Are you using just L1 cache (I,D) or also L2 cache ?

FJ->We don't use L2 Cache


Did you try to enable ECC prior to stack creation during init code?

FJ->NO


0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

I can finally confirm the issue in OCRAM when ECC is enabled (8,16,32 bit write access). Memory access cause precise abort when:

  • ECC + MMU normal memory + cache

All is OK when:

  • ECC + MMU normal memory + non cache
  • ECC + MMU strong order
  • ECC + MMU device

So cache + ecc does not work correctly. It needs to be discussed with the designer and ARM.

Nevertheless when the stack is in OCRAM our default setting which is strong order(device) is preferred.

/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

hi jiri

Ok , we will use strong order and ECC and we will wait an answer

Do you think that it's the same issue with ECC on DDR3 ?

Br

francois

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

Designers working on it. I do not think that same issue could be on DDR. ECC is part of given memory. Do you see any other troubles with ECC and DDR? I presume that we have solved everything in previous communication.

/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

hi jiri

02/17 , I sent you 2 zip file for 2 issue

1 -> ecc_ocram_issue.zip for OCRAM issue

2->ecc_ddr3_issue.zip for DDR3 issue

Br

francois

0 Kudos
Reply

5,505 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

I'm sorry. I thought that it was solved - moreover I had to use my own project.

So the issue is this? You wrote "but  I written the  DDR3  memory with the following width 32 or 64 bits , then the cortex A5 crashed and I need push the button reset"

Is it also happening when cache is set to write though and not happening when set to strong order, device or non cached?

/Jiri

0 Kudos
Reply

5,505 Views
francoisjuillet
Contributor III

hi jiri

condition

No CACHE enable , NO MMU enable

In the project ecc_ddr3_issue.zip , in function sysinit , We call the function user_testcase.

sysinit

    -> user_testcase

              .....

              ->ecc_32bit_test

                    -> enable ECC and initialize ECC on DDR3 ( base addr =0x80000000)

                    -> loop read DDR3 at 0x80000000

                    ->loop write DDR3 at 0x80000000

                    -> ca5_bench_ecc_test()

                                  LDR r0,=ReadBase_ADDR=0x80000000

                                  STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r6}

                                    LDR r0,=ReadBase_ADDR

                                    STMIA r0!,{r3-r4}                    -> crash

                                    LDR r0,=ReadBase_ADDR

When  ECC ddr3 is disable , this test is ok

francois

0 Kudos
Reply

5,503 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

I was able to replicate the abort event. It happen when:

  1. missing instruction for disable checking on partial writes  reg32_write(DDR_CR058, 0x01000000);
  2. wrong or no initiation of SDRAM memory by write after ECC enable

so please ensure that in your init code

  1. the checking on partial writes is disabled
  2. and SDRAM memory is initiated to 0's.

After some cleaning DS-5 project will be available. So far my init code is:

void ecc_sdram_init(void)

{

    uint32 memStart = 0x80000000;

    uint32 memSize = 0x1000000;

    uint32 i;

    /* Clear ECC errors in IN_STAT DDRMC_CR80 */

    reg32_write(DDR_CR081, 0x00000078);

    /* Re-configure the DDR controller for an 8-bit port width; reduc = 1*/

    reg32_write(DDR_CR078, 0x0000010c);

    // reduc = 1

    //reg32_write(DDR_CR078, 0x0700010c);    // q_fullness reduc

    /* Enable ECC - reporting and correcting on; ctrl_raw = 11 */

    reg32_write(DDR_CR057, 0x03000000);

    /* Need to disable checking on partial writes to get test to pass */

    reg32_write(DDR_CR058, 0x01000000);

    printf("Writing initial values to SDRAM\n");

    for (i = 0; i < memSize; i = i + 4)

    {

        //*(uint32 *) (memStart + i) = memStart + i;

        *(uint32 *) (memStart + i) = 0x0;

    }

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

}

/Jiri

0 Kudos
Reply

5,503 Views
francoisjuillet
Contributor III

hi jiri

Ok I initialize the memory at 0x0 but I have always the same issue ( why we need initialise the memory at 0 and not an other value ?)

the instruction for disable checking on partial writes  reg32_write(DDR_CR058, 0x01000000) is not missing

and at the end of memory initialisation , we must enable the correction reg32_write(DDR_CR058, 0x00000000)

ECC_DIS_WCRER

Disables automatic corruption of the ECC codes for an entire user word when the read portion of a read/

modify/write operation has an un-correctable error. If this is not disabled, the corruption will occur even if

the erroneous byte is overwritten with new data.

0 Allow the ECC codes for the entire user word to be corrupted. (Default)

1 Disable the corruption. The ECC codes written to memory will match the new write data written to

memory.

after I have always the error

    -> ca5_bench_ecc_test()

                                  LDR r0,=ReadBase_ADDR=0x80000000

                                  STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r10}

                                    STMIA r0!,{r3-r6}

                                    LDR r0,=ReadBase_ADDR

                                    STMIA r0!,{r3-r4}                    -> crash

                                    LDR r0,=ReadBase_ADDR

I join the code modified

0 Kudos
Reply

5,503 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

ECC check is enabled in CR57 (reg32_write(DDR_CR057, 0x03000000); )  not in DDR_CR058.

I tried also to allow corruption after correct memory initiation by reg32_write(DDR_CR058, 0x00000000);

No issue found. Data are correctly stored in the memory and there are no EEC errors in DDR_CR80. Code and dis-assembly below.

My program (compiler) uses STRB, STBH and STB instructions for store 8,16 and 32 bits data, LDR,LDRH, LDRB for load. Exact work of STMIA, you use, can be find in ARM documentation, but ECC_DIS_WCRER bit is here especially in the case of CPU access to ECC protected SDRAM memory.

Confirm that you see no issues when line reg32_write(DDR_CR058, 0x00000000); is removed. Maybe you can try to use STR instructions also.

/Jiri

pastedImage_17.png

/* init of ECC check in SDRAM function */

void ecc_sdram_init(void)

{

    uint32 memStart = 0x80000000;

    uint32 memSize = 0x1000000;

    uint32 i;

    /* Clear ECC errors in IN_STAT DDRMC_CR80 */

    reg32_write(DDR_CR081, 0x00000078);

    /* Re-configure the DDR controller for an 8-bit port width; reduc = 1*/

    reg32_write(DDR_CR078, 0x0000010c);

    //reg32_write(DDR_CR078, 0x0700010c);    // q_fullness reduc

    /* Enable ECC - reporting and correcting on; ctrl_raw = 11 */

    reg32_write(DDR_CR057, 0x03000000);

    /* Need to disable checking on partial writes to get test to pass */

    reg32_write(DDR_CR058, 0x01000000);

    printf("Writing initial values to SDRAM\n");

    for (i = 0; i < memSize; i = i + 4)

    {

        //*(uint32 *) (memStart + i) = memStart + i;

        *(uint32 *) (memStart + i) = 0x0;

    }

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

    /* Allow the ECC codes for the entire user word to be corrupted */

    reg32_write(DDR_CR058, 0x00000000);

}

void ecc_sdram_test(void)

{

    uint32 memStart = 0x80000000;

    uint32 memEnd = 0x81000000;

    uint32 memIncrement = 0x0100;

    uint32 i;

    for (i = memStart; i < memEnd; i = i + memIncrement)

    {

        printf("Testing SDRAM memory \n");

        mem8_write(i, (uint8_t) pattern);

        mem16_write(i+2, (uint16_t) pattern);

        mem32_write(i+4, (uint32_t) pattern);

        printf("Adress:%08x i8:%02x i16:%04x i32: %08x \n", i, mem8_read(i), mem16_read(i+2), mem32_read(i+4));

        mem8_write(i, (uint8_t) antipattern);

        mem16_write(i+2, (uint16_t) antipattern);

        mem32_write(i+4, (uint32_t) antipattern);

        printf("Adress:%08x i8:%02x i16:%04x i32: %08x \n", i, mem8_read(i), mem16_read(i+2), mem32_read(i+4));

    }

}

0 Kudos
Reply

5,503 Views
francoisjuillet
Contributor III

hi jiri

I forgot to tell you that only this exact sequence kills the processor

( if you suppress one STMIA , then it's work )

ca5_bench_ecc_test

  push {r3-r12,r14}

;init parameter

  LDR r0,=ReadBase_ADDR

;init limit

  LDR r2,=ReadLimit

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r10}

  STMIA r0!,{r3-r6}

  LDR r0,=ReadBase_ADDR

  STMIA r0!,{r3-r4}          - > crash

  LDR r0,=ReadBase_ADDR

0 Kudos
Reply

5,500 Views
jiri-b36968
NXP Employee
NXP Employee

Hi Francois,

Adding OCRAM ECC description for completeness. It has been removed from RM rev.5 by mistake. Please ignore Freescale confidential warning.

/Jiri

5,500 Views
francoisjuillet
Contributor III

hi

thank you for document

francois

0 Kudos
Reply