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.

RTOS: Required Configurations for Booting SYSBIOS-M4 core image via IPL bootloader

Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hi all,

We need to boot VisionSDK - VPS application M4 core image from IPL.

We are able to test the same image via CCS- JTAG Emulator. 

What are the minimal configurations required from IPL (bootloader) to boot  M4 core image ? 

Regards

Gokul

  • Hi Gokul,

    I have forwarded your question to VisionSDK experts.

    Regards,
    Yordan
  • Hi Gokul,

    What is the SoC and the software package that you are using?

    Regards,
    Rishabh
  • Hi Gokul,

    Let's continue the support through e2e rather than mails.
    If you want to connect directly to M4 without running Multi Core enable script you can add a call for <TDA2xx>_MULTICORE_EnableAllCores() in OnTargetConnect() API in <TDA2xx>_startup_common.gel.
    In case you want to load with SBL, you need to create a Application Image. The steps to do this are mentioned in <starterware_rootdir>/bootloader/SBL_UserGuide.pdf

    Regards,
    Rishabh
  • Hi Rishabh,

    We are not using SBL.  We have proprietary IPL.

    In this IPL, basic initialization for loading & booting M4 core has been done.

    We have verified the IPL has booted the m4 core image by reading the memory location ( 0x40500000U ) from IPL.

    But at some point , it has been crashed.

    While loading  and running M4 core image  via CCS , We are getting exception as below. Is it possible to debug this exception ? ( this is without GEL initialisation,just load the m4 core image & start running. We are doing the  GEL-initialisation from bootloader IPL)

    logs from CCS:

    [Cortex_M4_IPU1_C0] DISP_DSS_APP: Sample Application - STARTS !!!

    src/vpsdrv_init.c @ Line 212: VPS: vpsInitTda2xxPlatData !!

    src/vpsdrv_init.c @ Line 214: VPS: vpsInitTda2xxPlatData done !!

    ti.sysbios.family.arm.m3.Hwi: line 1095: E_hardFault: FORCED

    ti.sysbios.family.arm.m3.Hwi: line 1172: E_busFault: IMPRECISERR: Delayed Bus Fault, exact addr unknown, address: e000ed38

    Exception occurred in background thread at PC = 0x900be8a4.

    Core 0: Exception occurred in ThreadType_Task.

    Task name: {unknown-instance-name}, handle: 0x907578e0.

    Task stack base: 0x90788b00.

    Task stack size: 0x7800.

    R0 = 0x90b4cacc  R8  = 0x90b4cad4

    R1 = 0x00000004  R9  = 0x90b4cb28

    R2 = 0x000000fc  R10 = 0x90b4cb78

    R3 = 0x00000190  R11 = 0x90b4cae4

    R4 = 0x00000000  R12 = 0x00000010

    R5 = 0x00000000  SP(R13) = 0x9078fff8

    R6 = 0x48975800  LR(R14) = 0x900b01eb

    R7 = 0x90790014  PC(R15) = 0x900be8a4

    PSR = 0x21000000

    ICSR = 0x0440f803

    MMFSR = 0x00

    BFSR = 0x04

    UFSR = 0x0000

    HFSR = 0x40000000

    DFSR = 0x00000001

    MMAR = 0xe000ed34

    BFAR = 0xe000ed38

    AFSR = 0x00000000

    Terminating execution...

    Regards

    Gokul

  • Hi Gokul,

    What is the AMMU configuration done by IPL for M4?

    Regards,
    Rishabh
  • Hi Rishabh,

    Please find the Configurations as below.
    /*---------------- Setup the UNICACHE MMU -----------------*/
    /*Large Page Translations */
    /* Logical Address */
    WR_MEM_32(regAddr + 0x800, 0x40000000);
    WR_MEM_32(regAddr + 0x804, 0x80000000);
    WR_MEM_32(regAddr + 0x808, 0xA0000000);
    WR_MEM_32(regAddr + 0x80C, 0x60000000);

    /* Physical Address */
    WR_MEM_32(regAddr + 0x820, 0x40000000);
    WR_MEM_32(regAddr + 0x824, 0x80000000);
    WR_MEM_32(regAddr + 0x828, 0xA0000000);
    WR_MEM_32(regAddr + 0x82C, 0x40000000);

    /* Policy Register */
    WR_MEM_32(regAddr + 0x840, 0x00000007);
    WR_MEM_32(regAddr + 0x844, 0x000B0007);
    WR_MEM_32(regAddr + 0x848, 0x00020007);
    WR_MEM_32(regAddr + 0x84C, 0x00000007);

    /*Medium Page*/
    WR_MEM_32(regAddr + 0x860, 0x80300000);
    WR_MEM_32(regAddr + 0x864, 0x00400000);

    WR_MEM_32(regAddr + 0x8A0, 0x40300000);
    WR_MEM_32(regAddr + 0x8A4, 0x40400000);

    WR_MEM_32(regAddr + 0x8E0, 0x00000007);
    WR_MEM_32(regAddr + 0x8E4, 0x00020007);

    /*Small Page*/
    WR_MEM_32(regAddr + 0x920, 0x00000000);
    WR_MEM_32(regAddr + 0x924, 0x40000000);
    WR_MEM_32(regAddr + 0x928, 0x00004000);
    WR_MEM_32(regAddr + 0x92C, 0x00008000);
    WR_MEM_32(regAddr + 0x930, 0x20000000);

    WR_MEM_32(regAddr + 0x9A0, 0x55020000);
    WR_MEM_32(regAddr + 0x9A4, 0x55080000);
    WR_MEM_32(regAddr + 0x9A8, 0x55024000);
    WR_MEM_32(regAddr + 0x9AC, 0x55028000);
    WR_MEM_32(regAddr + 0x9B0, 0x55020000);

    WR_MEM_32(regAddr + 0xA20, 0x0001000B);
    WR_MEM_32(regAddr + 0xA24, 0x0000000B);
    WR_MEM_32(regAddr + 0xA28, 0x00010007);
    WR_MEM_32(regAddr + 0xA2C, 0x00000007);
    WR_MEM_32(regAddr + 0xA30, 0x00000007);


    Regards
    Gokul
  • Hi Gokul,

    Looking at the problem statement it seems that M4 application is also setting up AMMU which has conflicts with the one set by gel.
    As a first step can you try to boot the M4 image by SBL without Gel. This will verify the root cause as TDA2xx SBL does not set up AMMU for IPU.
    Then you can look at application cfg file and remove conflicting configuration.
    Ideally AMMU programming should be done only once. So you can move it to IPL and remove from gel/application.

    Regards,
    Rishabh
  • Hi Rishabh,

    We are using VPS dss application.
    Which configuration files, do we need to look on this application?

    Regards,
    Gokul

  • Hi Gokul,

    To refer to cfg files look at displayDss.cfg. It loads utility/bspCommonBIOS.cfg.
    Then it includes one of the AMMU cfg file depending on platform. These files are also present in <bspdrivers>\examples\utility.

    Regards,
    Rishabh
  • Hi Rishabh,

    Attached file which is used by IPL team which does initialization in IPL for M4 booting.

    Can you please support to find the missing initialization by IPL  ?

    We are using dra7xx platform. So our  cfg file will be bspCommon_AMMU.cfg .Am I right ?

    #include "ipl.h"
    
    #include "image.h"
    #include "boot.h"
    
    #include "dra7xx_prcm.h"
    
    #include "dra7xx.h"
    #include "dra7xx_gpio.h"
    #include "dra7xx_control.h"
    #include "dra7xx_tmu.h"
    
    #include "hwinit_board.h"
    #include "ubi.h"
    #include "config.h"
    
    
    #include "libsa/stand.h"
    
    
    #ifndef DBG2MEM
    #define DBG2MEM(...)
    #endif
    
    extern int do_cmd_sboot (int core, uint32_t addr, int flags, int32_t ram_offset);
    extern int public_sdc_load_file (unsigned ch, char* name, unsigned dest, unsigned *size, char* quiet[]);
    extern void dump_loader_args (const void *ap);
    extern void dump_tstamps (void);
    extern void init_pll_global  ( volatile adpll *adpll, const dpll_param *param, ssc_param *ssc, int lock, int sysclk_khz);
    extern void _mb_parse_image (struct image_info *, const char *, unsigned);
    
    #define IPU_SUPPORT /* test switch to disable IPU startup */
    
    #ifdef IPU_SUPPORT
    
    #define WR_MEM_32(a,b) *((volatile unsigned*) (a)) = (b)
    #define RD_MEM_32(a)  *((volatile unsigned*) (a))
    
    IPUSSClkEnable(uint32_t cpu_num)
    {
       PRM1;
    
       uint32_t regVal, regAddr, ramAddr;
    
       if (cpu_num) {
          /* Reset asserted for IPU CPU0, CPU1, Unicache and MMU */
          prm1->ipu2_rstctrl = 0x7;
    
          /* Reset deassertion for IPU Unicache/MMU */
          prm1->ipu2_rstst = 0x7;
          prm1->ipu2_rstctrl = 0x3;
    
          while ((prm1->ipu2_rstst & 0x4) != 0x4)
             ;
          regAddr = IPU2_UNICACHE_MMU;
          ramAddr = IPU2_RAM;
    
       } else {
          /* Reset asserted for IPU CPU0, CPU1, Unicache and MMU */
          prm1->ipu1_rstctrl = 0x7;
    
          /* Reset deassertion for IPU Unicache/MMU */
          prm1->ipu1_rstst = 0x7;
          prm1->ipu1_rstctrl = 0x3;
    
          while ((prm1->ipu1_rstst & 0x4) != 0x4)
             ;
          regAddr = IPU1_UNICACHE_MMU;
          ramAddr = IPU1_RAM;
       }
    
       /*---------------- Setup the UNICACHE MMU -----------------*/
       /*Large Page Translations */
       /* Logical Address */
       WR_MEM_32(regAddr + 0x800, 0x40000000);
       WR_MEM_32(regAddr + 0x804, 0x80000000);
       WR_MEM_32(regAddr + 0x808, 0xA0000000);
       WR_MEM_32(regAddr + 0x80C, 0x60000000);
    
       /* Physical Address */
       WR_MEM_32(regAddr + 0x820, 0x40000000);
       WR_MEM_32(regAddr + 0x824, 0x80000000);
       WR_MEM_32(regAddr + 0x828, 0xA0000000);
       WR_MEM_32(regAddr + 0x82C, 0x40000000);
    
       /* Policy Register */
       WR_MEM_32(regAddr + 0x840, 0x00000007);
       WR_MEM_32(regAddr + 0x844, 0x000B0007);
       WR_MEM_32(regAddr + 0x848, 0x00020007);
       WR_MEM_32(regAddr + 0x84C, 0x00000007);
    
       /*Medium Page*/
       WR_MEM_32(regAddr + 0x860, 0x80300000);
       WR_MEM_32(regAddr + 0x864, 0x00400000);
    
       WR_MEM_32(regAddr + 0x8A0, 0x40300000);
       WR_MEM_32(regAddr + 0x8A4, 0x40400000);
    
       WR_MEM_32(regAddr + 0x8E0, 0x00000007);
       WR_MEM_32(regAddr + 0x8E4, 0x00020007);
    
       /*Small Page*/
       WR_MEM_32(regAddr + 0x920, 0x00000000);
       WR_MEM_32(regAddr + 0x924, 0x40000000);
       WR_MEM_32(regAddr + 0x928, 0x00004000);
       WR_MEM_32(regAddr + 0x92C, 0x00008000);
       WR_MEM_32(regAddr + 0x930, 0x20000000);
    
       WR_MEM_32(regAddr + 0x9A0, 0x55020000);
       WR_MEM_32(regAddr + 0x9A4, 0x55080000);
       WR_MEM_32(regAddr + 0x9A8, 0x55024000);
       WR_MEM_32(regAddr + 0x9AC, 0x55028000);
       WR_MEM_32(regAddr + 0x9B0, 0x55020000);
    
       WR_MEM_32(regAddr + 0xA20, 0x0001000B);
       WR_MEM_32(regAddr + 0xA24, 0x0000000B);
       WR_MEM_32(regAddr + 0xA28, 0x00010007);
       WR_MEM_32(regAddr + 0xA2C, 0x00000007);
       WR_MEM_32(regAddr + 0xA30, 0x00000007);
    
    
       /*---------------- Write IPU IRAM Boot Image ---------------*/
       /* This puts the cores into dummy loops to prevent them from running bad code */
       WR_MEM_32(ramAddr + 0x0, 0x10000);
       WR_MEM_32(ramAddr + 0x4, 0x9);
       WR_MEM_32(ramAddr + 0x8, 0xE7FEE7FE);
    //   while (RD_MEM_32(ramAddr + 0x0) != 0x10000);
    //   while (RD_MEM_32(ramAddr + 0x4) != 0x9);
    //   while (RD_MEM_32(ramAddr + 0x8) != 0xE7FEE7FE);
    
    
       /* Reset deassertion for IPU CPU0, CPU1 */
    //   WR_MEM_32(RM_IPU_RSTCTRL, 0x0);
    
       /* Check the reset state: IPU CPU0, CPU1, Unicache and MMU are out of reset */
    //   while ((RD_MEM_32(RM_IPU_RSTST) & 0x3) != 0x3);
    //   WR_MEM_32(RM_IPU_RSTST, 0x7);
    }
    #endif
    
    int board_get_pcbrev() {
       int rev=0;
       dra7xx_gpio *gpio7=(dra7xx_gpio*) (GPIO7_BASE);
       dra7xx_gpio *gpio1=(dra7xx_gpio*) (GPIO1_BASE);
       //todo: powerup GPIO1, GPIO7 or do this in hwinit.c?
       //first, do muxing
       *(volatile unsigned*)(0x4a00343c) = 0x5000e; //disable PU/PD on GP7_3
       *(volatile unsigned*)(0x4a003440) = 0x5000e; //disable PU/PD on GP7_4
       *(volatile unsigned*)(0x4a003444) = 0x5000e; //disable PU/PD on GP7_5
       *(volatile unsigned*)(0x4a003448) = 0x5000e; //disable PU/PD on GP7_6
       *(volatile unsigned*)(0x4a00345c) = 0x5000e; //disable PU/PD on GP1_29
       *(volatile unsigned*)(0x4a003458) = 0x5000e; //disable PU/PD on GP1_28
       //TODO
       udelay(5);
       //GIO4[4:1]=PCB_REV
       gpio7->oe|=(0xf<<3); //set gpio7[7:4] to input
       rev=(gpio7->datain>>3)&0xf; //read gpio[4:1] vals
    
       //RSE/HU?
       gpio1->oe|=(0x3<<28); //set gpio1[29:28] to input
       rev|=((gpio1->datain>>28)&0x3)<<16;
       DBG2MEM(0x84,gpio7->datain);
       DBG2MEM(0x88,gpio1->datain);
       return rev;
    }
    
    int board_set_ioconf() {
       dra7xx_gpio *gpio6=(dra7xx_gpio*) (GPIO6_BASE);
       dra7xx_gpio *gpio5=(dra7xx_gpio*) (GPIO5_BASE);
       dra7xx_gpio *gpio1=(dra7xx_gpio*) (GPIO1_BASE);
       dra7xx_ctrl_core *core=(dra7xx_ctrl_core*) CTRL_MODULE_CORE;
       gpio6->setdataout |= (1<<8); //set output for GPIO6_8 to 1 (UART-Mux)
       gpio6->oe &= ~ (1<<8); //make GPIO6_8 an output (UART-Mux
    
       core->control_pbias |= (0x0C000000);
       gpio5->setdataout |= (1<<31); //set output for GPIO5_31 to 1(SDCARD1_PWR_ON)
       gpio5->oe &= ~(1<<31); //make GPIO5_31 an output (SDCARD1_PWR_ON)
    
       gpio6->setdataout |= (1<<15); //set output for GPIO6_15 to 1(SDCARD2_PWR_ON)
       gpio6->oe &= ~(1<<15); //make GPIO6_15 an output (SDCARD2_PWR_ON)
    
       gpio1->setdataout |= (1<<4); //set output for GPIO1_4 to 1(XNAND_RESET_Q)
       gpio1->oe &= ~(1<<4); //make GPIO1_4 an output (XNAND_RESET_Q)
    
       return 0;
    }
    
    dpll_param abe_dpll_param     =  { 256, 24,  1,  1, -1, -1, -1, -1, -1, -1, -1, -1};   //19.2 MHz
    
    int enable_board_clocks() {
       CML4;
       CM0;
       CM1;
       CM2;
       PRM1;
       CTRL1;
       unsigned i;
       unsigned max=20;
       uint32_t *clk_modules_hw_auto_project[] = {
          (uint32_t*) &cm2->cm_cam_vip1_clkctrl,
          (uint32_t*) &cm2->cm_cam_vip2_clkctrl,
          (uint32_t*) &cm2->cm_cam_vip3_clkctrl,
          (uint32_t*) &cm0->vpe_clkctrl,
    #ifdef IPU_SUPPORT
          (uint32_t*) &cm0->cm_ipu1_ipu1_clkctrl,
          (uint32_t*) &cm1->cm_ipu2_ipu2_clkctrl,
    #endif
          0
       };
    
       uint32_t *clk_domains_noauto_nosleep_project[] = {
          (uint32_t*) &cm2->cm_cam_clkstctrl,
          (uint32_t*) &cm0->vpe_clkstctrl,
    #ifdef IPU_SUPPORT
          (uint32_t*) &cm0->cm_ipu1_clkstctrl,
          (uint32_t*) &cm1->cm_ipu2_clkstctrl,
    #endif
          0
         };
    
       uint32_t *clk_modules_explicit_en_project[] = {
          (uint32_t*) &cml4->cm_l4per_mmcsd4_clkctrl,
          (uint32_t*) &cml4->cm_l4per_uart5_clkctrl,
          (uint32_t*) &cml4->cm_l4per2_uart8_clkctrl,
          (uint32_t*) &cml4->cm_l4per2_uart9_clkctrl,
          (uint32_t*) &prm1->cm_wkup_uart10_clkctrl,
          (uint32_t*) &cm1->cm_l3main1_gpmc_clkctrl,
          (uint32_t*) &cml4->cm_l4per_elm_clkctrl,
          (uint32_t*) &cm1->cm_l3main1_mmu_edma_clkctrl,
          0
         };
    
    #ifdef IPU_SUPPORT
       // Selects CORE_IPU_ISS_BOOST_CLK as the functional clock
       cm0->cm_ipu1_ipu1_clkctrl |= (1<<24);
    #endif
    
    
       //dpll configs
       prm1->cm_clksel_per_abe_x1_gdclk_mcasp_aux = 0x1; //set mcasp1 clk to 196,608/2 MHz
    
       init_pll_global((adpll*)&cm0->pll_abe,&abe_dpll_param,  (ssc_param*)0, LOCK, CPMS);
    
    
         for (i = 0; i<max;i++) {
             if (!clk_domains_noauto_nosleep_project[i])
                break;
             *clk_domains_noauto_nosleep_project[i]=(*clk_domains_noauto_nosleep_project[i]&0xfffffffc) | 0x2;
         }
    
         for (i = 0; i<max;i++) {
             if (!clk_modules_explicit_en_project[i])
                break;
             *clk_modules_explicit_en_project[i]=(*clk_modules_explicit_en_project[i]&0xfffffffc) | 0x2;
             while((*clk_modules_explicit_en_project[i]&(3<<16))==1 || (*clk_modules_explicit_en_project[i]&(3<<16))==3);
       }
    
       for (i = 0; i<max;i++) {
             if (!clk_modules_hw_auto_project[i])
                break;
             *clk_modules_hw_auto_project[i]=(*clk_modules_hw_auto_project[i]&0xfffffffc) | 0x1;
             while((*clk_modules_hw_auto_project[i]&(3<<16))==1 || (*clk_modules_hw_auto_project[i]&(3<<16))==3);
    
       }
    
    
       for (i = 0; i<max;i++) {
             if (!clk_domains_noauto_nosleep_project[i])
                break;
             *clk_domains_noauto_nosleep_project[i]=(*clk_domains_noauto_nosleep_project[i]&0xfffffffc) | 0x0; //put to nosleep
        }
    
    #ifdef IPU_SUPPORT
       IPUSSClkEnable(0);
       IPUSSClkEnable(1);
    #endif
    
       return 0;
    }
    
    /****************************************************************************************/
    #include "dra7xx_spi.h"
    
                                    /* timeout values (milliseconds): */
    #ifndef IOC_BM_TIMEOUT_START
    #define IOC_BM_TIMEOUT_START  500	/* - IOC starts sending boot mode info */
    #endif
    
    #ifndef IOC_BM_TIMEOUT_DONE
    #define IOC_BM_TIMEOUT_DONE	  5	/* - after last byte received */
    #endif
    // ========================================================================
    void
    init_get_bootmode_ioc (void)
    {
       volatile dra7xx_gpio *gpio = (dra7xx_gpio *)hwconfig[sample_config[hwVer.PCB]].ioc_gpio_base;
       volatile dra7xx_SPI  *spi  = (dra7xx_SPI *)hwconfig[sample_config[hwVer.PCB]].ioc_spi_base;
    
       const unsigned spimode = 2;
       const unsigned wordlen = 8;
    
       unsigned tval;
       unsigned pin  = (1U << ((hwconfig[sample_config[hwVer.PCB]].ioc_gpio_pin) & 0x1F));
       unsigned pol  = ((      hwconfig[sample_config[hwVer.PCB]].ioc_gpio_pin) & 0x80);
    
    
       if (pol)
          gpio->setdataout =  pin;
       else
          gpio->cleardataout =  pin;
    
       gpio->oe        &= ~pin;
    
       spi->SYSCONFIG |= 2;                 /* set .SOFTRESET (triggers module reset) */
       while ((spi->SYSSTATUS & 1) == 0)    /* await .RESETDONE */
          ;
    
       // Configure the serial port interface: slave mode, using chip select.
       tval = 0
          | ( 1 << 2)                       // .MS
          | ( 0 << 1);                      // .PIN34
       spi->MODULCTRL = tval;
    
       // ---------------------------------------------------------------------
       // Prepare for reading from SPI0:
    
       // Configure channel 0:
       tval = 0
          | (1             << 28)           // .FFER bit enabled (FIFO enabled for recieve)
          | (0             << 21)           // .SPIENSLV - use SPIEN[0]
          | (0             << 18)           // .IS       - receive  on SPIDAT[0]
          | (1             << 16)           // .DPE1/0   - transmit on SPIDAT[1]
          | (1             << 12)           // .TRM      - receive-only mode.
          | ((wordlen - 1) <<  7)           // .WL
          | (1             <<  6)           // .EPOL
          | (spimode       <<  0);          // .POL, .PHA
       if (hwconfig[sample_config[hwVer.PCB]].ioc_spi_swap)
          tval ^= (7<<16); // receive on SPIDAT[1], transmit on SPIDAT[0]
    
       spi->ch[0].CONF = tval;
    
       // disable all interrupts, we will be polling ...
       spi->IRQENABLE = 0;
    
       // Enable channel 0
       tval = 1;                            // .EN
       spi->ch[0].CTRL = tval;
    
       // ---------------------------------------------------------------------
       // Activate IOC_INT (tell the IOC to send the boot mode word).
       if (pol)
          gpio->cleardataout =  pin;
       else
          gpio->setdataout =  pin;
    }
    
    
    int
    do_get_bootmode_ioc (unsigned mode_len, uint8_t mode[], unsigned timeout)
    {
       volatile dra7xx_gpio *gpio = (dra7xx_gpio *)hwconfig[sample_config[hwVer.PCB]].ioc_gpio_base;
       volatile dra7xx_SPI  *spi  = (dra7xx_SPI *)hwconfig[sample_config[hwVer.PCB]].ioc_spi_base;
    
       const char *mode_string;
    
       unsigned word;
       unsigned nread = 0;
       uint32_t t0, t1;
       int res = 0;
    
       unsigned pin  = (1U << ((hwconfig[sample_config[hwVer.PCB]].ioc_gpio_pin) & 0x1F));
       unsigned pol  = ((      hwconfig[sample_config[hwVer.PCB]].ioc_gpio_pin) & 0x80);
    
       // Read the boot mode word from SPI0.
       t1 = t0 = TIMESTAMP_NOW();
       for (;;)
       {
          t1 = TIMESTAMP_NOW();
          if (t1 - t0 >= timeout * CPMS)
          {
             res = nread;                   /* time-out */
             break;
          }
    
          // check on RXFFE (rx FIFO not empty) and RXS (rx register epmty)
          if ( ((spi->ch[0].STAT & (1 << 5)) == 0) || ((spi->ch[0].STAT & (1 << 0)) == 1) )
          {
             word = spi->ch[0].RX;
    
             if (nread < mode_len )
                mode[nread++] = word;
    
             if ( nread >= mode_len )
                break;
    
             t0 = t1;                       /* re-arm (short, inter-word) timeout */
             timeout = IOC_BM_TIMEOUT_DONE;
          }
       }
    
       // ---------------------------------------------------------------------
       // Deactivate IOC_INT (tell the IOC that we are done).
       if (pol)
          gpio->setdataout =  pin;
       else
          gpio->cleardataout =  pin;
    
       // Shut down SPI0 and disable (reset) the interface:
       spi->ch[0].CTRL &= ~1;               /* clear .EN */
       spi->SYSCONFIG |= 2;                 /* set .SOFTRESET */
       while ((spi->SYSSTATUS & 1) == 0)    /* await .RESETDONE */
          ;
       if ( 0 == res)
          res = nread;
    
       if (res > 0)
          mode[res+1] = 0;
    
       if (res <= 0) {
          printf ("*** WARNING: no IOC boot mode!\n");
       }
       return res;
    }
    
    int
    get_IOC_bootmode_ioc (unsigned mode_len, uint8_t mode[])
    {
       if (IOC_BM_TIMEOUT_START == 0)
          return 0;
       else
       {
          init_get_bootmode_ioc();
          return do_get_bootmode_ioc (mode_len, mode, IOC_BM_TIMEOUT_START);
       }
    }
    // ========================================================================
    
    void
    show_bootmode_ioc (int len, const void *mode)
    {
       printf("IOC: ");
       if (len < 0)
       {
          printf ("** ERROR #%d!\n", len);
       }
       else if (len == 0)
       {
          printf ("** TIMEOUT!\n");
       }
       else
       {
          const uint8_t *m = mode;
          int i;
    
          for (i=0 ; i<len ; i+=1)
          {
             unsigned b = m[i];
             printf ("%c", (b >= ' ' && b <= '~') ? b : '.');
          }
          printf("\n    ");
          for (i=0 ; i<len ; i+=1)
          {
             unsigned b = m[i];
             if (i % 4 == 0)
                printf(" ");
             printf ("%02x", b);
          }
          printf ("\n");
       }
    }
    

    With Regards,

    Gokul

  • Gokul,

    Typical reason for M4 crash after loading from boot loader is that some of the peripheral clocks required by M4 are not turned on. In case of vision sdk, we normally use the patch shown below to turn on peripheral clocks.

    review.omapzoom.org/38438 spl: dra7xx: early boot: enable peripherals for vision sdk

    You many need more changes based on the peripherals used by your M4 application.

    regards,
    Venkat
  • Hi Venkat,

    We are able to load the m4 core image via bootloader.
    Thanks for sharing the required configuration.
    review.omapzoom.org/38438.

    Regards,
    Gokul