AM62P: Fast boot time KPI: unexpected time delay in ROM boot

Part Number: AM62P
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi,

I want to achieve the fast boot in WKUP core and measured the corresponding time slots. The time measurement results is attached below.

Referring to your internal manual "Boot Time KPIs" for AM62P, the ROM boot time consumes 30ms and there is a huge gap between TI's measurements and our measurements. I want to know the reason about this and whether we could optimize the boot time KPI during ROM boot. The boot mode we use is OSPI. 

  

BR,

Bomiao

  • Hi Bomiao,

    I can do a test at my end to verify this,  could you let me know a few things:

    1. What is the size of SBL Stage1 image here?

    2. Just for a confirmation, is your SoC in OSPI boot mode or the xSPI boot mode?

    Best Regards,

    Meet.

  • Hi Meet

    1. The size of SBL1 Stage 1 image is 381kb.

    2. I think the boot mode is OSPI NOR, referring to MCU_SDK tutorial.

    BR,

    Bomiao

  • Hi Bomiao,

    Please allow me sometime to run a test at my end, and check if I can reproduce these results, please expect a response by mid of this week.

    Best Regards,

    Meet.

  • Hi Bomiao,

    Apologies for the delay, I tested this at my end, and the results are as expected. I get the ROM execution time of 30ms as mentioned in the documentation:

    I followed this method to measure this: https://software-dl.ti.com/processor-sdk-linux/esd/AM62PX/11_01_16_13/exports/docs/linux/How_to_Guides/Target/How_to_boot_quickly.html#measurements

    Are you testing this on TI EVM or the custom board? 

    If you are using a custom board, then what is the flash part installed on it?

    Best Regards,

    Meet.

  • Hi Meet,

    I have done the test on TI EVM and our measurement is about 73ms, based on the tutorial you provided above. 

    The previous measurement on our custom board is about 79ms and the NOR FLASH we used on our custom board is S28HS512T, same as EVM.

    I also followed the method you have mentioned above and I attach the code for sbl_ospi_stage 1 below. I wonder whether I need some additional adjustments on Sysconfig. I would really appreciate if you could share your source code or binary for sbl_ospi_stage 1 and we could do the test on our EVM.

    BR,

    Bomiao

    #include <stdlib.h>
    #include "drivers/gpio/v0/gpio.h"
    #include "drivers/pinmux/am62px/pinmux.h"
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <drivers/device_manager/sciclient.h>
    #include <drivers/bootloader.h>
    #include <drivers/pinmux.h>
    #include <drivers/gtc.h>
    #include <sdl/include/sdl_types.h>
    #include <sdl/dpl/sdl_dpl.h>
    #include <sdl/sdl_pbist.h>
    #include <sdl/sdl_lbist.h>
    
    
    #include <drivers/gpio.h>
    
    
    #define CONFIG_BOOT_TIME_OPTIMZE_ON (1)
    #define CONFIG_BOOT_TIME_MEASURE_ON (1)
    
    
    #if CONFIG_BOOT_TIME_MEASURE_ON
    /* GPIO PIN Macros */
    #define CONFIG_GPIO0_BASE_ADDR (CSL_MCU_GPIO0_BASE)
    #define CONFIG_GPIO0_PIN (18)
    #define CONFIG_GPIO0_DIR (GPIO_DIRECTION_OUTPUT)
    #define CONFIG_GPIO0_TRIG_TYPE (GPIO_TRIG_TYPE_NONE)
    #define CONFIG_GPIO_NUM_INSTANCES (1U)
    
    static Pinmux_PerCfg_t gPinMuxMcuCfg[] = {
        /* MCU_GPIO0 pin config MCU_GPIO0_17 -> MCU_I2C0_SCL (E11) */
        {
            PIN_MCU_I2C0_SDA,
            ( PIN_MODE(7) | PIN_INPUT_ENABLE | PIN_PULL_DISABLE )
        },
        {PINMUX_END, PINMUX_END}
    };
    
    #endif
    
    
    /*  In this sample bootloader, we load appimages for RTOS/Baremetal and Linux at different offset
        i.e the appimage for Linux (for A53) and RTOS/Baremetal (for R5, MCU R5) is flashed at different offset in flash
    
        Here at one flash offset, there is a multi-core .appimage that holds RPRC for MCU R5 and R5
        and another .appimage that holds the linux binaries(ATF, OPTEE, A53-SPL) at another offset.
    
        When flashing make sure to flash images to below offset using the flash tool.
    
        RTOS/Baremetal appimage (MCU R5 cores) flash at offset 0x100000 of flash
        Linux appimage (for A53) flash at offset 0xC00000 of flash
    */
    
    /*
     * Timeout for the PBIST/LBIST completion
     */
    #define SDL_BIST_MAX_TIMEOUT_VALUE       (10000000u)
    
    /* Enable/Disable MCU LBIST on SBL */
    #define ENABLE_MCU_LBIST                 (0u)
    
    void flashFixUpOspiBoot(OSPI_Handle oHandle, Flash_Handle fHandle);
    
    /* This buffer needs to be defined for OSPI nand boot in case of HS device for
       image authentication
       The size of the buffer should be large enough to accomodate the appimage */
    uint8_t gAppimage[0x800000] __attribute__ ((section (".bss.app"), aligned (128)));
    
    /* call this API to stop the booting process and spin, do that you can connect
     * debugger, load symbols and then make the 'loop' variable as 0 to continue execution
     * with debugger connected.
     */
    void loop_forever()
    {
        volatile uint32_t loop = 1;
        while(loop)
            ;
    }
    
    int32_t App_loadSelfcoreImage(Bootloader_LoadImageParams *bootLoadParams)
    {
    	int32_t status = SystemP_FAILURE;
    
        if(bootLoadParams->bootHandle != NULL)
        {
            status = Bootloader_parseMultiCoreAppImage(bootLoadParams->bootHandle, &bootLoadParams->bootImageInfo);
    
            if(status == SystemP_SUCCESS)
            {
                (&bootLoadParams->bootImageInfo)->cpuInfo[CSL_CORE_ID_WKUP_R5FSS0_0].clkHz = Bootloader_socCpuGetClkDefault(CSL_CORE_ID_WKUP_R5FSS0_0);
    #if   (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
                Bootloader_profileAddCore(CSL_CORE_ID_WKUP_R5FSS0_0);
    #endif
                status = Bootloader_loadSelfCpu(bootLoadParams->bootHandle, &((&bootLoadParams->bootImageInfo)->cpuInfo[CSL_CORE_ID_WKUP_R5FSS0_0]));
            }
        }
    
        return status;
    }
    
    int32_t App_boardDriversOpen()
    {
        int32_t status = SystemP_SUCCESS;
    
        gFlashHandle[CONFIG_FLASH_SBL] = Flash_open(CONFIG_FLASH_SBL, &gFlashParams[CONFIG_FLASH_SBL]);
        if(NULL == gFlashHandle[CONFIG_FLASH_SBL])
        {
            DebugP_logError("FLASH open failed for instance %d !!!\r\n", CONFIG_FLASH_SBL);
            status = SystemP_FAILURE;
        }
    
        return status;
    }
    
    void App_driversOpen()
    {
        gOspiHandle[CONFIG_OSPI_SBL] = OSPI_open(CONFIG_OSPI_SBL, &gOspiParams[CONFIG_OSPI_SBL]);
        if(NULL == gOspiHandle[CONFIG_OSPI_SBL])
        {
            DebugP_logError("OSPI open failed for instance %d !!!\r\n", CONFIG_OSPI_SBL);
        }
    
        gUartHandle[CONFIG_UART_SBL] = UART_open(CONFIG_UART_SBL, &gUartParams[CONFIG_UART_SBL]);
        if(NULL == gUartHandle[CONFIG_UART_SBL])
        {
            DebugP_logError("UART open failed for instance %d !!!\r\n", CONFIG_UART_SBL);
        }
    }
    
    int32_t App_waitForMcuPbist()
    {
        int32_t status = SystemP_FAILURE;
        int32_t timeoutCount = 0;
    
        if (!Bootloader_socIsMCUResetIsoEnabled())
        {
            /* wait for the PBIST to be completed */
            while(timeoutCount < SDL_BIST_MAX_TIMEOUT_VALUE)
            {
                if(PBIST_DONE == SDL_SBL_PBIST_checkDone(SDL_PBIST_INST_MCU))
                {
                    status = SystemP_SUCCESS;
                    break;
                }
                timeoutCount++;
            }
        }
        else
        {
            status = SystemP_SUCCESS;
        }
    
        return status;
    }
    
    
    int32_t App_startMcuLbist()
    {
        int32_t status = SystemP_FAILURE;
    
        /* Start LBIST if MCU reset isolation is not enabled */
        if (!Bootloader_socIsMCUResetIsoEnabled())
        {
            if (SDL_LBIST_selfTest(LBIST_MCU_R5F, SDL_LBIST_TEST) == SDL_PASS)
            {
                status = SystemP_SUCCESS;
            }
        }
        else
        {
            status = SystemP_SUCCESS;
        }
        return status;
    }
    
    int32_t App_waitForMcuLbist()
    {
        int32_t status = SystemP_FAILURE;
        int32_t timeoutCount = 0;
    
        if (!Bootloader_socIsMCUResetIsoEnabled())
        {
            /* wait for the LBIST to be completed */
            while(timeoutCount < SDL_BIST_MAX_TIMEOUT_VALUE)
            {
                if(LBIST_DONE == SDL_LBIST_checkDone(LBIST_MCU_R5F))
                {
                    status = SystemP_SUCCESS;
                    break;
                }
                timeoutCount++;
            }
    
            if (status == SystemP_SUCCESS)
            {
                status = SDL_LBIST_selfTest(LBIST_MCU_R5F, SDL_LBIST_TEST_RELEASE);
                timeoutCount = 0;
                while(timeoutCount < SDL_BIST_MAX_TIMEOUT_VALUE)
                {
                    if(LBIST_DONE == SDL_LBIST_checkDone(LBIST_MCU_R5F))
                    {
                        status = SystemP_SUCCESS;
                        break;
                    }
                    timeoutCount++;
                }
            }
        }
        else
        {
            status = SystemP_SUCCESS;
        }
    
        return status;
    }
    
    int main()
    {
        int32_t status = SystemP_SUCCESS;
        
    
        // while (status == SystemP_SUCCESS) {
        
        // }
    #if CONFIG_BOOT_TIME_MEASURE_ON
        Pinmux_config(gPinMuxMcuCfg, PINMUX_DOMAIN_ID_MCU); // Configure PinMux
        GPIO_setDirMode(CONFIG_GPIO0_BASE_ADDR, CONFIG_GPIO0_PIN, CONFIG_GPIO0_DIR);    //Set GPIO direction
        GPIO_pinWriteLow(CONFIG_GPIO0_BASE_ADDR, CONFIG_GPIO0_PIN); // Set GPIO state to LOW
    #endif
    
        Bootloader_profileReset();
    
        Bootloader_socWaitForFWBoot();
        status = Bootloader_socOpenFirewalls();
    
        DebugP_assertNoLog(status == SystemP_SUCCESS);
    
        System_init();
        Module_clockSBLEnable();
        Module_clockSBLSetFrequency();
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("System_init");
    #endif
    
    
        /* wait for PBIST completion */
        status = App_waitForMcuPbist();
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("App_waitForMcuPbist");
    #endif
    
    #if (ENABLE_MCU_LBIST == 1u)
        /* start MCU LBIST*/
        status = App_startMcuLbist();
    #endif
        Board_init();
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("Board_init");
    #endif
    
        Drivers_open();
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("Drivers_open");
    #endif
    
        App_driversOpen();
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("SBL Drivers_open");
    #endif
    
        flashFixUpOspiBoot(gOspiHandle[CONFIG_OSPI_SBL], gFlashHandle[CONFIG_FLASH_SBL]);
    
        status = Board_driversOpen();
        DebugP_assert(status == SystemP_SUCCESS);
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("Board_driversOpen");
    #endif
    
        status = App_boardDriversOpen();
        DebugP_assert(status == SystemP_SUCCESS);
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
        Bootloader_profileAddProfilePoint("SBL Board_driversOpen");
    #endif
    
        if(SystemP_SUCCESS == status)
        {
            Bootloader_openDma();
    
            Bootloader_LoadImageParams bootDM;
    
            Bootloader_Params_init(&bootDM.bootParams);
    
            Bootloader_BootImageInfo_init(&bootDM.bootImageInfo);
    
            bootDM.bootHandle = Bootloader_open(CONFIG_BOOTLOADER_FLASH_SBL, &bootDM.bootParams);
    
            if(SystemP_SUCCESS == status)
    		{
                if(bootDM.bootHandle != NULL)
                {
                    ((Bootloader_Config *)bootDM.bootHandle)->scratchMemPtr = gAppimage;
                    status = App_loadSelfcoreImage(&bootDM);
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
                    Bootloader_profileAddProfilePoint("App_loadSelfcoreImage");
    #endif
                }
            }
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
            Bootloader_profileUpdateAppimageSize(Bootloader_getMulticoreImageSize(bootDM.bootHandle));
            Bootloader_profileUpdateMediaAndClk(BOOTLOADER_MEDIA_FLASH, OSPI_getInputClk(gOspiHandle[CONFIG_OSPI_SBL]));
    #endif
    
    #if (ENABLE_MCU_LBIST == 1u)
            /* wait for LBIST completion */
            status = App_waitForMcuLbist();
            Bootloader_profileAddProfilePoint("App_waitForMcuLbist");
    #endif
    
    		if(SystemP_SUCCESS == status)
    		{
    			/* Print SBL log as Linux prints log to the same UART port */
    
    #if (0 == CONFIG_BOOT_TIME_OPTIMZE_ON)
    			Bootloader_profilePrintProfileLog();
    			DebugP_log("Image loading done, switching to application ...\r\n");
    			DebugP_log("Starting 2nd stage bootloader\r\n");
    #endif
    
    			UART_flushTxFifo(gUartHandle[CONFIG_UART_SBL]);
    		}
    
            Bootloader_close(bootDM.bootHandle);
    
            Bootloader_closeDma();
        }
    
        if(status != SystemP_SUCCESS )
        {
            DebugP_log("SBL stage 1 failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    
        /* Call DPL deinit to close the tick timer and disable interrupts before jumping to Stage2*/
        Dpl_deinit();
    
        Bootloader_socWriteSBLBootMagicNum();
        
    #if CONFIG_BOOT_TIME_MEASURE_ON
        GPIO_pinWriteHigh(CONFIG_GPIO0_BASE_ADDR, CONFIG_GPIO0_PIN); // Set GPIO state to HIGH
    #endif
    
        Bootloader_JumpSelfCpu();
    
        Board_deinit();
        System_deinit();
    
        return 0;
    }
    
    void flashFixUpOspiBoot(OSPI_Handle oHandle, Flash_Handle fHandle)
    {
        /*
         *  In Fast XSPI mode, reintialization is not required unless
         *  user configures it or PHY configuration failed
         */
        if(SystemP_SUCCESS != OSPI_skipTuning(oHandle))
        {
            OSPI_setProtocol(oHandle, OSPI_FLASH_PROTOCOL(8,8,8,1));
            OSPI_enableDDR(oHandle);
            OSPI_setDualOpCodeMode(oHandle);
            Flash_reset(fHandle);
            OSPI_enableSDR(oHandle);
            OSPI_clearDualOpCodeMode(oHandle);
            OSPI_setProtocol(oHandle, OSPI_FLASH_PROTOCOL(1,1,1,0));
        }
    
    }
    

  • Hi Bomiao,

    The only difference I can observe is in the size of the image, I am using sbl_ospi_linux_stage1.release.tiimage having a size of 260kB, but I doubt that the difference in size will result into this big of a time difference, I am attaching my SBL OSPI Stage-1 image, you can test it at your end, and check if you observe the expected timing.

    sbl_ospi_linux_stage1.release.tiimage.zip

    Best Regards,

    Meet.

  • Hi Meet,

    I want to ask which pin you set low voltage at the SBL_start, is it as same as the tutorial mentioned (MCU_I2C0_SCL ;Pin #24 on the MCU Header J11) ? It also would be great if you could attach the whole project below. 

    In addition to that, I noticed my image name is "sbl_ospi_linux_stage1.release.hs_fs.tiimage" and your image name is "sbl_ospi_linux_stage1.release.tiimage". Dose this means the secure boot effects the ROM boot time? If so, how to disable secure boot during ROM boot?

    BR,

    Bomiao

  • I want to ask which pin you set low voltage at the SBL_start, is it as same as the tutorial mentioned (MCU_I2C0_SCL ;Pin #24 on the MCU Header J11) ?

    Yes.

    It also would be great if you could attach the whole project below. 

    Sure Please find it attached: sbl_ospi_linux_stage1.zip

    In addition to that, I noticed my image name is "sbl_ospi_linux_stage1.release.hs_fs.tiimage" and your image name is "sbl_ospi_linux_stage1.release.tiimage"

    That was a mistake. I was supposed to attach hs_fs.tiimage itself.