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.

AM5729: TI PDK SBLLibCPUReset function stuck in while loop

Part Number: AM5729

Hi champs,

When I want to use the

 SBLLibCPUReset(SBLLIB_CORE_ID_EVE1);

function from sbl_lib_platform.c file in the ti-pdk-2020.4.16 version in my custom application, I see that the code is stuck in the while loop in PMHALResetRelease called by this function.My code starts immediately after u-boot and EVEs need to be reset.Can you help with the problem?

int32_t PMHALResetRelease(pmhalPrcmResetGroupId_t resId, uint32_t timeout)
{
    AppUtils_printf("PMHAL line 293\n");
    pmErrCode_t retVal;
    uint32_t    resetCtrlMask;
    uint32_t    timeToWait;
    uint32_t    rstStat;
    uint32_t    rstStMask;
    rstStat = 0x0U;
    retVal  = PM_SUCCESS;
    retVal  = PmhalIsResetDomainIdValid(resId);
    if (PM_SUCCESS == retVal)
    {
        retVal = PmhalIsResetDomainRegAvailable(resId);
    }
    if (PM_SUCCESS == retVal)
    {
        /* Put the local reset domain out of reset state by programming the
         * <RD>_RSTCTRL bit to 0.
         */
        resetCtrlMask =
            (uint32_t) 1U <<
            pmhalResetDomainElems[resId].rstCtrlBitField->regShift;
        HW_WR_FIELD32_RAW(
            pmhalResetDomainElems[resId].rstCtrlBitField->regAddr,
            resetCtrlMask,
            pmhalResetDomainElems[resId].rstCtrlBitField->regShift,
            (uint32_t) 0x0U);
        /* On lifting the reset based on the time out given by the user wait
         * for the reset to complete and the status reflected in the <RD>_RSTST.
         */
        if (timeout == PM_TIMEOUT_NOWAIT)
        {
            /* Will not wait for the release status */
            ;
        }
        else if (timeout == PM_TIMEOUT_INFINITE)
        {
            /* Wait infinitely for the reset to complete */
            do
            {
                rstStMask = (uint32_t) 1U <<
                            pmhalResetDomainElems[resId].rstStBitField->
                            regShift;

                rstStat =
                    (uint32_t) HW_RD_FIELD32_RAW(
                        pmhalResetDomainElems[resId].rstStBitField->regAddr,
                        rstStMask,
                        pmhalResetDomainElems[resId].rstStBitField->regShift);
            } while (0x1U != rstStat);
        }
        else
        {

            /* Wait for the reset to complete till time out occurs */
            timeToWait = timeout;
            do
            {
                rstStMask = (uint32_t) 1U <<
                            pmhalResetDomainElems[resId].rstStBitField->
                            regShift;
            
                rstStat =
                    (uint32_t) HW_RD_FIELD32_RAW(
                        pmhalResetDomainElems[resId].rstStBitField->regAddr,
                        rstStMask,
                        pmhalResetDomainElems[resId].rstStBitField->regShift);
                timeToWait--;
            } while ((0x1U != rstStat) && (0U != timeToWait));
            /* If the time out expires and the reset has still not completed
             * the function returns failure.
             */
            if (timeToWait == 0U)
            {

                if (0x1U == rstStat)
                {
                    retVal = PM_SUCCESS;

                }
                else
                {
                    retVal = PM_FAIL;
                }
            }
        }
    }
    return (int32_t) retVal;
}

  • Hi Mert,

    Please expect a response early next week once the assigned engineer is back in office after a TI regional holiday today.

    regards

    Suman

  • Hi Suman,

    I look forward to hearing from you.

  • Hi,

    At what point are you calling this API? Can you please share your code flow?

    Regards,
    Parth

  • This is my main.c.

    /* xdctools header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Diags.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/Log.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/IHeap.h>
    
    /* package header files */
    #include <ti/ipc/Ipc.h>
    #include <ti/ipc/MessageQ.h>
    #include <ti/ipc/MultiProc.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/ipc/SharedRegion.h>
    
    /*-----------------------------------------------------------------------------
    * C standard library
    *----------------------------------------------------------------------------*/
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /* local header files */
    #include "custom_rsc_table_vayu_ipu1.h"
    #include "tal/mbox_msgq_shared.h"
    #include "src/utils_eveloader.h"
    
    #define MAX_NUM_EVES               (4)
    #define MAX_NUM_COMPLETION_PENDING (16)
    
    /* private data */
    int              num_eve_devices;
    int              eve_work_count = 0;
    MessageQ_Handle  eveProxyQueue = NULL;
    MessageQ_QueueId eveQueues[MAX_NUM_EVES];
    
    ocl_msgq_message_t* ocl_msgq_pkt = NULL;
    ocl_msgq_message_t* eve_ocl_msgq_pkt[MAX_NUM_EVES][MAX_NUM_COMPLETION_PENDING];
    int                 eve_ocl_msgq_avail_slot[MAX_NUM_EVES];
    
    /* private functions */
    static Void smain_idle(UArg arg0, UArg arg1);
    static Void smain(UArg arg0, UArg arg1);
    static bool create_mqueue();
    static int  GetNumEVEDevices();
    
    
    /*
     *  ======== main ========
     */
    Int main(Int argc, Char* argv[])
    {
        Error_Block     eb;
        Task_Params     taskParams;
        Int             status;
    
        Log_print0(Diags_ENTRY, "--> main:");
    
        /* Check available EVE devices to see if OpenCL firmware applies */
        num_eve_devices = GetNumEVEDevices();
    
        /* SR0, pm require Ipc_start() */
        do
        {
            status = Ipc_start();
        } while (status != Ipc_S_SUCCESS);
    
        /* must initialize the error block before using it */
        Error_init(&eb);
    
        /* create main thread (interrupts not enabled in main on BIOS) */
        Task_Params_init(&taskParams);
        taskParams.instance->name = "smain";
        taskParams.arg0 = (UArg)argc;
        taskParams.arg1 = (UArg)argv;
        taskParams.stackSize = 0x1000;
        if (num_eve_devices > 0)
            Task_create(smain, &taskParams, &eb);
        else
            Task_create(smain_idle, &taskParams, &eb);
    
        if (Error_check(&eb)) {
            System_abort("main: failed to create application startup thread");
        }
        if (num_eve_devices <= 0)
        {
            Log_print0(Diags_INFO | Diags_USER6,
                       "firmware does not apply. Idling...");
            BIOS_start(); /* start scheduler, this never returns */
        }
    
        /* Make sure we finish EVE attachments before IPC power management */
        eve_work_count = 1;
    
        Log_print0(Diags_INFO | Diags_USER6, "Creating msg queue...");
        /* Create the M4 proxy queue for EVEs */
        if (!create_mqueue())
        {
            Log_print0(Diags_INFO | Diags_USER6, "failed to create msg queue");
            System_abort("main: create_mqueue() failed");
        }
    
        Log_print0(Diags_INFO | Diags_USER6, "Booting EVEs...");
        /* Boot the EVEs */
        status = Utils_eveBoot(num_eve_devices);
        if (status)
        {
            Log_print0(Diags_INFO | Diags_USER6, "failed to boot EVEs");
            System_abort("main: Utils_eveBoot() failed");
        }
    
        Log_print0(Diags_INFO | Diags_USER6, "Starting BIOS...");
        /* start scheduler, this never returns */
        BIOS_start();
    
        /* should never get here */
        Log_print0(Diags_EXIT, "<-- main:");
        return (0);
    }
    
    /*
     *  ======== smain_idle ========
     *  For the purpose of entering the SYS/BIOS idle loop, so that
     *  power management idle function can be called for suspend/resume
     */
    Void smain_idle(UArg arg0, UArg arg1)
    {
        while (1)  Task_yield();
    }
    
    /*
     *  ======== smain ========
     */
    Void smain(UArg arg0, UArg arg1)
    {
        Int                 status = 0;
        int                 i, j;
    
        Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
    
        /* Attaching to EVEs */
        Log_print0(Diags_INFO | Diags_USER6, "Attaching to EVEs...");
        for (i = 0; i < num_eve_devices; i++)
        {
            const char *eve_name = (i == 0) ? "EVE1" :
                                   (i == 1) ? "EVE2" :
                                   (i == 2) ? "EVE3" :
                                              "EVE4";
            do {
                status = Ipc_attach(MultiProc_getId((String) eve_name));
                Task_sleep(1);
            } while (status == Ipc_E_NOTREADY);
    
            if (status < 0) {
                Log_print1(Diags_INFO | Diags_USER6,
                           "Attaching %s failed", (xdc_IArg) eve_name);
                return;
            }
            Log_print1(Diags_INFO | Diags_USER6,
                       "%s attached", (xdc_IArg) eve_name);
        }
    
        /* Opening MsgQs on EVEs */
        Log_print0(Diags_INFO | Diags_USER6, "Opening MsgQ on EVEs...");
        for (i = 0; i < num_eve_devices; i++)
        {
            const char *queue_name = (i == 0) ? "OCL:EVE1:MsgQ" :
                                     (i == 1) ? "OCL:EVE2:MsgQ" :
                                     (i == 2) ? "OCL:EVE3:MsgQ" :
                                                "OCL:EVE4:MsgQ";
            status = MessageQ_open((String) queue_name, &eveQueues[i]);
            if (status < 0) {
                Log_print1(Diags_INFO | Diags_USER6,
                           "Opening %s failed", (xdc_IArg) queue_name);
                return;
            }
            Log_print1(Diags_INFO | Diags_USER6,
                       "%s opened", (xdc_IArg) queue_name);
        }
    
        /* Pre-allocating msgs to EVEs */
        Log_print0(Diags_INFO | Diags_USER6, "Pre-allocating msgs to EVEs...");
        for (i = 0; i < num_eve_devices; i++)
        {
            for (j = 0; j < MAX_NUM_COMPLETION_PENDING; j++)
            {
                eve_ocl_msgq_pkt[i][j] = (ocl_msgq_message_t *)
                    MessageQ_alloc(XDC_CFG_HeapID_Eve, sizeof(ocl_msgq_message_t));
                if (eve_ocl_msgq_pkt[i][j] == NULL)
                {
                     Log_print2(Diags_INFO | Diags_USER6,
                                "Failed to pre-allocate msgs for EVE: %d, %d",
                                i, j);
                     return;
                }
            }
            eve_ocl_msgq_avail_slot[i] = 0;
        }
        Log_print0(Diags_INFO | Diags_USER6,
                   "Done  runtime initialization. Waiting for messages...");
    
        /* EVE attachments finished, enable IPU IPC power management */
        eve_work_count = 0;
    
        /* Loop forever, proxying between host and EVE */
        while (TRUE) {
            status = MessageQ_get(eveProxyQueue, (MessageQ_Msg *)&ocl_msgq_pkt,
                                  MessageQ_FOREVER);
            if (status < 0)  break;
    
            if ((ocl_msgq_pkt->message.command & EVE_MSG_COMMAND_MASK) == 0)
            {
                /* From host, command is not masked */
                /* Allocate msg to EVE */
                int eve_id = ocl_msgq_pkt->message.core_id;
                int slot   = eve_ocl_msgq_avail_slot[eve_id];
                ocl_msgq_message_t* eve_pkt = eve_ocl_msgq_pkt[eve_id][slot];
                slot += 1;
                eve_ocl_msgq_avail_slot[eve_id] =
                                   (slot == MAX_NUM_COMPLETION_PENDING) ? 0 : slot;
    
                /* Copy host_msg into EVE msg, mask command, remember host_msg */
                memcpy(&eve_pkt->message, &ocl_msgq_pkt->message, sizeof(Msg_t));
                eve_pkt->message.command |= EVE_MSG_COMMAND_MASK;
                eve_pkt->message.pid = (uint32_t)ocl_msgq_pkt;
                MessageQ_setReplyQueue(eveProxyQueue, (MessageQ_Msg) eve_pkt);
                MessageQ_put(eveQueues[eve_id], (MessageQ_Msg) eve_pkt);
                eve_work_count += 1;
            }
            else
            {
                /* From EVE, command is masked */
                /* Retrieve original host_msg, unmask command, restore pid */
                ocl_msgq_message_t* host_ocl_msgq_pkt = (ocl_msgq_message_t*)
                                                        ocl_msgq_pkt->message.pid;
                MessageQ_QueueId hostReplyQueue = MessageQ_getReplyQueue(
                                                                host_ocl_msgq_pkt);
                ocl_msgq_pkt->message.command &= (~EVE_MSG_COMMAND_MASK);
                ocl_msgq_pkt->message.pid = host_ocl_msgq_pkt->message.pid;
    
                if (ocl_msgq_pkt->message.command != PRINT)
                {
                    /* Use original host_msg to send back to host */
                    memcpy(&host_ocl_msgq_pkt->message,
                           &ocl_msgq_pkt->message, sizeof(Msg_t));
                    MessageQ_put(hostReplyQueue, (MessageQ_Msg) host_ocl_msgq_pkt);
                    eve_work_count -= 1;
                }
                else
                {
                    /* Allocate a new message for printf to send back to host */
                    ocl_msgq_message_t * host_print_pkt = (ocl_msgq_message_t *)
                    MessageQ_alloc(XDC_CFG_HeapID_Host, sizeof(ocl_msgq_message_t));
                    if (host_print_pkt != NULL)
                    {
                        memcpy(&host_print_pkt->message,
                               &ocl_msgq_pkt->message, sizeof(Msg_t));
                        MessageQ_put(hostReplyQueue, (MessageQ_Msg) host_print_pkt);
                    }
                    else
                        Log_print0(Diags_INFO | Diags_USER6,
                                   "msgq alloc failed for print");
                    MessageQ_free((MessageQ_Msg) ocl_msgq_pkt);
                }
            }
        }  /* while (TRUE) */
    
        Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
        return;
    }
    
    /*
     *  Create M4 proxy message queues for EVEs. Returns false if fails.
     */
    static bool create_mqueue()
    {
        MessageQ_Params msgqParams;
    
        /* Create DSP message queue (inbound messages from ARM) */
        MessageQ_Params_init(&msgqParams);
        eveProxyQueue = MessageQ_create((String)"OCL:EVEProxy:MsgQ", &msgqParams);
    
        if (eveProxyQueue == NULL)
        {
            Log_print0(Diags_INFO | Diags_USER6,
                       "create_mqueue: EVE Proxy MessageQ creation failed");
            return false;
        }
        Log_print1(Diags_INFO | Diags_USER6,
                   "%s ready", (xdc_IArg) "OCL:EVEProxy:MsgQ");
    
        /* get the SR_0 heap handle */
        IHeap_Handle heap = (IHeap_Handle) SharedRegion_getHeap(0);
        if (heap == NULL) {
            Log_print0(Diags_INFO | Diags_USER6, "SharedRegion getHeap failed\n" );
            return false;
        }
        /* Register this heap with MessageQ for communicating with EVE */
        Int status = MessageQ_registerHeap(heap, XDC_CFG_HeapID_Eve);
        Log_print0(Diags_INFO | Diags_USER6, "Heap for EVE ready");
    
        return true;
    }
    
    #undef  CTRL_WKUP_STD_FUSE_DIE_ID_2
    #define CTRL_WKUP_STD_FUSE_DIE_ID_2  0x4AE0C20C
    static int  GetNumEVEDevices()
    {
        uint32_t board_type = (  *((uint32_t *) CTRL_WKUP_STD_FUSE_DIE_ID_2)
                               & 0xFF000000) >> 24;
        int      num_eves = 0;
        if (     board_type == 0x3E ||  // AM5729-E (EtherCat)
                 board_type == 0x4E)    // AM5729
            num_eves = 4;
        else if (board_type == 0x5F ||  // AM5749-E (EtherCat)
                 board_type == 0xA6 ||  // AM5749
                 board_type == 0x69)    // AM5749IDK (shown on package sticker)
                                        // (data sheet: 0x69 is Jacinto 6 Plus)
            num_eves = 2;
    
        Log_print1(Diags_INFO | Diags_USER6, "%d EVEs Available", num_eves);
        if (num_eves > MAX_NUM_EVES)
        {
            num_eves = MAX_NUM_EVES;
            Log_print1(Diags_INFO | Diags_USER6, "Capped to %d (max) EVEs",
                       num_eves);
        }
        return num_eves;
    }
    
    
    /*
     *  Only suspend IPU when there are no work on EVEs, otherwise, messages
     *      from EVE won't be able to wake up IPU
     */
    extern void IpcPower_idle();
    void OclPower_idle()
    {
        if (eve_work_count <= 0)
            IpcPower_idle();
    }
    

    Main.c calls this utils_eveBoot function.

    #include "stdint.h"
    #include <ti/drv/pm/pmhal.h>
    #include "utils_eveloader.h"
    
    /*******************************************************************************
     *  GLOBAL VARIABLES
     *******************************************************************************
    */
    
    /*
     * Variable for version 1 of Meta Header structure
     */
    sbllibMetaHeaderV1_t    gUtilsAppMetaHeaderV1;
    
    /*
     * Variable for RPRC Header structure
     */
    sbllibRPRCImageHeader_t gUtilsAppRPRCHeader;
    
    /*
     * Variable for Entry points
     */
    sbllibEntryPoints_t gUtilsEntryPoints =
    {{0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U}};
    
    
    /*******************************************************************************
     *  FUNCTION DEFINITIONS
     *******************************************************************************
    */
    
    /**
     * \brief   This function acts as a wrapper for Print function.
     *
     * \param   message       Message to be printed.
     *
     * \return  None.
     */
    void Utils_eveLoaderPrintFxn(const char *message)
    {
        Vps_printf(message);
    }
    
    /**
     * \brief   Override weak definition of vectable page mask in sbl_lib.
     *
     * OpenCL Memory Map Requirement: Use 1MB vector table page alignment to
     * reduce memory usage for EVEs.  In fact, we can reuse part of the CMEM
     * memory that we previously reserved for OpenCL DSP runtime.
     * For this to work, entryPoint must be placed in the same 1MB page as
     * the vector table, so that we can correctly derive vector table address
     * from the entry point address.  This can be achieved by user application
     * in linker command file placement.
     * For example, if entryPoint is _c_int00, assuming that vector table
     * memory is large enough to hold _c_int00 as well (vector table is
     * usually very small, about 64 bytes), then add to linker command file:
     *     SECTIONS
     *     {
     *       .entry_point_page
     *       {
     *         * (.vecs)
     *         * (.text:_c_int00)
     *       } align = 0x100000 > EVE_VECS_MEM PAGE 1
     *     }
     *
     * \return  EVE vector table page mask.
     */
    uint32_t SBLLibEVEGetVecTablePageMask()
    {
        return 0xFFF00000U;
    }
    
    /**
     *******************************************************************************
     *
     * \brief Boots Eves with AppImage
     *
     *
     * \return SYSTEM_LINK_STATUS_SOK on success, else failure
     *
     *******************************************************************************
     */
    Int32 Utils_eveBoot(Int32 num_eve_devices)
    {
        Int32 retVal = SYSTEM_LINK_STATUS_SOK;
        UInt32 sblBuildMode = SBLLIB_SBL_BUILD_MODE_PROD;
        sbllibAppImageParseParams_t appImgParams;
        pmhalPrcmDpllConfig_t      *dpllParams;
    
        pmhalPrcmSysClkVal_t sysClkFreq = PMHALCMGetSysClockFreqEnum();
    
        sbllibInitParams_t sblInitPrms;
        UInt32 oppId, multVal, dspMultVal, dspDivVal;
    
        /* Default initialization of SBL Lib Params */
        SBLLibInitParamsInit(&sblInitPrms);
    
    
    
        /* Assign SBL Params */
        sblInitPrms.printFxn = &Utils_eveLoaderPrintFxn;
        SBLLibInit(&sblInitPrms);
    
        /* Configure DPLL EVE if it is not already configured, e.g. by u-boot */
        multVal = PMHALCMDpllGetMultiplier(PMHAL_PRCM_DPLL_EVE);
        if (multVal == 0U)
        {
    
            oppId = SBLLIB_PRCM_DPLL_OPP_HIGH;
    #if 0   /* Now: IPU1 gets early boot before DSP frequency is configured, */
            /* which happens at the end of u-boot, just before starting kernel. */
            /* if DPLL DSP in OPP_NOM 600MHz, use OPP_NOM for EVE as well */
            dspMultVal = PMHALCMDpllGetMultiplier(PMHAL_PRCM_DPLL_DSP);
            dspDivVal  = PMHALCMDpllGetDivider(PMHAL_PRCM_DPLL_DSP);
            if ((20U * dspMultVal / (dspDivVal + 1U)) <= 600U)  /* 20MHz sys_clk */
                oppId = SBLLIB_PRCM_DPLL_OPP_NOM;
    #endif
    
            retVal = SBLLibGetDpllStructure(PMHAL_PRCM_DPLL_EVE,
                                             sysClkFreq,
                                             oppId,
                                             &dpllParams);
     
            retVal += PMHALCMDpllConfigure(PMHAL_PRCM_DPLL_EVE,
                                           dpllParams,
                                           PM_TIMEOUT_INFINITE);
    
    
            if (SYSTEM_LINK_STATUS_SOK != retVal)
            {
    
                Vps_printf("\n EVELOADER: DPLL EVE not configured Correctly \n");
                SBLLibAbortBoot();
            }
        }
    
    
        /* Reset all EVEs */
        Utils_resetAllEVECores(num_eve_devices);
    
    
        /* Initialize App Image Params */
        SBLLibAppImageParamsInit(&appImgParams);
    
    
        appImgParams.appImgMetaHeaderV1 = &gUtilsAppMetaHeaderV1;
        appImgParams.appImgRPRCHeader   = &gUtilsAppRPRCHeader;
        appImgParams.entryPoints        = &gUtilsEntryPoints;
        appImgParams.skipDDRCopy        = 1U;
    
        Utils_loadAppImage(&appImgParams, num_eve_devices);
    
    
    #ifdef PROC_EVE1_INCLUDE
        if (num_eve_devices >= 1)
            SBLLibEVE1BringUp(gUtilsEntryPoints.entryPoint[SBLLIB_CORE_ID_EVE1],
                              sblBuildMode);
    
    
    #endif
    #ifdef PROC_EVE2_INCLUDE
        if (num_eve_devices >= 2)
            SBLLibEVE2BringUp(gUtilsEntryPoints.entryPoint[SBLLIB_CORE_ID_EVE2],
                              sblBuildMode);
    
    
    #endif
    #ifdef PROC_EVE3_INCLUDE
        if (num_eve_devices >= 3)
            SBLLibEVE3BringUp(gUtilsEntryPoints.entryPoint[SBLLIB_CORE_ID_EVE3],
                              sblBuildMode);
    
    
    #endif
    #ifdef PROC_EVE4_INCLUDE
        if (num_eve_devices >= 4)
            SBLLibEVE4BringUp(gUtilsEntryPoints.entryPoint[SBLLIB_CORE_ID_EVE4],
                              sblBuildMode);
    
    
    #endif
    
        return retVal;
    }
    

    The utils_eveBoot function calls the Utils_resetAllEveCores function, which uses the API's SBLLibCPUReset function.

    #include <stdint.h>
    #include "utils_eveloader.h"
    #include <ti/csl/hw_types.h>
    #include <ti/csl/soc.h>
    #include <ti/drv/pm/pmhal.h>
    
    /****************************************************************
     *  GLOBAL VARIABLES
     ****************************************************************/
    #ifdef IPU1_LOAD_EVES
    /* This expected to be defined in IPU1 application */
    extern unsigned char gTDA2XX_EVE_FIRMWARE;
    #endif
    
    /****************************************************************
     *  FUNCTION DEFINITIONS
     ****************************************************************/
    
    /**
     * \brief   This function copies data from DDR
     *
     * \param   dstAddr       Destination Address
     * \param   srcOffsetAddr NOR Source Offset Address
     * \param   length        The length of data block to be copied.
     *
     * \return  status        Whether copy is done successfully.
     */
    Int32 Utils_ddr3ReadLocal(void    *dstAddr,
                              UInt32 srcOffsetAddr,
                              UInt32 length)
    {
        memcpy((UInt32 *)dstAddr, (UInt32 *)srcOffsetAddr, length);
    
        return 0;
    }
    
    /**
     * \brief   This function moves the read head by n bytes.
     *
     * \param   srcAddr     Read head pointer.
     * \param   numBytes    Number of bytes of data by which read head is moved.
     *
     * \return  None
     */
    void Utils_ddr3Seek(UInt32 *srcAddr, UInt32 numBytes)
    {
        *(srcAddr) = numBytes;
    }
    
    /**
     * \brief   This is a dummy DDR copy function. TDA2xx SOC family doesn't have
     *          CRC feature and hence data is directly read from boot media.
     *
     * \param   dstAddr   Destination Address
     * \param   srcAddr   DDR Source Address
     * \param   length    The length of data block to be copied.
     *
     * \return  status    Whether data is copied correctly
     */
    Int32 Utils_dummyDDRRead(void   *dstAddr,
                             UInt32  srcAddr,
                             UInt32  length)
    {
        Int32 retVal = 0;
    
        /* This is dummy function */
        return retVal;
    }
    
    Int32 Utils_loadAppImage(sbllibAppImageParseParams_t *imageParams,
                             Int32 num_eve_devices)
    {
        /* Restrict loader to only load num_eve_devices EVE images,
           firmware may contain more EVE images than available EVEs,
           e.g. firmware has 4 EVE images, AM574x only has 2 EVEs */
        Int32 numFiles = ((sbllibMetaHeaderStartV1_t *) (&gTDA2XX_EVE_FIRMWARE))
                         ->numFiles;
        Int32 fileNo;
        for (fileNo = num_eve_devices; fileNo < numFiles; fileNo++)
        {
            sbllibMetaHeaderCoreV1_t *metaCore = ((sbllibMetaHeaderCoreV1_t *)
                                     (&gTDA2XX_EVE_FIRMWARE +
                                      sizeof(sbllibMetaHeaderStartV1_t) +
                                      sizeof(sbllibMetaHeaderCoreV1_t) * fileNo));
            /* Set coreId to 0xFFFFFFFFU so that loader won't load them */
            /* See SBLLibMultiCoreImageParseV1() in sbl_lib_tda2xx_platform.c */
            metaCore->coreId = 0xFFFFFFFFU;
        }
    
        imageParams->appImageOffset = (UInt32) &gTDA2XX_EVE_FIRMWARE;
    
        SBLLibRegisterImageCopyCallback(&Utils_ddr3ReadLocal,
                                        &Utils_dummyDDRRead,
                                        &Utils_ddr3Seek);
    
        return (SBLLibMultiCoreImageParseV1(imageParams));
    }
    
    void Utils_resetAllEVECores(Int32 num_eve_devices)
    {
        Int32 retVal = SYSTEM_LINK_STATUS_SOK;
    
        /* Enable EVE clock domains */
        if (num_eve_devices >= 1)
            retVal = PMHALCMSetCdClockMode(
                (pmhalPrcmCdId_t) PMHAL_PRCM_CD_EVE1,
                (pmhalPrcmCdClkTrnModes_t) PMHAL_PRCM_CD_CLKTRNMODES_SW_WAKEUP,
                PM_TIMEOUT_NOWAIT);
            
        if (num_eve_devices >= 2)
            retVal += PMHALCMSetCdClockMode(
                (pmhalPrcmCdId_t) PMHAL_PRCM_CD_EVE2,
                (pmhalPrcmCdClkTrnModes_t) PMHAL_PRCM_CD_CLKTRNMODES_SW_WAKEUP,
                PM_TIMEOUT_NOWAIT);
    
        
        if (num_eve_devices >= 3)
            retVal += PMHALCMSetCdClockMode(
                (pmhalPrcmCdId_t) PMHAL_PRCM_CD_EVE3,
                (pmhalPrcmCdClkTrnModes_t) PMHAL_PRCM_CD_CLKTRNMODES_SW_WAKEUP,
                PM_TIMEOUT_NOWAIT);
    
        
        if (num_eve_devices >= 4)
            retVal += PMHALCMSetCdClockMode(
                (pmhalPrcmCdId_t) PMHAL_PRCM_CD_EVE4,
                (pmhalPrcmCdClkTrnModes_t) PMHAL_PRCM_CD_CLKTRNMODES_SW_WAKEUP,
                PM_TIMEOUT_NOWAIT);
    
        /* Enable EVE modules */
        if (num_eve_devices >= 1)
            retVal += PMHALModuleModeSet(
                (pmhalPrcmModuleId_t) PMHAL_PRCM_MOD_EVE1,
                (pmhalPrcmModuleSModuleMode_t) PMHAL_PRCM_MODULE_MODE_AUTO,
                PM_TIMEOUT_INFINITE);
       
    
        if (num_eve_devices >= 2)
            retVal += PMHALModuleModeSet(
                (pmhalPrcmModuleId_t) PMHAL_PRCM_MOD_EVE2,
                (pmhalPrcmModuleSModuleMode_t) PMHAL_PRCM_MODULE_MODE_AUTO,
                PM_TIMEOUT_INFINITE);
    
        if (num_eve_devices >= 3)
            retVal += PMHALModuleModeSet(
                (pmhalPrcmModuleId_t) PMHAL_PRCM_MOD_EVE3,
                (pmhalPrcmModuleSModuleMode_t) PMHAL_PRCM_MODULE_MODE_AUTO,
                PM_TIMEOUT_INFINITE);
    
        if (num_eve_devices >= 4)
            retVal += PMHALModuleModeSet(
                (pmhalPrcmModuleId_t) PMHAL_PRCM_MOD_EVE4,
                (pmhalPrcmModuleSModuleMode_t) PMHAL_PRCM_MODULE_MODE_AUTO,
                PM_TIMEOUT_INFINITE);
    
        if (SYSTEM_LINK_STATUS_SOK != retVal)
        {
            Vps_printf("\n UTILS: EVELOADER: EVE PRCM Failed \n");
        }
    
        /* Reset EVE1 */
        if (num_eve_devices >= 1)
            SBLLibCPUReset(SBLLIB_CORE_ID_EVE1);
    
        /* Reset EVE2 */
        if (num_eve_devices >= 2)
            SBLLibCPUReset(SBLLIB_CORE_ID_EVE2);
    
    
    
    
        /* Reset EVE3 */
        if (num_eve_devices >= 3)
            SBLLibCPUReset(SBLLIB_CORE_ID_EVE3);
    
    
        /* Reset EVE4 */
        if (num_eve_devices >= 4)
            SBLLibCPUReset(SBLLIB_CORE_ID_EVE4);
    
    
    }
    
    

  • Hi Parth,

    This is the values from registers that we read:

    AM5729 00000337 00000000 00000000 00000000 PM_IPU_PWRSTST 0x4AE06504
    00000000 00000000 00000000 00000000 PM_EVE1_PWRSTST 0X4AE07B44
    00000000 00000000 00000000 00000003 PM_DSP1_PWRSTST 0X4AE06404
  • Hi Parth,

    Does anything seem strange in the code?

  • Hi,

    .My code starts immediately after u-boot and EVEs need to be reset.

    Would you please confirm if you are using PROCESSOR-SDK-LINUX-AM57X or PROCESSOR-SDK-RTOS-AM57X? and which boot flow using here?

    Regards,

    Karthik