⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 romload2.c

📁 dual-boot loader用来引导更新程序的例子
💻 C
字号:
/*******************************************************************************

File Name    : romload2.c

Description  : ROM boot loader (phase 2)

(C)Copyright ST Microelectronics 1998

Reference to the origin of this file within the build system repository
\5500ref\flash\loader\romload2.c

References to related design specifications, tools, required header files etc.

Date        Modification                                          Initials
----        ------------                                          --------
1996        Creation

*******************************************************************************/

/* Includes ----------------------------------------------------------------- */
#include <string.h>
#include <debug.h>
#include <setjmp.h>
#include "bootdata.h"
#include "restart.h"

#define true  1
#define false 0


/* Private Types ------------------------------------------------------------ */


/* Private Constants -------------------------------------------------------- */

/* Stack checking *must* be disabled in the bootstrap code because
 * global data required by the stack checking code is not set up */
#pragma ST_off(stack_checking)

/* local versions of memcpy and memset which have to be here because
   the may not be loaded into RAM before they are called */

/* These will be optimised to do word copies - also speed isn't as
   important as size here and so that may give us other opportunities */
#define	BS	16


/* Private Variables -------------------------------------------------------- */


/* Private Macros ----------------------------------------------------------- */


/* Private Function prototypes ---------------------------------------------- */


/* Functions ---------------------------------------------------------------- */

#if __CORE__ == 1

  static void local_memcpy(int *dst, const int *src, size_t n);
  #pragma ST_nolink(local_memcpy)
  static void local_memcpy(int *dst, const int *src, size_t n)
  {
    int top;

    __asm
    {                        /* |    Areg     |    Breg    |    Creg    | */
      ldabc   dst, n, src;   /* |    dst      |     n      |    src     | */
      add;                   /* |dst + n (top)|    src     |    dst     | */
      st      top;           /* |    src      |    dst     |    top     | */
    loop:
      ld      top;           /* |    top      |    src     |    dst     | */
      arot;                  /* |    dst      |    top     |    src     | */
      gt;                    /* |  top > dst  |    src     |    dst     | */
      cj      done;          /* |    src      |    dst     | top > dst  | <jump not taken> */
      lbinc;                 /* |   *src      |    dst     |   src + 1  | */
      rev;                   /* |    dst      |   *src     |   src + 1  | */
      sbinc;                 /* |  src + 1    |  dst + 1   |   *src     | */
      j       loop;
    done:;
    }
  }
  #define MEMCPY local_memcpy
#else
  #define MEMCPY memcpy
#endif /* __CORE__ == 1 */

static void local_memset(int *cp, size_t cnt);
#pragma ST_nolink(local_memset)

static void local_memset(int *cp, size_t cnt)
{
  while (cnt != 0)
  {
    *cp = 0;
    cp++;
    cnt -= 4;
  }
}

/* Declare the C runtime library startup routine. */

extern void cstart2(long int staticlink, bootdata_t *bdata);
#pragma ST_translate(cstart2, "cstart2%c")
#pragma ST_nolink(cstart2)

/* this contains the buffer for a long jump for a restart */
jmp_buf _ST_restartbuf ;
/* this contains 0 if the last start was cold and 1 if warm */
int     _ST_laststarttype ;

/* ROM Loader phase2 (romload2). This function is responsible for the
   following:
     1. Move sections to RAM and expand zero sections.
     2. Perform instruction level init.
     3. Call C runtime startup. */

extern void romload2(addressblock_t *addblock);
#pragma ST_translate(romload2, "romload2%c")

void InitStatics(addressblock_t *addblock) ;
#pragma ST_nolink(InitStatics)

void InitStatics(addressblock_t *addblock)
{
  romtableentry_t *sectable = addblock->__stable;

  while (sectable->__size != 0)
  {
    if (sectable->__source == ZERO_SECTION)
      local_memset((int *)(sectable->__dest), sectable->__size);
    else
      MEMCPY(sectable->__dest, sectable->__source, sectable->__size);
    sectable++;
  }
}


void romload2(addressblock_t *addblock)
{
  int warmStart, doInit ;

/*  debugbreak();*/

  /* clear DCU stall bit */
  __asm
  {
    ldab 0x3004, 0x7fffffff;
#if __CORE__ == 1
    lwinc;
#else
    devlw;
#endif
    and;
    ld 0x3004;
#if __CORE__ == 1
    swinc;
#else
    devsw;
#endif
  }

  warmStart = cold_t ;
  doInit    = true ;

  /* do the static initialisation */
  while (doInit==true)
  {
    doInit = false ;
    InitStatics(addblock) ;
    _ST_laststarttype = warmStart ;

    /* set the long jump */
    if (setjmp(_ST_restartbuf)!=0)
    {
      /* if a long jump has occurred */
      warmStart = warm_t ;
      doInit = true ;
    }
  }

  /* perform instruction level init */

#if __CORE__ == 1
  /* C1 core initialisation */

  /* Initialise status word and set address %0, %4 and %8 to MOSTNEG INT.
     This initialises the scheduling queue pointers. This is not done by
     command line pokes because of interactions with the romloader code. */

  __asm
  {
    ldc ((1 << 14) | (1 << 15) | (1 << 19));
    statusset;
    ldc ((1 << 21) | (1 << 16) | (1 << 17));
    statusclr;

    ldc 31;
    bitmask;
    dup;
    stnl 0;
    ldc 31;
    bitmask;
    dup;
    stnl 1;
    ldc 31;
    bitmask;
    dup;
    stnl 2;
  }

#else
  /* C2/C4 core initialisation */

  __asm
  {
    mint;
    dup;
    ldc 0;
    swapqueue;

    mint;
    dup;
    ldc 1;
    swapqueue;

    mint;
    ldc 0;
    swaptimer;

    mint;
    ldc 1;
    swaptimer;

    ldc 0xff;
    gintenb;

    ldc 0;
    sttimer;                       /* initialise clocks */
  }
#endif

  /* call C runtime startup, bootstrapping the staticlink parameter as we go. */
  cstart2(addblock->__bdata->__staticlink, addblock->__bdata);

  /* We should never return, but just in case we do, the buck stops here.
     This has the pleasant side effect of foiling the compiler's attempt
     to tail call optimise the above. If it succeeded to do the optimisation
     then the C4 call to cstart would fail  */

  __asm
  {
#if __CORE__ == 1
    /* This loop stops things from disappearing into oblivion, just
       in case we manage to get here */
back:
    j back;
#else
    stopp;
#endif
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -