AnsweredAssumed Answered

How to add InitCode into Uboot?

Question asked by EvanQiu on Mar 13, 2014
Latest reply on Mar 14, 2014 by EvanQiu

Hi,

     I have a problem in handing external watchdog reset.

 

     I use u-boot-2013.07-2013R1 for my bf512 board (with external SPI-Flash, external watchdog).The problem is I have not enough time to reset external watchdog when running int Uboot, although I add loop_wd_reset(as follow ,external watchdog WDI pin is PF5) in start.s file.

 

     I think the problem is default SPI0 baudrate(config in OTP) is too low, I measured time by Oscilloscope between Power up and execute loop_wd_reset is 2.6s .But my external watchdog timeout is 0.9s~2s. How Can I solve the problem.

 

     I used "initcode + standalone application" mode is OK in VDSP environment, Now I want to "Uboot+ application" mode, how can I add initcode to Uboot? Help me, Please...

 

 

================================================================

arch/blackfin/cpu/start.s

.....

ENTRY(_start)

 

 

          /* Set our initial stack to L1 scratch space */

          sp.l = LO(L1_SRAM_SCRATCH_END - 20);

          sp.h = HI(L1_SRAM_SCRATCH_END - 20);

 

 

          /* Optimization register tricks: keep a base value in the

           * reserved P registers so we use the load/store with an

           * offset syntax.  R0 = [P5 + <constant>];

           *   P4 - system MMR base

           *   P5 - core MMR base

           */

#ifdef CONFIG_HW_WATCHDOG

          p4.l = 0;

          p4.h = HI(SYSMMR_BASE);

#endif

          p5.l = 0;

          p5.h = HI(COREMMR_BASE);

 

 

#ifdef CONFIG_HW_WATCHDOG

          /* Program the watchdog with default timeout of ~5 seconds.

           * That should be long enough to bootstrap ourselves up and

           * then the common u-boot code can take over.

           */

          r1 = WDDIS;

# ifdef __ADSPBF60x__

          [p4 + (WDOG_CTL - SYSMMR_BASE)] = r1;

# else

          W[p4 + (WDOG_CTL - SYSMMR_BASE)] = r1;

# endif

          SSYNC;

          r0 = 0;

          r0.h = HI(MSEC_TO_SCLK(CONFIG_WATCHDOG_TIMEOUT_MSECS));

          [p4 + (WDOG_CNT - SYSMMR_BASE)] = r0;

          SSYNC;

          r1 = WDEN;

          /* fire up the watchdog - R0.L above needs to be 0x0000 */

# ifdef __ADSPBF60x__

          [p4 + (WDOG_CTL - SYSMMR_BASE)] = r1;

# else

          W[p4 + (WDOG_CTL - SYSMMR_BASE)] = r1;

# endif

          SSYNC;

#endif

 

 

#ifdef CONFIG_EXT_WATCHDOG

    /* set port f function enable register to GPIO (not peripheral)

    */

    p0.l = lo(PORTF_FER);

    p0.h = hi(PORTF_FER);

    r0.h = 0x0000;

    r0.l = 0x0000;

    w[p0] = r0;

    /* set port f direction register to enable some GPIO as output,

    remaining are input */

    p0.l = lo(PORTFIO_DIR);

    p0.h = hi(PORTFIO_DIR);

    r0.h = 0x0000;

    r0.l = 0xFFFF;

    w[p0] = r0;

    ssync;

    /* set port f clear register */

    p0.l = lo(PORTFIO_CLEAR);

    p0.h = hi(PORTFIO_CLEAR);

    r0.l = 0xFFFF;

    w[p0] = r0;

    ssync;

    /* set port f input enable register to enable input drivers of

    some GPIOs */

    p0.l = lo(PORTFIO_INEN);

    p0.h = hi(PORTFIO_INEN);

    r0.h = 0x0000;

    r0.l = 0x0000;

    w[p0] = r0;

    ssync;

       

    /* set port f polarity register */

    p0.l = lo(PORTFIO_POLAR);

    p0.h = hi(PORTFIO_POLAR);

    r0 = 0x00000;

    w[p0] = r0;

    ssync;

 

 

    r1 = 10;

loop_wd_reset:

    /* set port f set register */

    p0.l = lo(PORTFIO_SET);

    p0.h = hi(PORTFIO_SET);

    r0.l = 0xFFFF;

    w[p0] = r0;

    ssync;

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    /* set port f clear register */

    p0.l = lo(PORTFIO_CLEAR);

    p0.h = hi(PORTFIO_CLEAR);

    r0.l = 0xFFFF;

    w[p0] = r0;

    ssync;

    NOP;

    NOP;

    NOP;

   

    cc = r1;

    r2 = 1;

    r1 = r1 - r2;

          if cc jump loop_wd_reset;

#endif

 

 


/* Turn on the serial for debugging the init process */

serial_early_init

serial_early_set_baud

...

 


Outcomes