2 * Initialization and support routines for self-booting
5 * Copyright (C) 2009, Broadcom Corporation
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13 * $Id: load.c,v 1.19.2.1 2009/02/11 10:07:28 Exp $
28 void c_main(unsigned long ra
);
31 static chipcregs_t
*cc
;
34 extern unsigned char text_start
[], text_end
[];
35 extern unsigned char data_start
[], data_end
[];
36 extern char bss_start
[], bss_end
[];
38 #define INBUFSIZ 4096 /* Buffer size */
39 #define WSIZE 0x8000 /* window size--must be a power of two, and */
40 /* at least 32K for zip's deflate method */
42 static uchar
*inbuf
; /* input buffer */
43 #if !defined(USE_LZMA)
44 static ulong insize
; /* valid bytes in inbuf */
45 static ulong inptr
; /* index of next byte to be processed in inbuf */
48 static uchar
*outbuf
; /* output buffer */
49 static ulong bytes_out
; /* valid bytes in outbuf */
51 static ulong inoff
; /* offset of input data */
53 #if !defined(USE_LZMA)
59 for (insize
= 0; insize
< INBUFSIZ
; insize
+= bytes
, inoff
+= bytes
) {
60 *((uint32
*) &inbuf
[insize
]) = *((uint32
*) KSEG1ADDR(SI_FLASH1
+ inoff
));
61 bytes
= sizeof(uint32
);
69 /* Defines for gzip/bzip */
70 #define malloc(size) MALLOC(NULL, size)
71 #define free(addr) MFREE(NULL, addr, 0)
76 printf("\n\n%s\n\n -- System halted", x
);
91 #define memzero(s, n) memset ((s), 0, (n))
93 typedef unsigned char uch
;
94 typedef unsigned short ush
;
95 typedef unsigned long ulg
;
97 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
99 /* Diagnostic functions (stubbed out) */
101 #define Assert(cond, msg)
106 #define Tracecv(c, x)
108 static uchar
*window
; /* Sliding window buffer */
109 static unsigned outcnt
; /* bytes in window buffer */
112 gzip_mark(void **ptr
)
114 /* I'm not sure what the pourpose of this is, there are no malloc
115 * calls without free's in the gunzip code.
120 gzip_release(void **ptr
)
124 static void flush_window(void);
126 #include "gzip_inflate.c"
128 /* ===========================================================================
129 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
130 * (Used for the decompressed data only.)
140 out
= &outbuf
[bytes_out
];
141 for (n
= 0; n
< outcnt
; n
++) {
143 c
= crc_32_tab
[((int)c
^ ch
) & 0xff] ^ (c
>> 8);
146 bytes_out
+= (ulg
)outcnt
;
151 #elif defined(USE_BZIP2)
153 #include "bzip2_inflate.c"
159 void bz_internal_error(int i
)
163 sprintf(msg
, "Bzip2 internal error: %d", i
);
173 bzstream
.bzalloc
= 0;
176 bzstream
.avail_in
= 0;
178 if ((ret
= BZ2_bzDecompressInit(&bzstream
, 0, 1)) != BZ_OK
)
182 if (bzstream
.avail_in
== 0) {
184 bzstream
.next_in
= inbuf
;
185 bzstream
.avail_in
= insize
;
187 bzstream
.next_out
= &outbuf
[bytes_out
];
188 bzstream
.avail_out
= WSIZE
;
189 if ((ret
= BZ2_bzDecompress(&bzstream
)) != BZ_OK
)
191 bytes_out
= bzstream
.total_out_lo32
;
195 if (ret
== BZ_STREAM_END
)
196 ret
= BZ2_bzDecompressEnd(&bzstream
);
203 #elif defined(USE_LZMA)
206 #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
208 static void *SzAlloc(void *p
, size_t size
) { p
= p
; return malloc(size
); }
209 static void SzFree(void *p
, void *address
) { p
= p
; free(address
); }
210 static ISzAlloc g_Alloc
= { SzAlloc
, SzFree
};
214 * call LZMA decoder to decompress a LZMA block
217 decompressLZMA(unsigned char *src
, unsigned int srcLen
, unsigned char *dest
, unsigned int destLen
)
224 if (srcLen
< LZMA_HEADER_SIZE
)
225 return SZ_ERROR_INPUT_EOF
;
227 inSizePure
= srcLen
- LZMA_HEADER_SIZE
;
229 res
= LzmaDecode(dest
, &outSize
, src
+ LZMA_HEADER_SIZE
, &inSizePure
,
230 src
, LZMA_PROPS_SIZE
, LZMA_FINISH_ANY
, &status
, &g_Alloc
);
231 srcLen
= inSizePure
+ LZMA_HEADER_SIZE
;
233 if ((res
== SZ_OK
) ||
234 ((res
== SZ_ERROR_INPUT_EOF
) && (srcLen
== inSizePure
+ LZMA_HEADER_SIZE
)))
239 #endif /* defined(USE_GZIP) */
241 extern char input_data
[];
242 extern int input_len
;
250 /* Offset from beginning of flash */
252 inoff
= ((ulong
)text_end
- (ulong
)text_start
) + ((ulong
)input_data
- (ulong
)data_start
);
254 inoff
= (ulong
) input_data
- (ulong
) text_start
;
255 #endif /* CONFIG_XIP */
256 inbase
= (uint32
*) KSEG1ADDR(SI_FLASH1
+ inoff
);
257 outbuf
= (uchar
*) LOADADDR
;
259 inbuf
= malloc(INBUFSIZ
); /* input buffer */
261 #if defined(USE_GZIP)
262 window
= malloc(WSIZE
);
263 printf("Decompressing...");
266 #elif defined(USE_BZIP2)
267 /* Small decompression algorithm uses up to 2300k of memory */
268 printf("Decompressing...");
270 #elif defined(USE_LZMA)
271 printf("Decompressing...");
272 bytes_out
= (ulong
)_memsize
- (ulong
)PHYSADDR(outbuf
);
273 ret
= decompressLZMA((unsigned char *)inbase
, input_len
, outbuf
, bytes_out
);
275 printf("Copying...");
276 while (bytes_out
< input_len
) {
278 memcpy(&outbuf
[bytes_out
], inbuf
, insize
);
281 #endif /* defined(USE_GZIP) */
283 printf("error %d\n", ret
);
289 c_main(unsigned long ra
)
291 BCMDBG_TRACE(0x4c4400);
294 /* Initialize and turn caches on */
296 #endif /* CFG_UNCACHED */
298 BCMDBG_TRACE(0x4c4401);
300 /* Basic initialization */
301 sih
= (si_t
*)osl_init();
303 BCMDBG_TRACE(0x4c4402);
305 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
307 BCMDBG_TRACE(0x4c4403);
312 BCMDBG_TRACE(0x4c4405);
314 /* Flush all caches */
318 BCMDBG_TRACE(0x4c4406);
320 /* Jump to load address */
321 ((void (*)(void)) LOADADDR
)();