romStart.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:17k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* romStart.c - ROM initialization module */
  2. /* Copyright 1989-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,26mar02,sbs  correcting data section relocation for ROM compressed images
  8.                  (SPR 73785)
  9. 01e,29nov01,sbs  Adding dual copy mechanism for copying data sections from
  10.                  ROM to RAM using new WRS labels for sdata and edata. 
  11. 01d,27nov01,tpw  Manually unroll copyLongs and fillLongs.
  12. 01c,06jul98,jmp  added USER_RESERVED_MEM definition if USER_RESERVED_MEM is
  13.                  not defined.
  14. 01b,20may98,ms   minor cleanup to docs and code.
  15. 01a,22aug97,ms   derived from 04p of bootInit.c and simplified.
  16. */
  17. /*
  18. DESCRIPTION
  19. This module provides a generic ROM startup facility.  The target-specific
  20. romInit.s module performs the minimal preliminary board initialization and
  21. then jumps to the C routine romStart(). It is assumed that the romInit.s
  22. module has already set the initial stack pointer to STACK_ADRS.
  23. This module optionally clears memory to avoid parity errors, initializes
  24. the RAM data area, and then jumps to the routine "relocEntry".
  25. This module is a replacement for config/all/bootInit.c.
  26. CLEARING MEMORY
  27. One feature of this module is to optionally clear memory to avoid parity
  28. errors.
  29. Generally, we clear for the bottom of memory (the BSP's LOCAL_MEM_LOCAL_ADRS
  30. macro), to the top of memory (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE),
  31. but avoiding the stack area. In order to avoid trashing the stack area,
  32. the BSP's romInit.s must have set the stack pointer to the macro STACK_ADRS.
  33. There are three configuration macros which can be overridden in the
  34. BSP's config.h file to change how memory is cleared:
  35. ROMSTART_BOOT_CLEAR undefine to not clear memory when booting
  36. USER_RESERVED_MEM area at the top of memory to not clear
  37. RESERVED area at the bottom of memory to not clear
  38. .bS 22
  39. RAM
  40.     --------------  0x00100000 = LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE
  41.     |            |
  42.     |------------| = " - USER_RESERVED_MEM
  43.     |            |
  44.     |  0 filled  |
  45.     |            |
  46.     |------------|  0x00001000  = RAM_DATA_ADRS
  47.     | initial sp |
  48.     |------------| = RAM_DATA_ADRS - STACK_SAVE
  49.     |            |
  50.     | 0 filled   |
  51.     |            |  exc vectors, bp anchor, exc msg, bootline
  52.     |            |
  53.     |------------| = LOCAL_MEM_LOCAL_ADRS + RESERVED
  54.     |            |
  55.     --------------  0x00000000  = LOCAL_MEM_LOCAL_ADRS
  56. .bE
  57. Note: The STACK_ADRS macro defaults to either RAM_DATA_ADRS, or
  58. RAM_DATA_ADRS - STACK_SAVE, depending on if the stack grows up
  59. or down for the given processor.
  60. Note: The RAM_DATA_ADRS macro is passed to us from the Make system.
  61. It represents the address to which the data segment is linked
  62. and defaults to the BSP Makefile's RAM_LOW_ADRS macro. For details on
  63. how to change the addresses to which VxWorks is linked, refer to the
  64. documentation in h/make/defs.vxWorks.
  65. INITIALIZING DATA
  66. The other main feture of this module is to initialize the RAM data
  67. area.
  68. The way this is done depends on the kind of image you are building.
  69. There are three ROM image types that are supported by the Make
  70. system:
  71.   ROM_RESIDENT run from ROM, with only the data segment placed in RAM.
  72.   ROM_COPY copy the main image from ROM to RAM and jump to it.
  73.   ROM_COMPRESS uncompress the main image from ROM to RAM and jump to it.
  74. The make system will define one of these macros for you, depending on the
  75. name of the target you are building (%.rom_res, %.rom_cpy, or %.rom_cmp).
  76. There are separate version of romStart for each of these cases.
  77. Let's start with the simplest case; ROM_RESIDENT.
  78. ROM_RESIDENT IMAGES
  79. When the board is powered on, the processor starts executing instructions
  80. from ROM. The ROM contains some text (code) and a copy of the data
  81. segment. The pictured below is a typical example:
  82. .bS 6
  83. ROM
  84.     --------------
  85.     |            |
  86.     |------------|
  87.     |    data    |
  88.     |------------|  0xff8xxxxx  = ROM_DATA_ADRS
  89.     |    text    |
  90.     |            |  0xff800008  = ROM_TEXT_ADRS
  91.     --------------  0xff800000  = ROM_BASE_ADRS
  92. .bE
  93. romStart() copies the data segment from ROM_DATA_ADRS to RAM_DATA_ADRS -
  94. the address to which it is really linked.
  95. The picture below is an example of RAM addresses on a 1 meg board.
  96. .bS 22
  97. RAM
  98.     --------------  0x00100000 = LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE
  99.     |            |
  100.     |            |
  101.     |------------| = RAM_DATA_ADRS + data segment size
  102.     |            |
  103.     |data segment|
  104.     |            |
  105.     |------------|  0x00001000  = RAM_DATA_ADRS
  106.     | initial sp |
  107.     |------------| = RAM_DATA_ADRS - STACK_SAVE
  108.     |            |
  109.     |            |
  110.     --------------  0x00000000  = LOCAL_MEM_LOCAL_ADRS
  111. .bE
  112. ROM_COPY and ROM_COMPRESS IMAGES
  113. These images are slightly more complex than ROM_RESIDENT images.
  114. The Make system produces an intermediate image, called %.ram_reloc,
  115. which runs from RAM. It then embeds the binary for this subimage within
  116. a ROM image. The subimage is located between the global symbols
  117. "binArrayStart" and "binArrayEnd". The main difference between
  118. the ROM_COPY and the ROM_COMPRESS images is how the subimage is
  119. stored.
  120. For ROM_COMPRESS, the subimage is compressed to save ROM space.
  121. A modified version of the Public Domain f3zlibfP library is used to
  122. uncompress the VxWorks boot ROM executable linked with it.  Compressing
  123. object code typically achieves over 55% compression, permitting much
  124. larger systems to be burned into ROM.  The only expense is the added few
  125. seconds delay while the first two stages complete.
  126. For ROM_COPY, the subimage is not compressed to make the
  127. startup sequence shorter.
  128. In both cases, the ROM image initially looks like this, with
  129. binArrayStart and binArrayEnd at the end of the ROM data area.
  130. The pictured below is a typical example:
  131. .bS 6
  132. ROM
  133.     --------------
  134.     |            |
  135.     |------------|  0xff8xxxxx = binArrayEnd
  136.     |  subImage  |
  137.     |------------|  0xff8xxxxx = binArrayStart
  138.     |    data    |
  139.     |------------|  0xff8xxxxx  = ROM_DATA_ADRS
  140.     |    text    |
  141.     |            |  0xff800008  = ROM_TEXT_ADRS
  142.     --------------  0xff800000  = ROM_BASE_ADRS
  143. .bE
  144. For ROM_COPY images, romStart() copies the subimage from binArrayStart to
  145. RAM_DST_ADRS
  146. For ROM_UNCOMPRESS images, romStart() first copies the uncompression
  147. code's data segment to RAM_DATA_ADRS, and then runs the uncompression
  148. routine to place the subimage at RAM_DST_ADRS.
  149. Both the RAM_DST_ADRS and RAM_DATA_ADRS macros are link addressed
  150. defined by the Make system, which default to the BSP Makefile's
  151. RAM_LOW_ADRS and RAM_HIGH_ADRS respectively.
  152. For information on how to change link addresses, refer to the file
  153. target/h/make/rules.bsp.
  154. The picture below is an example of RAM addresses on a 1 meg board.
  155. "temp data" below refers to the uncompression code's data segment.
  156. .bS 22
  157.         RAM
  158.     --------------  0x00100000 = LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE
  159.     |            |
  160.     |            |
  161.     |------------|
  162.     | temp data  |
  163.     |------------|  0x00090000  = RAM_DATA_ADRS
  164.     | initial sp |
  165.     |------------|              = RAM_DATA_ADRS - STACK_SAVE
  166.     |            |
  167.     |            |
  168.     |------------|
  169.     |            |
  170.     |  subimage  |
  171.     |            |
  172.     |------------|  0x00001000  = RAM_DST_ADRS (for non-resident images)
  173.     |            |
  174.     |            |
  175.     --------------  0x00000000  = LOCAL_MEM_LOCAL_ADRS
  176. .bE
  177. SEE ALSO:
  178. inflate(), romInit(), and deflate.
  179. AUTHOR
  180. The original compression software was written by Jean-loup Gailly
  181. and Mark Adler. See the manual pages of inflate and deflate for
  182. more information on their freely available compression software.
  183. SUMMARY OF CONFIGURATION MACROS
  184. Macro defined synopsys
  185. ----- ------- --------
  186. ROM_BASE_ADRS config.h Start of ROM
  187. ROM_TEXT_ADRS Makefile Start of text segment within ROM, typically
  188. a CPU-dependant offset from ROM_BASE_ADRS.
  189. ROM_DATA_ADRS Here Location in ROM containing a copy of the 
  190. data segment. This must eventually be copied
  191. to the RAM address to which it is linked.
  192. RAM_DATA_ADRS rules.bsp Location in RAM to which the data segment is
  193. really linked.
  194. STACK_ADRS configAll.h Initial stack pointer.
  195. ROMSTART_BOOT_CLEAR configAll.h Undefine to not clear memory when booting
  196. USER_RESERVED_MEM configAll.h Area at the top of memory to not clear
  197. RESERVED configAll.h Area at the bottom of memory to not clear
  198. LOCAL_MEM_LOCAL_ADRS config.h
  199. LOCAL_MEM_SIZE config.h
  200. CHANGES from bootInit.c:
  201. Three separate version of romStart to make it readable.
  202. One each for ROM_COMPRESS, ROM_RESIDENT, and ROM_COPY images.
  203. * The ROM_COPY image copys the main image from binArrayStart to
  204.   RAM_DST_ADRS and then jumps to it.
  205.   The array binArrayStart and the macro RAM_DST_ADRS are provided by the
  206.   Make system.
  207. * The ROM_COMPRESS image uncompresses the main image from binArrayStart to
  208.   RAM_DST_ADRS and then jumps to it.
  209.   Before the uncompression can run, this image needs to initialize the
  210.   uncompression code's data segment. It does this by copying data from
  211.   ROM_DATA to RAM_DATA_ADRS.
  212.   The array binArrayStart and the macros RAM_DST_ADRS and RAM_DATA_ADRS
  213.   are provided by the Make system. The macro ROM_DATA is a toolchain
  214.   dependant macro, which defaults to the global symbol "etext".
  215. * The ROM_RESIDENT image copys its data segment from ROM to RAM. As with
  216.   the ROM_COMPRESS image, it does this by copying from ROM_DATA to
  217.   RAM_DATA_ADRS.
  218. */
  219. #include "vxWorks.h"
  220. #include "sysLib.h"
  221. #include "config.h"
  222. #include "usrConfig.h"
  223. /* default uncompression routine for compressed ROM images */
  224. #ifndef UNCMP_RTN
  225. #   define UNCMP_RTN inflate
  226. #endif
  227. /* toolchain dependant location of the data segment within ROM */
  228. #ifndef ROM_DATA_ADRS
  229. #   define ROM_DATA_ADRS (UINT *)(etext)
  230. #endif
  231. /* MIPS needs to write to uncached memory, others just do normal writes */
  232. #ifndef UNCACHED
  233. #    define UNCACHED(adr) adr
  234. #endif
  235. /* USER_RESERVED_MEM must be set to 0 if not defined */
  236. #ifndef USER_RESERVED_MEM
  237. #    define USER_RESERVED_MEM 0
  238. #endif
  239. /* handy macros */
  240. #define ROM_DATA(adrs) ((UINT)adrs + ((UINT)ROM_DATA_ADRS - RAM_DATA_ADRS))
  241. #define SYS_MEM_TOP 
  242. (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE - USER_RESERVED_MEM)
  243. #define SYS_MEM_BOTTOM 
  244. (LOCAL_MEM_LOCAL_ADRS + RESERVED)
  245. #define BINARRAYEND_ROUNDOFF    (ROUND_DOWN(binArrayEnd, sizeof(long)))
  246. /* forward declarations */
  247. LOCAL void copyLongs (FAST UINT *source, FAST UINT *destination, UINT nlongs);
  248. #ifdef ROMSTART_BOOT_CLEAR
  249. LOCAL void fillLongs (FAST UINT *buf, UINT nlongs, FAST UINT val);
  250. LOCAL void bootClear (void);
  251. #endif
  252. /* imports */
  253. IMPORT STATUS   UNCMP_RTN ();
  254. IMPORT void     relocEntry ();
  255. IMPORT UCHAR    binArrayStart [];       /* compressed binary image */
  256. IMPORT UCHAR    binArrayEnd []; /* end of compressed binary image */
  257. IMPORT char     etext [];               /* defined by the loader */
  258. IMPORT char     end [];                 /* defined by the loader */
  259. IMPORT char     wrs_kernel_data_end []; /* defined by the loader */
  260. #ifdef ROM_COMPRESS
  261. /*******************************************************************************
  262. *
  263. * romStart - generic ROM initialization for compressed images
  264. *
  265. * This is the first C code executed after reset.
  266. *
  267. * This routine is called by the assembly start-up code in romInit().
  268. * It clears memory, copies ROM to RAM, and invokes the uncompressor.
  269. * It then jumps to the entry point of the uncompressed object code.
  270. *
  271. * RETURNS: N/A
  272. */
  273. void romStart
  274.     (
  275.     FAST int startType /* start type */
  276.     )
  277.     {
  278.     volatile FUNCPTR absEntry = (volatile FUNCPTR)RAM_DST_ADRS;
  279.     /* relocate the data segment of the decompression stub */
  280.     copyLongs (ROM_DATA_ADRS, (UINT *)UNCACHED(RAM_DATA_ADRS),
  281.               ((UINT)binArrayStart - (UINT)RAM_DATA_ADRS) / sizeof (long));
  282.     copyLongs ((UINT *)((UINT)ROM_DATA_ADRS + ((UINT)BINARRAYEND_ROUNDOFF -  
  283.         (UINT)RAM_DATA_ADRS)), (UINT *)UNCACHED(BINARRAYEND_ROUNDOFF),
  284. ((UINT)wrs_kernel_data_end - (UINT)binArrayEnd) / sizeof (long));
  285.     /* If cold booting, clear memory to avoid parity errors */
  286. #ifdef ROMSTART_BOOT_CLEAR
  287.     if (startType & BOOT_CLEAR)
  288. bootClear();
  289. #endif
  290.     /* decompress the main image */
  291.     if (UNCMP_RTN (ROM_DATA(binArrayStart),
  292. UNCACHED(RAM_DST_ADRS),
  293. binArrayEnd - binArrayStart) != OK)
  294. return;
  295.     /* and jump to it */
  296.     absEntry (startType);
  297.     }
  298. #endif /* ROM_COMPRESS */
  299. #ifdef ROM_COPY
  300. /*******************************************************************************
  301. *
  302. * romStart - generic ROM initialization for uncompressed ROM images
  303. *
  304. * This is the first C code executed after reset.
  305. *
  306. * This routine is called by the assembly start-up code in romInit().
  307. * It clears memory, copies ROM to RAM, and then jumps to the entry
  308. * point of the copied object code.
  309. *
  310. * RETURNS: N/A
  311. */
  312. void romStart
  313.     (
  314.     FAST int startType /* start type */
  315.     )
  316.     {
  317.     volatile FUNCPTR absEntry = (volatile FUNCPTR)RAM_DST_ADRS;
  318.     /* If cold booting, clear memory to avoid parity errors */
  319. #ifdef ROMSTART_BOOT_CLEAR
  320.     if (startType & BOOT_CLEAR)
  321.         bootClear();
  322. #endif
  323.     /* copy the main image into RAM */
  324.     copyLongs ((UINT *)ROM_DATA(binArrayStart),
  325. (UINT *)UNCACHED(RAM_DST_ADRS),
  326. (binArrayEnd - binArrayStart) / sizeof (long));
  327.     /* and jump to it */
  328.     absEntry (startType);
  329.     }
  330. #endif /* ROM_COPY */
  331. #ifdef ROM_RESIDENT
  332. /*******************************************************************************
  333. *
  334. * romStart - generic ROM initialization for ROM resident images
  335. *
  336. * This is the first C code executed after reset.
  337. *
  338. * This routine is called by the assembly start-up code in romInit().
  339. * It clears memory, copies ROM to RAM, and invokes the uncompressor.
  340. * It then jumps to the entry point of the uncompressed object code.
  341. *
  342. * RETURNS: N/A
  343. */
  344. void romStart
  345.     (
  346.     FAST int startType /* start type */
  347.     )
  348.     {
  349.     /* relocate the data segment into RAM */
  350.     copyLongs ((UINT *)ROM_DATA_ADRS, (UINT *)UNCACHED(RAM_DATA_ADRS),
  351. ((UINT)end - (UINT)RAM_DATA_ADRS) / sizeof (long));
  352.     /* If cold booting, clear memory to avoid parity errors */
  353. #ifdef ROMSTART_BOOT_CLEAR
  354.     if (startType & BOOT_CLEAR)
  355.         bootClear();
  356. #endif
  357.     /* and jump to the entry */
  358.     usrInit (startType);
  359.     }
  360. #endif /* ROM_RESIDENT */
  361. #ifdef ROMSTART_BOOT_CLEAR
  362. /******************************************************************************
  363. *
  364. * bootClear - clear memory
  365. *
  366. * If cold booting, clear memory not loaded with text & data.
  367. *
  368. * We are careful about initializing all memory (except
  369. * STACK_SAVE bytes) due to parity error generation (on
  370. * some hardware) at a later stage.  This is usually
  371. * caused by read accesses without initialization.
  372. */
  373. LOCAL void bootClear (void)
  374.     {
  375.     /* fill from the bottom of memory to the load image */
  376.     fillLongs ((UINT *)SYS_MEM_BOTTOM,
  377. ((UINT)RAM_DATA_ADRS - STACK_SAVE - (UINT)SYS_MEM_BOTTOM) /
  378. sizeof (long), 0);
  379.     /* fill from the load image to the top of memory */
  380.     fillLongs ((UINT *)end, ((UINT)SYS_MEM_TOP - (UINT)end) / sizeof(long), 0);
  381.     }
  382. /*******************************************************************************
  383. *
  384. * fillLongs - fill a buffer with a value a long at a time
  385. *
  386. * This routine fills the first <nlongs> longs of the buffer with <val>.
  387. */
  388. LOCAL void fillLongs
  389.     (
  390.     FAST UINT * buf, /* pointer to buffer              */
  391.     UINT nlongs, /* number of longs to fill        */
  392.     FAST UINT val /* char with which to fill buffer */
  393.     )
  394.     {
  395.     FAST UINT *bufend = buf + nlongs;
  396.     FAST UINT nchunks;
  397.     /* Hop by chunks of longs, for speed. */
  398.     for (nchunks = nlongs / 8; nchunks; --nchunks)
  399. {
  400. #if (CPU_FAMILY == MC680X0)
  401. *buf++ = val; /* 0 */
  402. *buf++ = val; /* 1 */
  403. *buf++ = val; /* 2 */
  404. *buf++ = val; /* 3 */
  405. *buf++ = val; /* 4 */
  406. *buf++ = val; /* 5 */
  407. *buf++ = val; /* 6 */
  408. *buf++ = val; /* 7 */
  409. #else
  410. buf[0] = val;
  411. buf[1] = val;
  412. buf[2] = val;
  413. buf[3] = val;
  414. buf[4] = val;
  415. buf[5] = val;
  416. buf[6] = val;
  417. buf[7] = val;
  418. buf += 8;
  419. #endif
  420. }
  421.     /* Do the remainder one long at a time. */
  422.     while (buf < bufend)
  423. *buf++ = val;
  424.     }
  425. #endif
  426. /*******************************************************************************
  427. *
  428. * copyLongs - copy one buffer to another a long at a time
  429. *
  430. * This routine copies the first <nlongs> longs from <source> to <destination>.
  431. */
  432. LOCAL void copyLongs
  433.     (
  434.     FAST UINT * source, /* pointer to source buffer      */
  435.     FAST UINT * destination, /* pointer to destination buffer */
  436.     UINT  nlongs /* number of longs to copy       */
  437.     )
  438.     {
  439.     FAST UINT *dstend = destination + nlongs;
  440.     FAST UINT nchunks;
  441.     /* Hop by chunks of longs, for speed. */
  442.     for (nchunks = nlongs / 8; nchunks; --nchunks)
  443. {
  444. #if (CPU_FAMILY == MC680X0)
  445. *destination++ = *source++; /* 0 */
  446. *destination++ = *source++; /* 1 */
  447. *destination++ = *source++; /* 2 */
  448. *destination++ = *source++; /* 3 */
  449. *destination++ = *source++; /* 4 */
  450. *destination++ = *source++; /* 5 */
  451. *destination++ = *source++; /* 6 */
  452. *destination++ = *source++; /* 7 */
  453. #else
  454. destination[0] = source[0];
  455. destination[1] = source[1];
  456. destination[2] = source[2];
  457. destination[3] = source[3];
  458. destination[4] = source[4];
  459. destination[5] = source[5];
  460. destination[6] = source[6];
  461. destination[7] = source[7];
  462. destination += 8, source += 8;
  463. #endif
  464. }
  465.     /* Do the remainder one long at a time. */
  466.     while (destination < dstend)
  467. *destination++ = *source++;
  468.     }