This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] TDA4VL-Q1: Enabling and testing Inline ECC for DDR

Part Number: TDA4VL-Q1
Other Parts Discussed in Thread: TDA4VL

Tool/software:

How to enable and perform single and double bit error injection on inline ECC for DDR?

  • Hi,

    Please follow the below patch to enable and inject single and double bit errors on inline ECC for DDRSS0 and DDRSS1 of J721S2.

    From e79f94cc2ec1678bdb00eb03ff41e0caec92f2d1 Mon Sep 17 00:00:00 2001
    From: Josiitaa RL <j-rl@ti.com>
    Date: Fri, 13 Jun 2025 16:54:19 +0530
    Subject: [PATCH] [PDK-17791][J721S2] Enabling and Testing inline ECC on DDRSS0
     and DDRSS1.  - Includes DDRSS0 and DDRSS1 configuration  - ECC enabled for
     the following regions on DDRSS0 and DDRSS1      - R0: 0x80000000 - 0x80001000
          - R1: 0x90000000 - 0x90001000      - R2: 0xA0000000 - 0xA0001000  - ECC
     memory priming  - Residual ECC errors and interrupts cleared  - Includes
     single bit error injection to trigger events in both DDRSS0 and DDRSS1  -
     Includes double bit error injection to trigger events in both DDRSS0 and
     DDRSS1
    
    Signed-off-by: Josiitaa RL <j-rl@ti.com>
    ---
     csl_component.mk                              |  24 +
     example/ddr/ddr_ecc_test_app/ecc_ddr.c        | 528 ++++++++++++++++++
     example/ddr/ddr_ecc_test_app/ecc_ddr.h        |  92 +++
     .../ddr/ddr_ecc_test_app/linker_r5_j721s2.lds | 101 ++++
     example/ddr/ddr_ecc_test_app/main.c           | 366 ++++++++++++
     example/ddr/ddr_ecc_test_app/makefile         |  76 +++
     6 files changed, 1187 insertions(+)
     create mode 100644 example/ddr/ddr_ecc_test_app/ecc_ddr.c
     create mode 100644 example/ddr/ddr_ecc_test_app/ecc_ddr.h
     create mode 100644 example/ddr/ddr_ecc_test_app/linker_r5_j721s2.lds
     create mode 100644 example/ddr/ddr_ecc_test_app/main.c
     create mode 100644 example/ddr/ddr_ecc_test_app/makefile
    
    diff --git a/csl_component.mk b/csl_component.mk
    index f8770ae91..c9825c848 100644
    --- a/csl_component.mk
    +++ b/csl_component.mk
    @@ -1851,6 +1851,30 @@ endif
     csl_ddr_test_app_SBL_APPIMAGEGEN = yes
     export csl_ddr_test_app_SBL_APPIMAGEGEN
     
    +# DDR ECC test app
    +csl_ddr_ecc_test_app_COMP_LIST = csl_ddr_ecc_test_app
    +csl_ddr_ecc_test_app_RELPATH = ti/csl/example/ddr/ddr_ecc_test_app
    +csl_ddr_ecc_test_app_PATH = $(PDK_CSL_COMP_PATH)/example/ddr/ddr_ecc_test_app
    +csl_ddr_ecc_test_app_BOARD_DEPENDENCY = yes
    +ccsl_ddr_ecc_test_app_CORE_DEPENDENCY = yes
    +export csl_ddr_ecc_test_app_COMP_LIST
    +export csl_ddr_ecc_test_app_BOARD_DEPENDENCY
    +export csl_ddr_ecc_test_app_CORE_DEPENDENCY
    +csl_ddr_ecc_test_app_PKG_LIST = csl_ddr_ecc_test_app
    +csl_ddr_ecc_test_app_INCLUDE = $(csl_ddr_ecc_test_app_PATH)
    +csl_ddr_ecc_test_app_BOARDLIST = j721s2_evm
    +export csl_ddr_ecc_test_app_BOARDLIST
    +ifeq ($(BOARD),$(filter $(BOARD), j721s2_evm))
    +csl_ddr_ecc_test_app_$(SOC)_CORELIST = mcu1_0
    +endif
    +export csl_ddr_ecc_test_app_$(SOC)_CORELIST
    +
    +# Packaged for below CSL_BUILDS
    +ifeq ($(CSL_BUILD),$(filter $(CSL_BUILD), CSL))
    +csl_EXAMPLE_LIST += csl_ddr_ecc_test_app
    +endif
    +csl_ddr_ecc_test_app_SBL_APPIMAGEGEN = yes
    +export csl_ddr_ecc_test_app_SBL_APPIMAGEGEN
     
     # CCM R5 test app
     csl_ccmr5_baremetal_test_app_COMP_LIST = csl_ccmr5_baremetal_test_app
    diff --git a/example/ddr/ddr_ecc_test_app/ecc_ddr.c b/example/ddr/ddr_ecc_test_app/ecc_ddr.c
    new file mode 100644
    index 000000000..27325db3f
    --- /dev/null
    +++ b/example/ddr/ddr_ecc_test_app/ecc_ddr.c
    @@ -0,0 +1,528 @@
    +/*
    + *  Copyright (c) Texas Instruments Incorporated 2025
    + *  All rights reserved.
    + *
    + *  Redistribution and use in source and binary forms, with or without
    + *  modification, are permitted provided that the following conditions
    + *  are met:
    + *
    + *    Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + *
    + *    Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the
    + *    distribution.
    + *
    + *    Neither the name of Texas Instruments Incorporated nor the names of
    + *    its contributors may be used to endorse or promote products derived
    + *    from this software without specific prior written permission.
    + *
    + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + *  \file     ecc_ddr.c
    + *
    + *  \brief    This file implements DDR ECC functions
    + */
    +
    +/*===========================================================================*/
    +/*                         Include files                                     */
    +/*===========================================================================*/
    +
    +#include "ecc_ddr.h"
    +#include <sdl_esm.h>
    +#include <ti/osal/osal.h>
    +
    +/* ========================================================================== */
    +/*                                Macros                                      */
    +/* ========================================================================== */
    +
    +/* None */
    +
    +/* ========================================================================== */
    +/*                            Global Variables                                */
    +/* ========================================================================== */
    +
    +volatile uint32_t gSecTestPass;
    +volatile uint32_t gDedTestPass;
    +
    +volatile uint32_t testVal;
    +
    +SDL_ESM_config ECC_Test_esmInitConfig_MAIN =
    +{
    +    .esmErrorConfig = {1u, 8u}, /* Self test error config */
    +    .enableBitmap = {0x00000000u, 0xffffffdbu, 0x7fffffffu, 0xffffffffu,
    +                 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000000u,
    +                 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
    +                 0xfffbfeffu,
    +                },
    +     /**< All events enable: except clkstop events for unused clocks
    +      *   and PCIE events */
    +    .priorityBitmap = {0x00000000u, 0xfffeffdbu, 0x7fffffffu, 0xffffffffu,
    +                         0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                         0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                         0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000000u,
    +                         0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
    +                         0xfffbfeffu,
    +                        },
    +    /**< All events high priority: except clkstop events for unused clocks
    +     *   and PCIE events */
    +    .errorpinBitmap = {0x00000000u, 0xfffeffdbu, 0x7fffffffu, 0xffffffffu,
    +                       0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                       0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
    +                       0xffffffffu, 0xffffffffu, 0xffffffffu, 0x00000000u,
    +                       0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
    +                       0xfffbfeffu,
    +                      },
    +    /**< All events high priority: except clkstop for unused clocks
    +     *   and PCIE events */
    +};
    +
    +/* ========================================================================== */
    +/*                          Function Definitions                              */
    +/* ========================================================================== */
    +
    +static void DDREccInit();
    +static int32_t DDREccConfig();
    +static int32_t DDRSecErrTest(CSL_ecc_aggrRegs *eccAggrRegs, uint32_t test_address_offset);
    +static int32_t DDRDedErrTest(CSL_ecc_aggrRegs *eccAggrRegs, uint32_t test_address_offset);
    +int32_t DDREnableECC(CSL_emif_sscfgRegs *ddrCfgAddr);
    +int32_t DDRDisableECC(CSL_emif_sscfgRegs *ddrCfgAddr);
    +int32_t SDL_ESM_applicationCallbackFunction(SDL_ESM_Inst esmInstType,
    +                                                   SDL_ESM_IntType esmIntType,
    +                                                   uint32_t grpChannel,
    +                                                   uint32_t index,
    +                                                   uint32_t intSrc,
    +                                                   void *arg);
    +
    +/* ========================================================================== */
    +/*                 Internal Function Declarations                             */
    +/* ========================================================================== */
    +
    +int32_t DDREccTest(void)
    +{
    +    int32_t retVal;
    +    static uint32_t arg;
    +    void *ptr = (void *)&arg;
    +    SDL_ErrType_t result = 0;
    +
    +    /* Initialize Test variables */
    +    gSecTestPass   = FALSE;
    +    gDedTestPass   = FALSE;
    +
    +     /* Initialize MAIN ESM module */
    +        retVal = SDL_ESM_init(SDL_ESM_INST_MAIN_ESM0, &ECC_Test_esmInitConfig_MAIN, SDL_ESM_applicationCallbackFunction, ptr);
    +        if (retVal != CSL_PASS) {
    +            /* print error and quit */
    +            UART_printf("ESM_ECC_Example_init: Error initializing MAIN ESM: result = %d\n", result);
    +        } else {
    +            UART_printf("\nESM_ECC_Example_init: Init MAIN ESM complete \n");
    +        }
    +
    +
    +    while (1)
    +    {
    +            DDREccInit();
    +            //Injecting within DDRSS0
    +            retVal = DDRSecErrTest(NULL, 0x15);
    +            retVal = DDRDedErrTest(NULL, 0x15);
    +
    +            //Injecting within DDRSS1
    +            retVal = DDRSecErrTest(NULL, 0x95);
    +            retVal = DDRDedErrTest(NULL, 0x95);
    +            UART_printf( "\r\nDDR ECC test exiting...");
    +            break;
    +        }
    +
    +    if (gSecTestPass)
    +    {
    +        UART_printf( "\r\nDDR ECC SEC ECC TESTS PASSED");
    +    }
    +    else
    +    {
    +        UART_printf( "\r\nDDR ECC SEC ECC TESTS FAILED");
    +    }
    +
    +    if (gDedTestPass)
    +    {
    +        UART_printf( "\r\nDDR ECC DED ECC TESTS PASSED");
    +    }
    +    else
    +    {
    +        UART_printf( "\r\nDDR ECC DED ECC TESTS FAILED");
    +    }
    +    if (gDedTestPass & gSecTestPass)
    +    {
    +        UART_printf( "\r\nDDR ECC TESTS PASS\n");
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +        TEST_PASS();
    +#endif
    +    }
    +    else
    +    {
    +        UART_printf( "\r\nDDR ECC TESTS FAILED");
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +        TEST_FAIL();
    +#endif
    +    }
    +    return retVal;
    +}
    +
    +/* Function initialized DDR ECC */
    +static void DDREccInit()
    +{
    +    int32_t cslRet;
    +
    +    /* Ecc config */
    +    cslRet = DDREccConfig();
    +
    +    if (cslRet != CSL_PASS)
    +    {
    +        UART_printf( "\r\nECC Config failed...");
    +    }
    + 
    +    return;
    +}
    +
    +int32_t DDRDisableECC(CSL_emif_sscfgRegs *ddrCfgAddr)
    +{
    +    CSL_EmifConfig emifCfg;
    +    int32_t cslRet;
    +    int32_t retVal =0;
    +    /* Configure ECC addresses and other configuration */
    +    emifCfg.bEnableMemoryECC = true;
    +    emifCfg.bReadModifyWriteEnable = true;
    +    emifCfg.bECCCheck = true;
    +    emifCfg.bWriteAlloc = true;
    +    emifCfg.ECCThreshold = 1U;
    +    emifCfg.pMemEccCfg.endAddr[0] = DDR_ECC_START_ADDR-EMIF_DDR_START_ADDR;
    +    emifCfg.pMemEccCfg.startAddr[0] = DDR_ECC_END_ADDR-EMIF_DDR_START_ADDR;
    +    emifCfg.pMemEccCfg.endAddr[1] = DDR_ECC_START_ADDR1-EMIF_DDR_START_ADDR;
    +    emifCfg.pMemEccCfg.startAddr[1] = DDR_ECC_END_ADDR1-EMIF_DDR_START_ADDR;
    +    emifCfg.pMemEccCfg.endAddr[2] = DDR_ECC_START_ADDR2-EMIF_DDR_START_ADDR;
    +    emifCfg.pMemEccCfg.startAddr[2] = DDR_ECC_END_ADDR2-EMIF_DDR_START_ADDR;
    +    cslRet = CSL_emifConfig(ddrCfgAddr, &emifCfg);
    +    if (cslRet != CSL_PASS)
    +    {
    +        UART_printf( "\r\n CSL_emifConfig failed");
    +        retVal = -1;
    +    }
    +    return retVal;
    +}
    +
    +int32_t DDREnableECC(CSL_emif_sscfgRegs *ddrCfgAddr)
    +{
    +    CSL_EmifConfig emifCfg;
    +    int32_t cslRet;
    +    int32_t retVal =0;
    +    /* Configure ECC addresses and other configuration */
    +    emifCfg.bEnableMemoryECC = true;
    +    emifCfg.bReadModifyWriteEnable = true;
    +    emifCfg.bECCCheck = true;
    +    emifCfg.bWriteAlloc = true;
    +    emifCfg.ECCThreshold = 1U;
    +    emifCfg.pMemEccCfg.startAddr[0] = (DDR_ECC_START_ADDR-EMIF_DDR_START_ADDR)/2;
    +    emifCfg.pMemEccCfg.endAddr[0] = (DDR_ECC_END_ADDR-EMIF_DDR_START_ADDR)/2;
    +    emifCfg.pMemEccCfg.startAddr[1] = (DDR_ECC_START_ADDR1-EMIF_DDR_START_ADDR)/2;
    +    emifCfg.pMemEccCfg.endAddr[1] = (DDR_ECC_END_ADDR1-EMIF_DDR_START_ADDR)/2;
    +    emifCfg.pMemEccCfg.startAddr[2] = (DDR_ECC_START_ADDR2-EMIF_DDR_START_ADDR)/2;
    +    emifCfg.pMemEccCfg.endAddr[2] = (DDR_ECC_END_ADDR2-EMIF_DDR_START_ADDR)/2;
    +    cslRet = CSL_emifConfig(ddrCfgAddr, &emifCfg);
    +    if (cslRet != CSL_PASS)
    +    {
    +        UART_printf( "\r\n CSL_emifConfig failed");
    +        retVal = -1;
    +    }
    +    return retVal;
    +}
    +
    +/* Function configures DDR ECC and also primes the memory area */
    +int32_t DDREccConfig()
    +{
    +    int32_t    cslResult = CSL_PASS;
    +    uintptr_t  memPtr;
    +    int32_t    retVal = 0;
    +
    +    UART_printf( "\r\n Enabling ECC for DDRSS0 ");
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    UART_printf( "\r\n Enabling ECC for DDRSS1 ");
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    if ( retVal == 0 )
    +    {
    +         /* Prime memory section 1 with known pattern */
    +        for (memPtr = DDR_ECC_START_ADDR; memPtr < DDR_ECC_END_ADDR; memPtr += 4)
    +        {
    +            *((uint32_t *) memPtr) = 0x0;
    +        }
    +
    +        CacheP_wbInv((void *)DDR_ECC_START_ADDR, DDR_ECC_END_ADDR-DDR_ECC_START_ADDR);
    +
    +        /* Prime memory section 2 with known pattern */
    +        for (memPtr = DDR_ECC_START_ADDR1; memPtr < DDR_ECC_END_ADDR1; memPtr += 4)
    +        {
    +            *((uint32_t *) memPtr) = 0x0;
    +        }
    +
    +        CacheP_wbInv((void *)DDR_ECC_START_ADDR1, DDR_ECC_END_ADDR1-DDR_ECC_START_ADDR1);
    +
    +        /* Prime memory section 3 with known pattern */
    +        for (memPtr = DDR_ECC_START_ADDR2; memPtr < DDR_ECC_END_ADDR2; memPtr += 4)
    +        {
    +            *((uint32_t *) memPtr) = 0x0;
    +        }
    +
    +        CacheP_wbInv((void *)DDR_ECC_START_ADDR2, DDR_ECC_END_ADDR2-DDR_ECC_START_ADDR2);
    +
    +        /* Clear any residual ECC errors */
    +        cslResult = CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifClearECCErrors failed for DDRSS0 ");
    +            retVal = -1;
    +        }
    +        cslResult = CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifClearECCErrors failed for DDRSS1");
    +            retVal = -1;
    +        }
    +    }
    +
    +    if ( retVal == 0 )
    +    {
    +        /* clear interrupt status */
    +        cslResult = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                                CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifEnableECCInterrupts failed for DDRSS0");
    +            retVal = -1;
    +        }
    +        /* clear interrupt status */
    +        cslResult = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                                CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifEnableECCInterrupts failed for DDRSS1");
    +            retVal = -1;
    +        }
    +    }
    +
    +    if ( retVal == 0 )
    +    {
    +        /* Configure ECC interrupts : 1 bit error , 1 bit error multiple and 2 bit errors */
    +        cslResult = CSL_emifEnableECCInterrupts((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                                CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifEnableECCInterrupts for DDRSS0 ");
    +            retVal = -1;
    +        }
    +        /* Configure ECC interrupts : 1 bit error , 1 bit error multiple and 2 bit errors */
    +        cslResult = CSL_emifEnableECCInterrupts((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                                CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK
    +                                                | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +        if (cslResult != CSL_PASS)
    +        {
    +            UART_printf( "\r\n CSL_emifEnableECCInterrupts for DDRSS1");
    +            retVal = -1;
    +        }
    +    }
    +
    +    if ( retVal != 0 )
    +    {
    +        UART_printf( "\r\nECC AGGR Configuration failed...");
    +    }
    +
    +    return (retVal);
    +}
    +
    +/* Function performs DDR single bit error test
    + * Configures ECC, Inserts single bit error
    + * and waits for handler to finish
    + */
    +int32_t DDRSecErrTest(CSL_ecc_aggrRegs *eccAggrRegs, uint32_t test_address_offset)
    +{
    +     
    +    int32_t  retVal = CSL_EFAIL;
    +    volatile uint32_t testVal2;
    +    uint32_t waitCount = 0;
    +    uint32_t test_address;
    +
    +    UART_printf( "\r\n Offset: 0x%x", test_address_offset);
    +
    +    /* set the test status to false */
    +    gSecTestPass = FALSE;
    +
    +    /* Clear any residual ECC errors */
    +    CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    test_address = DDR_ECC_START_ADDR + test_address_offset;
    +
    +    /* Inject error */
    +    gTest_Addr = (uint32_t *) (test_address);
    +
    +    /* Write back any pending writes */
    +    CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +    /* Read value from test location */
    +    testVal = gTest_Addr[0];
    +
    +    /* Flip one bit to introduce error */
    +    testVal2       = testVal ^ 0x00010000u;
    +
    +    /* No need to translate the address */
    +
    +    /* NOTE: The following section is test code only cannot be used in real application */
    +    /* ================================================================================ */
    +
    +    /* Temporarily disable ECC */
    +    retVal = DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    retVal = DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    /* Now corrupt the value */
    +    *(gTest_Addr) = testVal2;
    +    CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +    /* Enable back ECC */
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    /* ================================================================================ */
    +
    +    /* Invalidate cache */
    +    CacheP_Inv((const void *)gTest_Addr, 4);
    +
    +    /* Read value to trigger error */
    +    testVal2 = gTest_Addr[0];
    +
    +    /* wait until the test passes */
    +    UART_printf( "\r\n Waiting on SEC Interrupt...");
    +
    +    while ((gSecTestPass == FALSE) && (waitCount++ < 100u)) {
    +        Osal_delay(10);
    +    }
    +    if (gSecTestPass == TRUE) {
    +        UART_printf( "\r\n Got it (test pass)...");
    +        retVal = CSL_PASS;
    +    }
    +    else
    +    {
    +        UART_printf( "\r\n Test failed timedout ...");
    +       
    +    }
    +
    +    /* Restore original value */
    +    gTest_Addr[0] = testVal;
    +
    +    /* Write back any pending writes */
    +    CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +    TEST_ASSERT_EQUAL_INT32(CSL_PASS, retVal);
    +#endif
    +    /* return the test status */
    +    return retVal;
    +}
    +
    +/* Function performs DDR double bit error test
    + * Inserts double bit error and waits for handler to finish
    + */
    +static int32_t DDRDedErrTest(CSL_ecc_aggrRegs *eccAggrRegs, uint32_t test_address_offset)
    +{
    +    int32_t  retVal = CSL_EFAIL;
    +    volatile uint32_t testVal;
    +    volatile uint32_t testVal2;    
    +    uint32_t waitCount = 0;
    +    uint32_t test_address;
    +
    +    gDedTestPass = FALSE;
    +
    +    UART_printf( "\r\n Offset: 0x%x", test_address_offset);
    +
    +    /* Clear any residual ECC errors */
    +    CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    CSL_emifClearAllECCErrors((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    test_address = DDR_ECC_START_ADDR + test_address_offset;
    +    gTest_Addr = (uint32_t *) (test_address);
    +        
    +    CacheP_wbInv((const void *)gTest_Addr, 4);
    +     /* Read reference value */
    +    testVal       = gTest_Addr[0];
    +    /* flip 2 bits */
    +    testVal2       = testVal ^ 0x00101000u;
    +
    +    /* No need to translate the address */
    +
    +    /* NOTE: The following section is test code only cannot be used in real application */
    +    /* ================================================================================ */
    +
    +    /* Temporarily disable ECC */
    +    retVal = DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    retVal = DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    /* Now corrupt the value */
    +    *(gTest_Addr) = testVal2;
    +
    +    /* Make sure the values are written back */
    +    CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +    /* Enable back ECC */
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    retVal = DDREnableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +    /* ================================================================================ */
    +
    +    /* Invalidate cache */
    +    CacheP_Inv((const void *)gTest_Addr, 4);
    +
    +    /* Read value to trigger error */
    +    testVal2 = gTest_Addr[0];
    +
    +    /* wait until the test passes */
    +    UART_printf( "\r\n Waiting on DED interrupt...");
    +    while ((gDedTestPass == FALSE) && (waitCount++ < 10u)) {
    +        Osal_delay(1000);
    +    }
    +
    +    if (gDedTestPass == TRUE) {
    +        UART_printf( "\r\n Got it (test pass)...");
    +        retVal = CSL_PASS;
    +    }
    +    else
    +    {
    +        UART_printf( "\r\n Test failed timedout ...");
    +    }
    +
    +    /* Restore original value */
    +    gTest_Addr[0] = testVal;
    +    
    +    /* return the test status */
    +    return retVal;
    +}
    +
    +/* Nothing past this point */
    \ No newline at end of file
    diff --git a/example/ddr/ddr_ecc_test_app/ecc_ddr.h b/example/ddr/ddr_ecc_test_app/ecc_ddr.h
    new file mode 100644
    index 000000000..bb6699b4c
    --- /dev/null
    +++ b/example/ddr/ddr_ecc_test_app/ecc_ddr.h
    @@ -0,0 +1,92 @@
    +/*
    + *  Copyright (c) Texas Instruments Incorporated 2025
    + *  All rights reserved.
    + *
    + *  Redistribution and use in source and binary forms, with or without
    + *  modification, are permitted provided that the following conditions
    + *  are met:
    + *
    + *    Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + *
    + *    Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the
    + *    distribution.
    + *
    + *    Neither the name of Texas Instruments Incorporated nor the names of
    + *    its contributors may be used to endorse or promote products derived
    + *    from this software without specific prior written permission.
    + *
    + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + *  \file     ecc_ddr.h
    + *
    + *  \brief    This file contains DDR ECC example code defines.
    + */
    +
    +/*===========================================================================*/
    +/*                            Include files                                  */
    +/*===========================================================================*/
    +
    +#ifndef ECC_DDR_H_
    +#define ECC_DDR_H_
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +#include <ti/csl/csl_emif.h>
    +#include <ti/csl/src/ip/ecc_aggr/V1/cslr_ecc_aggr.h>
    +
    +#include <ti/drv/uart/UART_stdio.h>
    +
    +#ifdef UNITY_INCLUDE_CONFIG_H
    +#include <ti/build/unit-test/Unity/src/unity.h>
    +#include <ti/build/unit-test/config/unity_config.h>
    +#endif
    +
    +/* ========================================================================== */
    +/*                                Macros                                      */
    +/* ========================================================================== */
    +
    +extern volatile uint32_t *gTest_Addr;
    +
    +
    +#define DDRSS0_CFG_BASE                  (SDL_COMPUTE_CLUSTER0_DDR0_0_SS_CFG_BASE)
    +#define DDRSS1_CFG_BASE                  (SDL_COMPUTE_CLUSTER0_DDR1_1_SS_CFG_BASE)
    +
    +#define DDR_ECC_START_ADDR               (0x80000000)
    +#define DDR_ECC_END_ADDR                 (0x90000000)
    +#define DDR_ECC_START_ADDR1              (0x90000000)
    +#define DDR_ECC_END_ADDR1                (0xA0000000)
    +#define DDR_ECC_START_ADDR2              (0xA0000000)
    +#define DDR_ECC_END_ADDR2                (0xB0000000)
    +
    +#define EMIF_DDR_START_ADDR              (0x80000000u)
    +
    +/* ========================================================================== */
    +/*                         Function Declarations                              */
    +/* ========================================================================== */
    +
    +int32_t DDREccTest(void);
    +int32_t DDREnableECC(CSL_emif_sscfgRegs *ddrCfgAddr);
    +int32_t DDRDisableECC(CSL_emif_sscfgRegs *ddrCfgAddr);
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif /* ECC_DDR_H_ */
    \ No newline at end of file
    diff --git a/example/ddr/ddr_ecc_test_app/linker_r5_j721s2.lds b/example/ddr/ddr_ecc_test_app/linker_r5_j721s2.lds
    new file mode 100644
    index 000000000..15bb8e937
    --- /dev/null
    +++ b/example/ddr/ddr_ecc_test_app/linker_r5_j721s2.lds
    @@ -0,0 +1,101 @@
    +/* Linker Settings */
    +--retain="*(.bootCode)"
    +--retain="*(.startupCode)"
    +--retain="*(.startupData)"
    +--retain="*(.intvecs)"
    +--retain="*(.intc_text)"
    +--retain="*(.rstvectors)"
    +--retain="*(.irqStack)"
    +--retain="*(.fiqStack)"
    +--retain="*(.abortStack)"
    +--retain="*(.undStack)"
    +--retain="*(.svcStack)"
    +--fill_value=0
    +--stack_size=0x2000
    +--heap_size=0x1000
    +--entry_point=_resetvectors     /* Default C RTS boot.asm   */
    +
    +-stack  0x2000                              /* SOFTWARE STACK SIZE           */
    +-heap   0x2000                              /* HEAP AREA SIZE                */
    +
    +/* Stack Sizes for various modes */
    +__IRQ_STACK_SIZE = 0x1000;
    +__FIQ_STACK_SIZE = 0x1000;
    +__ABORT_STACK_SIZE = 0x1000;
    +__UND_STACK_SIZE = 0x1000;
    +__SVC_STACK_SIZE = 0x1000;
    +
    +/* Memory Map */
    +MEMORY
    +{
    +    /* MCU0_R5F_0 local view */
    +    MCU0_R5F_TCMA_SBL_RSVD (X)  : origin=0x0        length=0x100
    +    MCU0_R5F_TCMA (X)       : origin=0x100      length=0x8000 - 0x100
    +    MCU0_R5F_TCMB0 (RWIX)   : origin=0x41010000 length=0x8000
    +
    +    /* MCU0_R5F_1 SoC view */
    +    MCU0_R5F1_ATCM (RWIX)   : origin=0x41400000 length=0x8000
    +    MCU0_R5F1_BTCM (RWIX)   : origin=0x41410000 length=0x8000
    +
    +    /* Refer the user guide for details on persistence of these sections */
    +    OCMC_RAM_BOARD_CFG (RWIX)   : origin=0x41C80000 length=0x2000
    +    OCMC_RAM_SCISERVER (RWIX)   : origin=0x41C82000 length=0x60000
    +    VECTORS (X)                 : origin=0x41CE2000 length=0x1000
    +    RESET_VECTORS (X)           : origin=0x41CE3000 length=0x100
    +    OCMC_RAM (RWIX)             : origin=0x41CE3100 length=0x1AA00
    +    OCMC_RAM_X509_HEADER (RWIX) : origin=0x41CFDB00 length=0x500
    +
    +    /* j721s2 MCMS3 locations */
    +    /* j721s2 Reserved Memory for ARM Trusted Firmware */
    +    MSMC3_ARM_FW   (RWIX)   : origin=0x70000000 length=0x40000         /* 256KB */
    +    MSMC3   (RWIX)          : origin=0x70040000 length=0x3B0000        /* 4MB - 320KB */
    +    /* j721s2 Reserved Memory for DMSC Firmware */
    +    MSMC3_DMSC_FW  (RWIX)   : origin=0x703F0000 length=0x10000         /* 64KB */
    +
    +    DDR0    (RWIX)          : origin=0x80000000 length=0x40000000      /* 2GB */
    +}
    +
    +/* Section Configuration */
    +SECTIONS
    +{
    +    /* 'intvecs' and 'intc_text' sections shall be placed within */
    +    /* a range of +\- 16 MB */
    +    .intvecs       : {} palign(8)      > VECTORS
    +    .intc_text     : {} palign(8)      > VECTORS
    +    .rstvectors    : {} palign(8)      > RESET_VECTORS
    +    .bootCode      : {} palign(8)      > MSMC3
    +    .startupCode   : {} palign(8)      > MSMC3
    +    .startupData   : {} palign(8)      > MSMC3, type = NOINIT
    +    .text          : {} palign(8)      > MSMC3
    +    .const         : {} palign(8)      > MSMC3
    +    .cinit         : {} palign(8)      > MSMC3
    +    .pinit         : {} palign(8)      > MSMC3
    +    .bss           : {} align(4)       > MSMC3
    +    .far           : {} align(4)       > MSMC3
    +    .data          : {} palign(128)    > MSMC3
    +    .boardcfg_data : {} palign(128)    > MSMC3
    +    .sysmem        : {}                > MSMC3
    +    .data_buffer   : {} palign(128)    > MSMC3
    +    .bss.devgroup  : {*(.bss.devgroup*)} align(4)         > MSMC3
    +    .const.devgroup: {*(.const.devgroup*)} align(4)      > MSMC3
    +
    +    /* USB or any other LLD buffer for benchmarking */
    +    .benchmark_buffer (NOLOAD) {} ALIGN (8) > MSMC3
    +
    +    .stack      : {} align(4)       > MSMC3  (HIGH)
    +    .irqStack   : {. = . + __IRQ_STACK_SIZE;} align(4)      > MSMC3  (HIGH)
    +    RUN_START(__IRQ_STACK_START)
    +    RUN_END(__IRQ_STACK_END)
    +    .fiqStack   : {. = . + __FIQ_STACK_SIZE;} align(4)      > MSMC3  (HIGH)
    +    RUN_START(__FIQ_STACK_START)
    +    RUN_END(__FIQ_STACK_END)
    +    .abortStack : {. = . + __ABORT_STACK_SIZE;} align(4)    > MSMC3  (HIGH)
    +    RUN_START(__ABORT_STACK_START)
    +    RUN_END(__ABORT_STACK_END)
    +    .undStack   : {. = . + __UND_STACK_SIZE;} align(4)      > MSMC3  (HIGH)
    +    RUN_START(__UND_STACK_START)
    +    RUN_END(__UND_STACK_END)
    +    .svcStack   : {. = . + __SVC_STACK_SIZE;} align(4)      > MSMC3  (HIGH)
    +    RUN_START(__SVC_STACK_START)
    +    RUN_END(__SVC_STACK_END)
    +}
    \ No newline at end of file
    diff --git a/example/ddr/ddr_ecc_test_app/main.c b/example/ddr/ddr_ecc_test_app/main.c
    new file mode 100644
    index 000000000..5603e17e1
    --- /dev/null
    +++ b/example/ddr/ddr_ecc_test_app/main.c
    @@ -0,0 +1,366 @@
    +/*
    + *  Copyright (c) Texas Instruments Incorporated 2024-2025
    + *  All rights reserved.
    + *
    + *  Redistribution and use in source and binary forms, with or without
    + *  modification, are permitted provided that the following conditions
    + *  are met:
    + *
    + *    Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + *
    + *    Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the
    + *    distribution.
    + *
    + *    Neither the name of Texas Instruments Incorporated nor the names of
    + *    its contributors may be used to endorse or promote products derived
    + *    from this software without specific prior written permission.
    + *
    + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + *  \file main.c
    + *
    + *  \brief File containing main function implementation for csl_ddr_ecc_test_app
    + */
    +
    +/* ========================================================================== */
    +/*                             Include Files                                  */
    +/* ========================================================================== */
    +
    +#include <ti/osal/CacheP.h>
    +
    +#include <ti/board/board.h>
    +
    +#include "ecc_ddr.h"
    +#include <sdl_esm.h>
    +#include <sdl_ecc.h>
    +#include <osal_interface.h>
    +
    +#ifdef UNITY_INCLUDE_CONFIG_H
    +#include <ti/build/unit-test/Unity/src/unity.h>
    +#include <ti/build/unit-test/config/unity_config.h>
    +#endif
    +
    +/* ========================================================================== */
    +/*                           Macros & Typedefs                                */
    +/* ========================================================================== */
    +
    +#define BOARD_INIT_WAIT_DELAY        1000
    +
    +/* ========================================================================== */
    +/*                         Structure Declarations                             */
    +/* ========================================================================== */
    +
    +/* None */
    +
    +/* ========================================================================== */
    +/*                            Global Variables                                */
    +/* ========================================================================== */
    +
    +volatile uint32_t *gTest_Addr    = NULL;
    +
    +volatile uint32_t gSecTestPass;
    +volatile uint32_t gDedTestPass;
    +
    +int32_t gDdrEccTestResult = CSL_EFAIL;
    +
    +/* ========================================================================== */
    +/*                 Internal Function Declarations                             */
    +/* ========================================================================== */
    +
    +/* Unity functions */
    +void test_csl_ddr_ecc_test_app_runner(void);
    +void test_csl_ddr_ecc_test_app (void);
    +
    +/* ========================================================================== */
    +/*                          Function Definitions                              */
    +/* ========================================================================== */
    +#ifdef UNITY_INCLUDE_CONFIG_H
    +/*
    + *  ======== Unity set up and tear down ========
    + */
    +void setUp(void)
    +{
    +    /* Do nothing */
    +}
    +
    +void tearDown(void)
    +{
    +    /* Do nothing */
    +}
    +#endif
    +
    +int32_t SDL_ESM_applicationCallbackFunction(SDL_ESM_Inst esmInst,
    +                                            SDL_ESM_IntType esmIntrType,
    +                                            uint32_t grpChannel,
    +                                            uint32_t index,
    +                                            uint32_t intSrc,
    +                                            uintptr_t *arg)
    +{
    +
    +    SDL_ECC_MemType eccmemtype;
    +    SDL_Ecc_AggrIntrSrc eccIntrSrc;
    +    SDL_ECC_ErrorInfo_t eccErrorInfo;
    +    int32_t retVal;
    +    volatile uint32_t testVal =0;
    +
    +    UART_printf("\n  ESM Call back function called : instType 0x%x, intType 0x%x, " \
    +                "intSrc 0x%x \n",
    +                esmInst, esmIntrType, intSrc);
    +    UART_printf("  Take action \n");
    +    if(esmIntrType == 1u){
    +        UART_printf(" High Priority Interrupt Executed\n");
    +    }
    +    else{
    +        UART_printf(" Low Priority Interrupt Executed\n");
    +    }
    +    retVal = SDL_ECC_getESMErrorInfo(esmInst, intSrc, &eccmemtype, &eccIntrSrc);
    +
    +    /* Any additional customer specific actions can be added here */
    +    retVal = SDL_ECC_getErrorInfo(eccmemtype, eccIntrSrc, &eccErrorInfo);
    +
    +    if (intSrc == SDLR_ESM0_ESM_LVL_EVENT_DDR0_DDRSS_DRAM_ECC_CORR_ERR_LVL_0)
    +    {
    +        gSecTestPass = TRUE;
    +        /* Clear Specific ECC error */
    +            retVal = CSL_emifClearECCError((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                           CSL_EMIF_ECC_ERROR_TYPE_SINGLE_BIT);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCErrors  failed ");
    +            }
    +
    +            /* Clear ECC interupt bits */
    +            retVal = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                                     CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                     | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCInterruptStatus Failed ");
    +            }
    +
    +    }
    +    else if (intSrc == SDLR_ESM0_ESM_LVL_EVENT_DDR1_DDRSS_DRAM_ECC_CORR_ERR_LVL_0)
    +    {
    +        gSecTestPass = TRUE;
    +        /* Clear Specific ECC error */
    +            retVal = CSL_emifClearECCError((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                           CSL_EMIF_ECC_ERROR_TYPE_SINGLE_BIT);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCErrors  failed ");
    +            }
    +
    +            /* Clear ECC interupt bits */
    +            retVal = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                                     CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC1BERR_EN_MASK
    +                                                     | CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECCM1BERR_EN_MASK);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCInterruptStatus Failed ");
    +            }
    +
    +    }
    +    else if (intSrc == SDLR_ESM0_ESM_LVL_EVENT_DDR0_DDRSS_DRAM_ECC_UNCORR_ERR_LVL_0)
    +    {
    +        gDedTestPass = TRUE;
    +
    +            /* This section corrects the ECC error simulated */
    +            /* In a real application the user must take necessary corrective action */
    +            /******************************************************************/
    +
    +            /* Temporarily disable ECC */
    +            DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +    
    +            /* Now replace location with original value as 2b errors are not corrected */
    +            *(gTest_Addr) = testVal;
    +
    +            /* Write back any pending writes */
    +            CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +            /* Enable back ECC */
    +            DDREnableECC((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE);
    +
    +            /******************************************************************/
    +           /* Clear specific error */
    +            retVal = CSL_emifClearECCError((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                           CSL_EMIF_ECC_ERROR_TYPE_DOUBLE_BIT);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCErrors  failed ");
    +            }
    +
    +            /* Clear ECC interrupt bits */
    +            retVal = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS0_CFG_BASE,
    +                                                     CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCInterruptStatus Failed ");
    +            }
    +    }
    +    else if (intSrc == SDLR_ESM0_ESM_LVL_EVENT_DDR1_DDRSS_DRAM_ECC_UNCORR_ERR_LVL_0)
    +    {
    +        gDedTestPass = TRUE;
    +
    +            /* This section corrects the ECC error simulated */
    +            /* In a real application the user must take necessary corrective action */
    +            /******************************************************************/
    +
    +            /* Temporarily disable ECC */
    +            DDRDisableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +    
    +             /* Now replace location with original value as 2b errors are not corrected */
    +            *(gTest_Addr) = testVal;
    +       
    +            /* Write back any pending writes */
    +            CacheP_wbInv((const void *)gTest_Addr, 4);
    +
    +            /* Enable back ECC */
    +            DDREnableECC((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE);
    +
    +            /******************************************************************/
    +           /* Clear specific error */
    +            retVal = CSL_emifClearECCError((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                           CSL_EMIF_ECC_ERROR_TYPE_DOUBLE_BIT);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCErrors  failed ");
    +            }
    +
    +            /* Clear ECC interrupt bits */
    +            retVal = CSL_emifClearECCInterruptStatus((CSL_emif_sscfgRegs *)DDRSS1_CFG_BASE,
    +                                                     CSL_EMIF_SSCFG_V2A_INT_SET_REG_ECC2BERR_EN_MASK);
    +            if (retVal != CSL_PASS)
    +            {
    +                UART_printf( "\r\n CSL_emifClearECCInterruptStatus Failed ");
    +            }
    +    }
    +    SDL_ESM_clrNError(esmInst);
    +    return retVal;
    +}
    +
    +static int32_t sdlApp_osalInit(void)
    +{
    +    SDL_ErrType_t ret = SDL_PASS;
    +
    +    ret = SDL_TEST_osalInit();
    +    if (ret != SDL_PASS)
    +    {
    +        UART_printf("Error: Init Failed\n");
    +    }
    +
    +    return ret;
    +}
    +
    +void test_csl_ddr_ecc_test_app(void)
    +{
    +
    +    gDdrEccTestResult = DDREccTest();
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +            TEST_ASSERT_EQUAL_INT32(CSL_PASS, gDdrEccTestResult);
    +#else
    +            if (gDdrEccTestResult != CSL_PASS)
    +            {
    +                UART_printf("\r\n DDR ECC test failed \n");
    +            }
    +#endif
    +    return;
    +}
    +
    +void test_csl_ddr_ecc_test_app_runner(void)
    +{
    +#if defined(UNITY_INCLUDE_CONFIG_H)
    +    UNITY_BEGIN();
    +    /* DDR ECC test for R5F */
    +    RUN_TEST (test_csl_ddr_ecc_test_app);
    +
    +    UNITY_END();
    +    /* Function to print results defined in our unity_config.h file */
    +    print_unityOutputBuffer_usingUARTstdio();
    +#else
    +    test_csl_ddr_ecc_test_app();
    +#endif
    +    return;
    +}
    +
    +int main (void)
    +{
    +    Board_initCfg     boardCfg;
    +    Board_STATUS  status = BOARD_SOK;
    +
    +    boardCfg = BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
    +    status = Board_init(boardCfg);
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +    TEST_ASSERT_EQUAL_INT32(BOARD_SOK, status);
    +#else
    +    if (status != BOARD_SOK)
    +    {
    +        UART_printf("\n Board Init failed \n");
    +        return;
    +    }
    +#endif /* (UNITY_INCLUDE_CONFIG_H) */
    +
    +#ifdef NO_SBL
    +    if (status == BOARD_SOK)
    +    {
    +        Osal_delay(BOARD_INIT_WAIT_DELAY);
    +        boardCfg = BOARD_INIT_PINMUX_CONFIG;
    +        status = Board_init(boardCfg);
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +        TEST_ASSERT_EQUAL_INT32(BOARD_SOK, status);
    +#else
    +        if (status != BOARD_SOK)
    +        {
    +            UART_printf("\n Board Init Pinmux Config failed \n");
    +            return;
    +        }
    +#endif /* (UNITY_INCLUDE_CONFIG_H) */
    +    }
    +    if (status == BOARD_SOK)
    +    {
    +        Osal_delay(BOARD_INIT_WAIT_DELAY);
    +        boardCfg = BOARD_INIT_DDR |
    +                   BOARD_INIT_DDR_ECC;
    +        status = Board_init(boardCfg);
    +#if defined (UNITY_INCLUDE_CONFIG_H)
    +        TEST_ASSERT_EQUAL_INT32(BOARD_SOK, status);
    +#else
    +        if (status != BOARD_SOK)
    +        { 
    +            UART_printf("\n Board Init DDR with ECC failed \n");
    +            return;
    +        }
    +#endif /* (UNITY_INCLUDE_CONFIG_H) */
    +    }
    +#endif /* NO_SBL */ 
    +
    +    UART_printf("\n Board init complete \n");
    +    
    +    sdlApp_osalInit();
    +
    +    test_csl_ddr_ecc_test_app_runner();
    +    if (gDdrEccTestResult == CSL_PASS)
    +    {
    +#if defined (SOC_J721E)
    +        if(gMsmcMemParityResult == CSL_PASS)
    +#endif
    +        {
    +           UART_printf("\r\nAll tests have passed.");
    +        }
    +    }
    +    while (1);
    +}
    \ No newline at end of file
    diff --git a/example/ddr/ddr_ecc_test_app/makefile b/example/ddr/ddr_ecc_test_app/makefile
    new file mode 100644
    index 000000000..e39cfbf50
    --- /dev/null
    +++ b/example/ddr/ddr_ecc_test_app/makefile
    @@ -0,0 +1,76 @@
    +include $(PDK_INSTALL_PATH)/ti/build/Rules.make
    +
    +BUILD_OS_TYPE=baremetal
    +
    +APP_NAME = csl_ddr_ecc_test_app
    +
    +SRCDIR = .
    +INCDIR = .
    +
    +# List all the external components/interfaces, whose interface header files
    +#  need to be included for this component
    +INCLUDE_EXTERNAL_INTERFACES = pdk csl_arch
    +
    +# List all the components required by the application
    +ifeq ($(BOARD),$(filter $(BOARD), j721s2_evm))
    + COMP_LIST_COMMON += $(PDK_COMMON_BAREMETAL_COMP)
    +else
    + COMP_LIST_COMMON += csl
    + ifeq ($(CORE),$(filter $(CORE), mcu1_0))
    +  COMP_LIST_a15_0 = csl_init
    + endif
    +endif
    +
    +# Common source files and CFLAGS across all platforms and cores
    +PACKAGE_SRCS_COMMON = .
    +
    +CFLAGS_LOCAL_COMMON = $(PDK_CFLAGS)
    +
    +ifeq ($(SOC), $(filter $(SOC), j721s2))
    +ifeq ($(CORE),mcu1_0)
    +SDL_INSTALL_PATH=$(PDK_INSTALL_PATH)/../../sdl
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/sdl
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/include/soc/$(SOC)
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/include
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/osal
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/test/osal
    +INCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/ip/ecc/V1
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/sdl/ecc
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/sdl/esm
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/ip/esm/V0
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/src/ip/ecc/V1
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/osal/src
    +SRCDIR += $(PDK_INSTALL_PATH)/../../sdl/test/osal/src
    +EXT_LIB_LIST_COMMON += $(SDL_INSTALL_PATH)/binary/src/sdl/lib/$(SOC)/r5f/$(BUILD_PROFILE)/sdl_api.$(LIBEXT)
    +EXT_LIB_LIST_COMMON += $(SDL_INSTALL_PATH)/binary/osal/lib/$(SOC)/r5f/$(BUILD_PROFILE)/sdl_osal.$(LIBEXT)
    +EXT_LIB_LIST_COMMON += $(SDL_INSTALL_PATH)/binary/src/ip/lib/$(SOC)/r5f/$(BUILD_PROFILE)/sdl_ip.$(LIBEXT)
    +EXTERNAL_LNKCMD_FILE_LOCAL = $(PDK_CSL_COMP_PATH)/example/ddr/ddr_ecc_test_app/linker_r5_$(SOC).lds
    +SRCS_COMMON = main.c ecc_ddr.c osal_interface.c
    +endif
    +endif
    +
    +# LNKFLAGS_LOCAL_a15_0 += --entry Entry
    +# LNKFLAGS_LOCAL_mpu1_0 += --entry Entry
    +
    +ifeq ($(SOC),$(filter $(SOC), j721s2))
    + SRCDIR += $(PDK_INSTALL_PATH)/ti/build/unit-test/Unity/src
    + SRCDIR += $(PDK_INSTALL_PATH)/ti/build/unit-test/config
    + INCDIR += $(PDK_INSTALL_PATH)/ti/build/unit-test/Unity/src
    + INCDIR += $(PDK_INSTALL_PATH)/ti/build/unit-test/config
    + SRCS_COMMON += unity_config.c unity.c
    + CFLAGS_LOCAL_COMMON += -DUNITY_INCLUDE_CONFIG_H
    +endif
    +
    +# Include common make files
    +ifeq ($(MAKERULEDIR), )
    +#Makerule path not defined, define this and assume relative path from ROOTDIR
    +  MAKERULEDIR := $(ROOTDIR)/ti/build/makerules
    +  export MAKERULEDIR
    +endif
    +include $(MAKERULEDIR)/common.mk
    +
    +# OBJs and libraries are built by using rule defined in rules_<target>.mk
    +#     and need not be explicitly specified here
    +
    +# Nothing beyond this point
    \ No newline at end of file
    -- 
    2.34.1
    
    

    This patch has been tested on SDK 11.0. Please apply the patch using the below mentioned steps -

    cd $RTOS_SDK/
    git init
    git add .
    git commit -m "init commit"
    git am $PATH_TO_PATCH_SHARED_BELOW

    The following are the memory ranges for which ECC has been enabled and primed -

    #define DDR_ECC_START_ADDR (0x80000000)
    #define DDR_ECC_END_ADDR (0x90000000)
    #define DDR_ECC_START_ADDR1 (0x90000000)
    #define DDR_ECC_END_ADDR1 (0xA0000000)
    #define DDR_ECC_START_ADDR2 (0xA0000000)
    #define DDR_ECC_END_ADDR2 (0xB0000000)

    For more details on inline ECC please refer to the following userguide - https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-j721s2/latest/exports/docs/psdk_rtos/docs/user_guide/developer_notes_ddr_inline_ecc.html

    Please note that this patch is applicable for TDA4VL/J721S2 with 2x DDRSS interleaved every 128 bytes. For 1 or 3x DDRSS interleaved every 128 bytes, the following change would be required -

    +    emifCfg.pMemEccCfg.startAddr[0= (DDR_ECC_START_ADDR-EMIF_DDR_START_ADDR) / n;
    +    emifCfg.pMemEccCfg.endAddr[0= (DDR_ECC_END_ADDR-EMIF_DDR_START_ADDR) / n;
    +    emifCfg.pMemEccCfg.startAddr[1= (DDR_ECC_START_ADDR1-EMIF_DDR_START_ADDR) / n;
    +    emifCfg.pMemEccCfg.endAddr[1= (DDR_ECC_END_ADDR1-EMIF_DDR_START_ADDR) / n;
    +    emifCfg.pMemEccCfg.startAddr[2= (DDR_ECC_START_ADDR2-EMIF_DDR_START_ADDR) / n;
    +    emifCfg.pMemEccCfg.endAddr[2= (DDR_ECC_END_ADDR2-EMIF_DDR_START_ADDR) / n;
    where n is the number of DDRSS.
     

    Regards,

    Josiitaa