bootInit.c
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:16k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* bootInit.c - ROM initialization module */
  2. /* Copyright 1989-1999 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 04x,10jun99,jpd  fix error when BOOTCODE_IN_RAM defined (SPR #27775).
  8. 04w,13nov98,cdp  make Thumb support for ARM CPUs dependent on ARM_THUMB.
  9. 04w,10feb99,db   Fix to ensure that default bootline gets copied for
  10.  standalone and rom-resident images(SPR #21763).
  11. 04v,05oct98,jmp  doc: cleanup.
  12. 04u,17apr98,cdp  backed out 04t and made absEntry volatile for ARM.
  13. 04t,16apr98,cdp  for ARM, make UNCOMPRESS entry point in RAM.
  14. 04s,20mar98,cdp  make ROM_COPY_SIZE subject to #ifndef.
  15. 04r,11nov97,cdp  ARM7TDMI_T: force romStart to call entry point in Thumb state.
  16.  (SPR# 9716)
  17. 04q,14jul97,tam  changed remaining references to bfillLong to fillLong. 
  18. 04p,12feb97,dat  Added USER_RESERVED_MEM, SYS_MEM_TOP, SYS_MEM_BOTTOM, SPR 8030
  19. 04o,04feb97,ms   fixed compiler warning about protoype for bcopyLongs.
  20. 04o,28nov96,cdp  added ARM support.
  21. 04n,03sep96,hdn  added the compression support for pc[34]86 BSP.
  22. 04m,19aug96,ms   added UNCMP_RTN macro to use inflate instead of uncompress
  23. 04l,21jun96,jmb  long modhist -- deleted entries prior to 1994.  SPR #6528
  24. 03k,10jun96,tam  added rom resident support for PPC architecture. 
  25. 03j,14may96,dat  fixed compiler warnings for copyLongs, fillLongs. SPR #6536
  26. 03i,06mar96,tpr  changed absEntry to be volatile for PowerPC.
  27. 03h,22aug95,hdn  added support for I80X86.
  28. 03g,14mar95,caf  restored mips resident rom support (SPR #3856).
  29. 03f,16feb95,jdi  doc format change.
  30. 03f,23may95,yao  define binArrayStart and binArrayEnd for PowerPC
  31.  because tools don't prepend "_".
  32. 03e,09dec94,caf  undid mod 03a, use sdata for resident roms (SPR #3856).
  33. 03d,22jun94,caf  undid 16-byte alignment portion of mod 03c, below.
  34. 03c,14jun94,cd   corrected definitions of etext, edata and end.
  35.    +caf  for R4000 resident ROMs: data starts on 16-byte boundary.
  36.  for R4000 uncompressed ROMs: added volatile to absEntry type.
  37. */
  38. /*
  39. DESCRIPTION
  40. This module provides a generic boot ROM facility.  The target-specific
  41. romInit.s module performs the minimal preliminary board initialization and
  42. then jumps to the C routine romStart().  This routine, still executing out
  43. of ROM, copies the first stage of the startup code to a RAM address and
  44. jumps to it.  The next stage clears memory and then uncompresses the
  45. remainder of ROM into the final VxWorks ROM image in RAM.
  46. A modified version of the Public Domain f3zlibfP library is used to
  47. uncompress the VxWorks boot ROM executable linked with it.  Compressing
  48. object code typically achieves over 55% compression, permitting much
  49. larger systems to be burned into ROM.  The only expense is the added few
  50. seconds delay while the first two stages complete.
  51. ROM AND RAM MEMORY LAYOUT
  52. Example memory layout for a 1-megabyte board:
  53. .CS
  54.     --------------  0x00100000 = LOCAL_MEM_SIZE = sysMemTop()
  55.     |            |
  56.     |    RAM     |
  57.     |  0 filled  |
  58.     |            |
  59.     |------------| = (romInit+ROM_COPY_SIZE) or binArrayStart
  60.     | ROM image  |
  61.     |----------- |  0x00090000  = RAM_HIGH_ADRS
  62.     | STACK_SAVE |
  63.     |------------|
  64.     |            |  0x00080000  = 0.5 Megabytes
  65.     |            |
  66.     |            |
  67.     | 0 filled   |
  68.     |            |
  69.     |            |  0x00001000  = RAM_ADRS & RAM_LOW_ADRS
  70.     |            |
  71.     |            |  exc vectors, bp anchor, exc msg, bootline
  72.     |            |
  73.     |            |
  74.     --------------  0x00000000  = LOCAL_MEM_LOCAL_ADRS
  75. .CE
  76. .CS
  77.     --------------
  78.     |    ROM     |
  79.     |            |  0xff8xxxxx  = binArrayStart
  80.     |            |
  81.     |            |  0xff800008  = ROM_TEXT_ADRS
  82.     --------------  0xff800000  = ROM_BASE_ADRS
  83. .CE
  84. SEE ALSO:
  85. inflate(), romInit(), and deflate
  86. AUTHOR
  87. The original compression software for zlib was written by Jean-loup Gailly
  88. and Mark Adler. See the manual pages of inflate and deflate for
  89. more information on their freely available compression software.
  90. */
  91. #include "vxWorks.h"
  92. #include "sysLib.h"
  93. #include "config.h"
  94. #include "errno.h"
  95. #include "sioLib.h"
  96. #define UNCMP_RTN inflate
  97. #ifndef USER_RESERVED_MEM
  98. #   define USER_RESERVED_MEM 0
  99. #endif
  100. /*
  101.  * If memory is to be cleared, it will be cleared from SYS_MEM_BOTTOM
  102.  * up to (but not including) SYS_MEM_TOP, except for text and data segments.
  103.  * The user reserved area is not cleared.
  104.  */
  105. #define SYS_MEM_TOP 
  106. (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE - USER_RESERVED_MEM)
  107. #define SYS_MEM_BOTTOM 
  108. (LOCAL_MEM_LOCAL_ADRS + RESERVED)
  109. IMPORT void romInit ();
  110. IMPORT STATUS UNCMP_RTN ();
  111. IMPORT void usrInit ();
  112. IMPORT void sysInitAlt ();
  113. IMPORT void start ();
  114. #if ((CPU_FAMILY == MIPS) || (CPU_FAMILY==PPC))
  115. #define binArrayStart _binArrayStart
  116. #define binArrayEnd _binArrayEnd
  117. #define RESIDENT_DATA RAM_DST_ADRS
  118. #else
  119. #define RESIDENT_DATA (&sdata)
  120. IMPORT char sdata; /* defined in romInit.s */
  121. #endif
  122. IMPORT UCHAR binArrayStart []; /* compressed binary image */
  123. IMPORT UCHAR binArrayEnd; /* end of compressed binary image */
  124. IMPORT char etext []; /* defined by the loader */
  125. IMPORT char edata []; /* defined by the loader */
  126. IMPORT char end []; /* defined by the loader */
  127. #ifndef RAM_DST_ADRS                 /* default uncompress dest. */
  128. #define RAM_DST_ADRS        RAM_HIGH_ADRS
  129. #endif
  130. /* If the boot code is in RAM and the RAM is already initialized,
  131.  * clearing the RAM is not necessary.  Macro BOOTCODE_IN_RAM is
  132.  * used not to clear the RAM.
  133.  */
  134. #ifdef BOOTCODE_IN_RAM /* not to clear RAM */
  135. #undef ROM_TEXT_ADRS
  136. #undef ROM_BASE_ADRS
  137. #define ROM_TEXT_ADRS ((UINT)romInit)
  138. #define ROM_BASE_ADRS ((UINT)romInit)
  139. #endif /* BOOTCODE_IN_RAM */
  140. #if defined (UNCOMPRESS) || defined (ROM_RESIDENT)
  141. #ifndef ROM_COPY_SIZE
  142. #define ROM_COPY_SIZE (ROM_SIZE - (ROM_TEXT_ADRS - ROM_BASE_ADRS))
  143. #endif
  144. #endif /* UNCOMPRESS */
  145. #define ROM_OFFSET(adr) (((UINT)adr - (UINT)romInit) + ROM_TEXT_ADRS)
  146. /* forward declarations */
  147. LOCAL void copyLongs (FAST UINT *source, FAST UINT *destination, UINT nlongs);
  148. #ifndef BOOTCODE_IN_RAM
  149. LOCAL void fillLongs (FAST UINT *buf, UINT nlongs, FAST UINT val);
  150. #endif /* BOOTCODE_IN_RAM */
  151. #ifdef BROADCOM_BSP
  152. #include "drv/sio/ns16552Sio.h"
  153. #undef UART_REG
  154. #define XTAL COM1_FREQ
  155. #define UART_REG(reg)  (reg)
  156. void sysSerialPrintString2 (char a, char b, char c, char d);
  157. void sysLedDsply2 (char a, char b, char c, char d);
  158. void serialPollInit (int channel);
  159. void serialPutc(int c);
  160. void serialOutByte (int addr, UCHAR c);
  161. UCHAR serialInByte (int addr);
  162. #endif
  163. #define ROMPRINT(a,b,c,d)  
  164.         if (romPrintRtn != NULL) (romPrintRtn) (a,b,c,d)
  165. /* Defaults set to external UART properties */
  166. unsigned char *uartBaseAddr = MBZ_DUART_CHAN0_ASM;
  167. int serialClockFreq = COM1_FREQ;
  168. /*******************************************************************************
  169. *
  170. * romStart - generic ROM initialization
  171. *
  172. * This is the first C code executed after reset.
  173. *
  174. * This routine is called by the assembly start-up code in romInit().
  175. * It clears memory, copies ROM to RAM, and possibly invokes the uncompressor.
  176. * It then jumps to the entry point of the uncompressed object code.
  177. *
  178. * RETURNS: N/A
  179. */
  180. void romStart
  181.     (
  182.     FAST int startType /* start type */
  183.     )
  184.     {
  185. #if ((CPU_FAMILY==SPARC) || (CPU_FAMILY==MIPS) || (CPU_FAMILY==I80X86) || 
  186.      (CPU_FAMILY==PPC) || (CPU_FAMILY==ARM))
  187.     volatile /* to force absolute adressing */
  188. #endif /* (CPU_FAMILY==SPARC) */
  189.     FUNCPTR absEntry; /* to avoid PC Relative Jump Subroutine */
  190. #if (CPU_FAMILY==ARM) && (!defined(ROM_RESIDENT)) && !defined(BOOTCODE_IN_RAM)
  191.     VOIDFUNCPTR ramfillLongs = fillLongs;     /* force call to RAM */
  192. #define fillLongs(a,b,c) ramfillLongs(a,b,c)
  193. #endif  /* (CPU_FAMILY==ARM) */
  194.     /* Check board type...see if we have LEDs or not.  If no LED's
  195.     *  use serial
  196.     */
  197. #ifdef BROADCOM_BSP
  198.     VOIDFUNCPTR romPrintRtn = NULL;
  199. #endif
  200. #ifdef BRINGUP
  201.     UINT8 boardId;
  202.     romPrintRtn = (VOIDFUNCPTR) ROM_OFFSET(sysLedDsply2);
  203.     boardId = SYS_REVID_GET();
  204.     if (boardId == BOARD_ID_LM_1)
  205.         {
  206.         romPrintRtn = (VOIDFUNCPTR) (ROM_OFFSET(sysSerialPrintString2));
  207.         ((FUNCPTR) ROM_OFFSET (serialPollInit))(0);
  208.         ROMPRINT('A'+ ((boardId >> 4) - 10),
  209.                  'A'+ ((boardId & 0xF) - 10),
  210.                  '0' + (boardId >> 4),
  211.                  '0'+(boardId & 0xF)
  212.                  );
  213.         }
  214. #endif
  215.     ROMPRINT ('C', 'H', 'K', '0');
  216.     /*
  217.      * Copy from ROM to RAM, minus the compressed image
  218.      * if compressed boot ROM which relies on binArray
  219.      * appearing last in DATA segment.
  220.      */
  221. #ifdef ROM_RESIDENT
  222.     /* If ROM resident code, then copy only data segment
  223.      * from ROM to RAM, initialize memory and jump
  224.      * to usrInit.
  225.      */
  226.     
  227. #if  (CPU_FAMILY == SPARC)
  228.     copyLongs ((UINT *)(etext + 8), (UINT *) RESIDENT_DATA,
  229. #elif ((CPU_FAMILY == MIPS) || (CPU_FAMILY == PPC))
  230.     copyLongs ((UINT *)(etext + 0), (UINT *) RESIDENT_DATA,
  231. #else
  232.     copyLongs ((UINT *)(etext + 4), (UINT *) RESIDENT_DATA,
  233. #endif
  234.  ((UINT) edata - (UINT) RESIDENT_DATA) / sizeof (long));
  235. #else /* ROM_RESIDENT */
  236. #ifdef UNCOMPRESS
  237. #if (CPU_FAMILY == MIPS)
  238.     /*
  239.      * copy text to uncached locations to avoid problems with
  240.      * copy back caches
  241.      */
  242.     ((FUNCPTR)ROM_OFFSET(copyLongs)) (ROM_TEXT_ADRS, (UINT)K0_TO_K1(romInit),
  243. ROM_COPY_SIZE / sizeof (long));
  244. #else /* CPU_FAMILY == MIPS */
  245.     ((FUNCPTR)ROM_OFFSET(copyLongs)) (ROM_TEXT_ADRS, (UINT)romInit,
  246. ROM_COPY_SIZE / sizeof (long));
  247. #endif /* CPU_FAMILY == MIPS */
  248.     ROMPRINT ('C', 'H', 'K', '1');
  249. #else /* UNCOMPRESS */
  250. #if (CPU_FAMILY == MIPS)
  251.     /*
  252.      * copy text to uncached locations to avoid problems with
  253.      * copy back caches
  254.      * copy the entire data segment because there is no way to ensure that
  255.      * binArray is the last thing in the data segment because of GP relative
  256.      * addressing
  257.      */
  258.     ((FUNCPTR)ROM_OFFSET(copyLongs)) (ROM_TEXT_ADRS, (UINT)K0_TO_K1(romInit),
  259. ((UINT)edata - (UINT)romInit) / sizeof (long));
  260. #else /* CPU_FAMILY == MIPS */
  261.     ((FUNCPTR)ROM_OFFSET(copyLongs)) (ROM_TEXT_ADRS, (UINT)romInit,
  262. ((UINT)binArrayStart - (UINT)romInit) / sizeof (long));
  263. #endif /* CPU_FAMILY == MIPS */
  264.     ROMPRINT ('C', 'H', 'K', '2');
  265. #endif /* UNCOMPRESS */
  266. #endif /* ROM_RESIDENT */
  267. #if (CPU_FAMILY != MIPS) && (!defined (BOOTCODE_IN_RAM))
  268.     /* clear all memory if cold booting */
  269.     if (startType & BOOT_CLEAR)
  270. {
  271. #ifdef ROM_RESIDENT
  272. /* Clear memory not loaded with text & data.
  273.  *
  274.  * We are careful about initializing all memory (except
  275.  * STACK_SAVE bytes) due to parity error generation (on
  276.  * some hardware) at a later stage.  This is usually
  277.  * caused by read accesses without initialization.
  278.  */
  279. fillLongs ((UINT *)SYS_MEM_BOTTOM,
  280. ((UINT) RESIDENT_DATA - STACK_SAVE - (UINT)SYS_MEM_BOTTOM)
  281. / sizeof(long), 0);
  282. fillLongs (((UINT *) edata),
  283. ((UINT)SYS_MEM_TOP - ((UINT) edata)) / sizeof(long), 0);
  284. #else /* ROM_RESIDENT */
  285. fillLongs ((UINT *)(SYS_MEM_BOTTOM),
  286. ((UINT)romInit - STACK_SAVE - (UINT)SYS_MEM_BOTTOM) /
  287. sizeof(long), 0);
  288.         ROMPRINT ('C', 'H', 'K', '3');
  289. #if     defined (UNCOMPRESS)
  290. fillLongs ((UINT *)((UINT)romInit + ROM_COPY_SIZE),
  291.     ((UINT)SYS_MEM_TOP - ((UINT)romInit + ROM_COPY_SIZE))
  292.     / sizeof(long), 0);
  293. #else
  294. fillLongs ((UINT *)binArrayStart,
  295. ((UINT)SYS_MEM_TOP - (UINT)binArrayStart) / sizeof (long), 0);
  296. #endif  /* UNCOMPRESS */
  297.         ROMPRINT ('C', 'H', 'K', '4');
  298. #endif  /* ROM_RESIDENT */
  299. /* 
  300.  * Ensure the boot line is null. This is necessary for those
  301.  * targets whose boot line is excluded from cleaning.
  302.  */
  303. *(BOOT_LINE_ADRS) = EOS;
  304. }
  305. #endif /* (CPU_FAMILY != MIPS) && (!defined (BOOTCODE_IN_RAM)) */
  306.     /* jump to VxWorks entry point (after uncompressing) */
  307. #if defined (UNCOMPRESS) || defined (ROM_RESIDENT)
  308. #if (CPU_FAMILY == I960)
  309.     absEntry = (FUNCPTR)sysInitAlt; /* reinit proc tbl */
  310. #else
  311.     absEntry = (FUNCPTR)usrInit; /* on to bootConfig */
  312. #endif /* CPU_FAMILY == I960 */
  313. #else
  314.     {
  315. #if (CPU_FAMILY == MIPS)
  316.     volatile FUNCPTR absUncompress = (FUNCPTR) UNCMP_RTN;
  317.     if ((absUncompress) ((UCHAR *)ROM_OFFSET(binArrayStart),
  318.  (UCHAR *)K0_TO_K1(RAM_DST_ADRS),
  319.  (int)((UINT)&binArrayEnd - (UINT)binArrayStart)) != OK)
  320. #elif (CPU_FAMILY == I80X86) || (CPU_FAMILY == ARM)
  321.     volatile FUNCPTR absUncompress = (FUNCPTR) UNCMP_RTN;
  322.     if ((absUncompress) ((UCHAR *)ROM_OFFSET(binArrayStart),
  323.             (UCHAR *)RAM_DST_ADRS, &binArrayEnd - binArrayStart) != OK)
  324. #else
  325.     if (UNCMP_RTN ((UCHAR *)ROM_OFFSET(binArrayStart),
  326.             (UCHAR *)RAM_DST_ADRS, &binArrayEnd - binArrayStart) != OK)
  327. #endif /* (CPU_FAMILY == MIPS) */
  328. return; /* if we return then ROM's will halt */
  329.     ROMPRINT ('C', 'H', 'K', '5');
  330.     absEntry = (FUNCPTR)RAM_DST_ADRS; /* compressedEntry () */
  331.     }
  332. #endif /* defined UNCOMPRESS || defined ROM_RESIDENT */
  333. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  334.     absEntry = (FUNCPTR)((UINT32)absEntry | 1); /* force Thumb state */
  335. #endif /* CPU_FAMILY == ARM */
  336.     (absEntry) (startType);
  337.     }
  338. #if     (CPU_FAMILY==ARM) && (!defined(ROM_RESIDENT))
  339. #undef fillLongs
  340. #endif  /* (CPU_FAMILY==ARM) */
  341. extern void displaymsg (char *);
  342. /*****************************************************************************
  343. *
  344. * sysLedDsply2 - print 4 characters to alphanumeric LEDs
  345. *
  346. * This routine should only be used when running from the bootrom.
  347. * After the bootrom image has been copied to ram and decompressed, you
  348. * should use sysLedDsply() to write a string to the LEDs.
  349. *
  350. * Returns:  N/A
  351. */
  352. void sysLedDsply2
  353.     (
  354.     char a,
  355.     char b,
  356.     char c,
  357.     char d
  358.     )
  359.     {
  360.     char str[4];
  361.     VOIDFUNCPTR func = (VOIDFUNCPTR) (ROM_OFFSET(displaymsg));
  362.     str[0] = a;
  363.     str[1] = b;
  364.     str[2] = c;
  365.     str[3] = d;
  366.     func (str);
  367.     }
  368. /*******************************************************************************
  369. *
  370. * copyLongs - copy one buffer to another a long at a time
  371. *
  372. * This routine copies the first <nlongs> longs from <source> to <destination>.
  373. */
  374. LOCAL void copyLongs (source, destination, nlongs)
  375.     FAST UINT *source; /* pointer to source buffer      */
  376.     FAST UINT *destination; /* pointer to destination buffer */
  377.     UINT nlongs; /* number of longs to copy       */
  378.     {
  379.     FAST UINT *dstend = destination + nlongs;
  380.     while (destination < dstend)
  381. *destination++ = *source++;
  382.     }
  383. #ifndef BOOTCODE_IN_RAM
  384. /*******************************************************************************
  385. *
  386. * fillLongs - fill a buffer with a value a long at a time
  387. *
  388. * This routine fills the first <nlongs> longs of the buffer with <val>.
  389. */
  390. LOCAL void fillLongs (buf, nlongs, val)
  391.     FAST UINT *buf; /* pointer to buffer              */
  392.     UINT nlongs; /* number of longs to fill        */
  393.     FAST UINT val; /* char with which to fill buffer */
  394.     {
  395.     FAST UINT *bufend = buf + nlongs;
  396.     while (buf < bufend)
  397. *buf++ = val;
  398.     }
  399. #endif /* BOOTCODE_IN_RAM */
  400. UCHAR serialInByte
  401.     (
  402.     int addr
  403.     )
  404.     {
  405.     return *(volatile unsigned char *) ((MBZ_DUART_CHAN0_ASM)+(addr^3));
  406.     }
  407. void serialOutByte
  408.     (
  409.     int addr,
  410.     UCHAR c
  411.     )
  412.     {
  413.     *(volatile unsigned char *) ((MBZ_DUART_CHAN0_ASM)+(addr^3)) = c;
  414.     }
  415. void serialPutc(int c)
  416. {
  417.     int i = 10000;
  418.     FUNCPTR inbyte = (FUNCPTR) (ROM_OFFSET(serialInByte));
  419.     VOIDFUNCPTR outbyte = (VOIDFUNCPTR) (ROM_OFFSET(serialOutByte));
  420.     while (!(inbyte (UART_REG(LSR)) & 0x40) && i--)
  421.         ;
  422.     outbyte (UART_REG(THR), c);
  423. }
  424. void serialPollInit
  425.    (
  426.    int channel
  427.    )
  428.    {
  429.    VOIDFUNCPTR func = (VOIDFUNCPTR) (ROM_OFFSET(serialOutByte));
  430.    func (UART_REG (LCR), LCR_DLAB);
  431.    func (UART_REG (DLL), BAUD_LO (CONSOLE_BAUD_RATE));
  432.    func (UART_REG (DLM), BAUD_HI (CONSOLE_BAUD_RATE));
  433.    func (UART_REG (LCR), CHAR_LEN_8 | ONE_STOP | PARITY_NONE);
  434.    func (UART_REG (MCR), 0xb);
  435.    }
  436. /*****************************************************************************
  437. *
  438. * sysSerialPrintString2 - print 4 characters to the serial port
  439. *
  440. * This routine should only be used when running from the bootrom.
  441. * After the bootrom image has been copied to ram and decompressed, you
  442. * should use sysSerialPrintString() for general purpose string printing.
  443. *
  444. * Returns:  N/A
  445. */
  446. void sysSerialPrintString2(char a, char b, char c, char d)
  447. {
  448.     FUNCPTR func = (FUNCPTR) (ROM_OFFSET(serialPutc));
  449.     func (a);
  450.     func (b);
  451.     func (c);
  452.     func (d);
  453.     func ('n');
  454.     func ('r');
  455. }