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.

AM2634: AM2634 how to started Core2 by Core0 without bootloader and image?

Part Number: AM2634


Tool/software:

Hi!

Can I boot Core2 directly from Core0 by setting Core2 entry address in Core2's TCM memory without the bootloader and image?

I want to use the Core0 function as the entry address for Core2,my code looks like this:

#include <stdio.h>
#include <string.h>
#include <drivers/ipc_rpmsg.h>
#include <drivers/bootloader.h>

#define LOG_TAG  ""
#include "elog.h"

#define IPC_TEST_REMOTE_CORE    CSL_CORE_ID_R5FSS1_0

Bootloader_socCoreOpModeConfig socCoreOpMode =
{
     .r5fss0_opMode = BOOTLOADER_OPMODE_STANDALONE,
     .r5fss1_opMode = BOOTLOADER_OPMODE_STANDALONE
};

volatile uint8_t remote_start_flag = 0x00;

void ipc_remote_core_main()
{
    remote_start_flag = 0x01;

    while(1)
    {

    }
}

void exception_handler()
{
    remote_start_flag = 0x02;

    while(1)
    {

    }
}

uint32_t tcm_memory_data[] =
{
     0xE5FF9018,0xE5FF9018,
     0xE5FF9018,0xE5FF9018,
     0xE5FF9018,0xE5FF9018,
     0xE5FF9018,0xE5FF9018,

     /* 向量表 */
     (uint32_t)ipc_remote_core_main,  // entry
     (uint32_t)&exception_handler,    // undefined
     (uint32_t)&exception_handler,    // svc
     (uint32_t)&exception_handler,    // prefetch
     (uint32_t)&exception_handler,    // data abort
     (uint32_t)&exception_handler,    // reserved
     (uint32_t)&exception_handler,    // irq
     (uint32_t)&exception_handler,    // fiq
};

void ipc_remote_core_start()
{
    uint8_t i = 0;
    int32_t status;

    Bootloader_Handle gBootloaderHandle;
    Bootloader_CpuInfo gBootImageInfo;

    gBootImageInfo.cpuId = IPC_TEST_REMOTE_CORE;
    gBootImageInfo.clkHz = Bootloader_socCpuGetClkDefault(IPC_TEST_REMOTE_CORE);

    status = Bootloader_socCpuSetClock(gBootImageInfo.cpuId, gBootImageInfo.clkHz);

    if(status != SystemP_SUCCESS)
    {
        log_i("Bootloader_socCpuSetClock failed\r\n");
        return;
    }

    status = Bootloader_socCpuPowerOnReset(IPC_TEST_REMOTE_CORE, &socCoreOpMode);

    if(status != SystemP_SUCCESS)
    {
        log_i("Bootloader_socCpuPowerOnReset failed\r\n");
        return;
    }

    uint32_t *tcm_memory_addr = (uint32_t *)0x78400000;

    for(i = 0; i < (sizeof(tcm_memory_data) / sizeof(tcm_memory_data[0])); i++)
    {
        *tcm_memory_addr++ = tcm_memory_data[i];
    }

    status = Bootloader_runCpu(NULL, &gBootImageInfo);

    if(status == SystemP_SUCCESS)
    {
        log_i("core(%d) start success\r\n", IPC_TEST_REMOTE_CORE);
    }
    else
    {
        log_i("core(%d) start failed\r\n", IPC_TEST_REMOTE_CORE);
    }
}

I hope that when Core2 is started, ipc_remote_core_main can be executed to change the variable remote_start_flag to 1, which is the basis for judging the success of Core2 startup, but after running, it is found that remote_start_flag is still 0, Core2 startup fails.

Is my idea feasible? How can I modify my code?

Thanks.

  • Hi,

    Where are you keeping the image for core 2? Is SBL running on core0 copying that to TCM?

  • Hi,

    Maybe I didn't express myself clearly. Let me be as detailed as I can.

    I want to give Core0 functions to Core2 to run, I don't know whether this can be achieved?

    The overall process is as follows:

    1. All of the code provided above is Core0 code,I want to give the following function (ipc_remote_core_main) to Core2 to run.

    void ipc_remote_core_main()
    {
        remote_start_flag = 0x01;
    
        while(1)
        {
    
        }
    }


    2. I manually built the vector table for Core2 (modeled after the first Section of the RPRC file), as shown below:

    uint32_t tcm_memory_data[] =
    {
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
    
         /* 向量表 */
         (uint32_t)&ipc_remote_core_main, // entry point
         (uint32_t)&exception_handler,    // undefined
         (uint32_t)&exception_handler,    // svc
         (uint32_t)&exception_handler,    // prefetch
         (uint32_t)&exception_handler,    // data abort
         (uint32_t)&exception_handler,    // reserved
         (uint32_t)&exception_handler,    // irq
         (uint32_t)&exception_handler,    // fiq
    };

    3. Then I copied the way the bootloader started the kernel, and i Instead of loading RPRC with mine code.

    as shown below,you can see that I executed Bootloader_socCpuPowerOnReset to initialize TCM memory, wrote the Core2 vector table to 0x74800000, and then Bootloader_runCpu to start Core2.

    void ipc_remote_core_start()
    {
        uint8_t i = 0;
        int32_t status;
    
        Bootloader_Handle gBootloaderHandle;
        Bootloader_CpuInfo gBootImageInfo;
    
        gBootImageInfo.cpuId = IPC_TEST_REMOTE_CORE;
        gBootImageInfo.clkHz = Bootloader_socCpuGetClkDefault(IPC_TEST_REMOTE_CORE);
    
        status = Bootloader_socCpuSetClock(gBootImageInfo.cpuId, gBootImageInfo.clkHz);
    
        if(status != SystemP_SUCCESS)
        {
            log_i("Bootloader_socCpuSetClock failed\r\n");
            return;
        }
    
        status = Bootloader_socCpuPowerOnReset(IPC_TEST_REMOTE_CORE, &socCoreOpMode);
    
        if(status != SystemP_SUCCESS)
        {
            log_i("Bootloader_socCpuPowerOnReset failed\r\n");
            return;
        }
    
        uint32_t *tcm_memory_addr = (uint32_t *)0x78400000;
    
        for(i = 0; i < (sizeof(tcm_memory_data) / sizeof(tcm_memory_data[0])); i++)
        {
            *tcm_memory_addr++ = tcm_memory_data[i];
        }
    
        status = Bootloader_runCpu(NULL, &gBootImageInfo);
    
        if(status == SystemP_SUCCESS)
        {
            log_i("core(%d) start success\r\n", IPC_TEST_REMOTE_CORE);
        }
        else
        {
            log_i("core(%d) start failed\r\n", IPC_TEST_REMOTE_CORE);
        }
    }

    Thanks.

  • Hi ,

    The core booting is done by SBL and if your intention is to just boot core 2 only then it would make sense to create a application image which contains binary of core 2 this way SBL itself would boot the second core.

  • Hi,Nilablh Anand.

    Maybe I haven't been clear enough.

    I don't want to launch Core2 through SBL, I want to launch Core2 through Core0 application, so can I customize Core2 vector table, then launch Core2 and run the vector table 0x00 function?

    I mean is the first function that the kernel runs after startup on the vector table 0x00 in TCM memory? Can I set the function to Core2's Vector Table 0x00, then restart Core2 and Core2 will execute the function?

    Thanks.

  • Hi Nilabh Anand.

    As shown below, I write tcm_memory_data to 0x78400000 (Core2 TCM) and then start Core2. My expectation is that Core2 will execute the table mount ipc_remote_core_main function when it starts

    /*  This table -> Write to Core2 TCM memory */
    uint32_t tcm_memory_data[] =
    {
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
         0xE5FF9018,0xE5FF9018,
    
         /* vector table */
         (uint32_t)&ipc_remote_core_main, // entry point?
         (uint32_t)&exception_handler,    // undefined
         (uint32_t)&exception_handler,    // svc
         (uint32_t)&exception_handler,    // prefetch
         (uint32_t)&exception_handler,    // data abort
         (uint32_t)&exception_handler,    // reserved
         (uint32_t)&exception_handler,    // irq
         (uint32_t)&exception_handler,    // fiq
    };
        
        
    uint32_t *tcm_memory_addr = (uint32_t *)0x78400000;
    
    for(i = 0; i < (sizeof(tcm_memory_data) / sizeof(tcm_memory_data[0])); i++)
    {
        *tcm_memory_addr++ = tcm_memory_data[i];
    }

  • Hi 

    The approach should be feasible. As long as the you are ensuing the program loaded on TCM is correct.

  • Hi Nilabh Anand.

     Can you provide me with relevant routines, I do not know the internal mechanism of the chip, I do not know where my code is wrong.

    Thanks.

  • You can check for the relevant routine from the SBL QSPI routine, this is available in SDK at : 

    mcu_plus_sdk\examples\drivers\boot\sbl_qspi\am263x-lp\r5fss0-0_nortos\main.c