Broadcom SDK and wireless driver: another attempt to update to ver. 5.10.147.0
[tomato.git] / release / src-rt / shared / load.c
blobb5a7e3506380ae3c9a2c2aa671580cbc34be405a
1 /*
2 * Initialization and support routines for self-booting
3 * compressed image.
5 * Copyright (C) 2009, Broadcom Corporation
6 * All Rights Reserved.
7 *
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 $
16 #include <typedefs.h>
17 #include <bcmdefs.h>
18 #include <osl.h>
19 #include <bcmutils.h>
20 #include <bcmdevs.h>
21 #include <hndsoc.h>
22 #include <siutils.h>
23 #include <sbchipc.h>
24 #include <hndmips.h>
25 #include <sbmemc.h>
26 #include <bcmsrom.h>
28 void c_main(unsigned long ra);
30 static si_t *sih;
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 */
46 #endif /* USE_GZIP */
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)
54 static int
55 fill_inbuf(void)
57 int bytes;
59 for (insize = 0; insize < INBUFSIZ; insize += bytes, inoff += bytes) {
60 *((uint32 *) &inbuf[insize]) = *((uint32 *) KSEG1ADDR(SI_FLASH1 + inoff));
61 bytes = sizeof(uint32);
64 inptr = 1;
66 return inbuf[0];
69 /* Defines for gzip/bzip */
70 #define malloc(size) MALLOC(NULL, size)
71 #define free(addr) MFREE(NULL, addr, 0)
73 static void
74 error(char *x)
76 printf("\n\n%s\n\n -- System halted", x);
78 for (;;);
80 #endif /* USE_LZMA */
82 #if defined(USE_GZIP)
85 * gzip declarations
88 #define OF(args) args
89 #define STATIC static
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)
102 #define Trace(x)
103 #define Tracev(x)
104 #define Tracevv(x)
105 #define Tracec(c, x)
106 #define Tracecv(c, x)
108 static uchar *window; /* Sliding window buffer */
109 static unsigned outcnt; /* bytes in window buffer */
111 static void
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.
119 static void
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.)
132 static void
133 flush_window(void)
135 ulg c = crc;
136 unsigned n;
137 uch *in, *out, ch;
139 in = window;
140 out = &outbuf[bytes_out];
141 for (n = 0; n < outcnt; n++) {
142 ch = *out++ = *in++;
143 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
145 crc = c;
146 bytes_out += (ulg)outcnt;
147 outcnt = 0;
148 putc('.');
151 #elif defined(USE_BZIP2)
153 #include "bzip2_inflate.c"
156 * bzip2 declarations
159 void bz_internal_error(int i)
161 char msg[128];
163 sprintf(msg, "Bzip2 internal error: %d", i);
164 error(msg);
167 static int
168 bunzip2(void)
170 bz_stream bzstream;
171 int ret = 0;
173 bzstream.bzalloc = 0;
174 bzstream.bzfree = 0;
175 bzstream.opaque = 0;
176 bzstream.avail_in = 0;
178 if ((ret = BZ2_bzDecompressInit(&bzstream, 0, 1)) != BZ_OK)
179 return ret;
181 for (;;) {
182 if (bzstream.avail_in == 0) {
183 fill_inbuf();
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)
190 break;
191 bytes_out = bzstream.total_out_lo32;
192 putc('.');
195 if (ret == BZ_STREAM_END)
196 ret = BZ2_bzDecompressEnd(&bzstream);
198 if (ret == BZ_OK)
199 ret = 0;
201 return ret;
203 #elif defined(USE_LZMA)
205 #include "LzmaDec.c"
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 };
212 extern int _memsize;
214 * call LZMA decoder to decompress a LZMA block
216 static int
217 decompressLZMA(unsigned char *src, unsigned int srcLen, unsigned char *dest, unsigned int destLen)
219 int res;
220 SizeT inSizePure;
221 ELzmaStatus status;
222 SizeT outSize;
224 if (srcLen < LZMA_HEADER_SIZE)
225 return SZ_ERROR_INPUT_EOF;
227 inSizePure = srcLen - LZMA_HEADER_SIZE;
228 outSize = destLen;
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)))
235 res = 0;
236 return res;
239 #endif /* defined(USE_GZIP) */
241 extern char input_data[];
242 extern int input_len;
244 static void
245 load(void)
247 int ret = 0;
248 uint32 *inbase;
250 /* Offset from beginning of flash */
251 #ifdef CONFIG_XIP
252 inoff = ((ulong)text_end - (ulong)text_start) + ((ulong)input_data - (ulong)data_start);
253 #else
254 inoff = (ulong) input_data - (ulong) text_start;
255 #endif /* CONFIG_XIP */
256 inbase = (uint32 *) KSEG1ADDR(SI_FLASH1 + inoff);
257 outbuf = (uchar *) LOADADDR;
258 bytes_out = 0;
259 inbuf = malloc(INBUFSIZ); /* input buffer */
261 #if defined(USE_GZIP)
262 window = malloc(WSIZE);
263 printf("Decompressing...");
264 makecrc();
265 ret = gunzip();
266 #elif defined(USE_BZIP2)
267 /* Small decompression algorithm uses up to 2300k of memory */
268 printf("Decompressing...");
269 ret = bunzip2();
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);
274 #else
275 printf("Copying...");
276 while (bytes_out < input_len) {
277 fill_inbuf();
278 memcpy(&outbuf[bytes_out], inbuf, insize);
279 bytes_out += insize;
281 #endif /* defined(USE_GZIP) */
282 if (ret) {
283 printf("error %d\n", ret);
284 } else
285 printf("done\n");
288 void
289 c_main(unsigned long ra)
291 BCMDBG_TRACE(0x4c4400);
293 #ifndef CFG_UNCACHED
294 /* Initialize and turn caches on */
295 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);
309 /* Load binary */
310 load();
312 BCMDBG_TRACE(0x4c4405);
314 /* Flush all caches */
315 blast_dcache();
316 blast_icache();
318 BCMDBG_TRACE(0x4c4406);
320 /* Jump to load address */
321 ((void (*)(void)) LOADADDR)();