CPU: Wrong CPU Load %.
[tomato.git] / release / src / shared / load.c
blobeffb90f16390ceb861664d492b9c9f05f71cb1f0
1 /*
2 * Initialization and support routines for self-booting
3 * compressed image.
5 * Copyright 2004, 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$
16 #include <typedefs.h>
17 #include <bcmdefs.h>
18 #include <osl.h>
19 #include <bcmutils.h>
20 #include <sbutils.h>
21 #include <bcmdevs.h>
22 #include <sbconfig.h>
23 #include <sbchipc.h>
24 #include <hndmips.h>
25 #include <sbmemc.h>
26 #include <sflash.h>
27 #include <bcmsrom.h>
29 void c_main(unsigned long ra);
31 static sb_t *sbh;
32 static chipcregs_t *cc;
34 static struct sflash *sflash;
36 extern char text_start[], text_end[];
37 extern char data_start[], data_end[];
38 extern char bss_start[], bss_end[];
40 #define INBUFSIZ 4096 /* Buffer size */
41 #define WSIZE 0x8000 /* window size--must be a power of two, and */
42 /* at least 32K for zip's deflate method */
44 static uchar *inbuf; /* input buffer */
45 static ulong insize; /* valid bytes in inbuf */
46 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 static int
54 fill_inbuf(void)
56 int bytes;
58 for (insize = 0; insize < INBUFSIZ; insize += bytes, inoff += bytes) {
59 if (sflash) {
60 if ((bytes = sflash_read(cc, inoff, INBUFSIZ - insize,
61 &inbuf[insize])) < 0)
62 return bytes;
63 } else {
64 *((uint32 *) &inbuf[insize]) = *((uint32 *) KSEG1ADDR(SB_FLASH1 + inoff));
65 bytes = sizeof(uint32);
69 inptr = 1;
71 return inbuf[0];
74 /* Defines for gzip/bzip */
75 #define malloc(size) MALLOC(NULL, size)
76 #define free(addr) MFREE(NULL, addr, 0)
78 static void
79 error(char *x)
81 printf("\n\n%s\n\n -- System halted", x);
83 for (;;);
86 #if defined(USE_GZIP)
89 * gzip declarations
92 #define OF(args) args
93 #define STATIC static
95 #define memzero(s, n) memset ((s), 0, (n))
97 typedef unsigned char uch;
98 typedef unsigned short ush;
99 typedef unsigned long ulg;
101 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
103 /* Diagnostic functions (stubbed out) */
105 #define Assert(cond, msg)
106 #define Trace(x)
107 #define Tracev(x)
108 #define Tracevv(x)
109 #define Tracec(c, x)
110 #define Tracecv(c, x)
112 static uchar *window; /* Sliding window buffer */
113 static unsigned outcnt; /* bytes in window buffer */
115 static void
116 gzip_mark(void **ptr)
118 /* I'm not sure what the pourpose of this is, there are no malloc
119 * calls without free's in the gunzip code.
123 static void
124 gzip_release(void **ptr)
128 static void flush_window(void);
130 #include "gzip_inflate.c"
132 /* ===========================================================================
133 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
134 * (Used for the decompressed data only.)
136 static void
137 flush_window(void)
139 ulg c = crc;
140 unsigned n;
141 uch *in, *out, ch;
143 in = window;
144 out = &outbuf[bytes_out];
145 for (n = 0; n < outcnt; n++) {
146 ch = *out++ = *in++;
147 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
149 crc = c;
150 bytes_out += (ulg)outcnt;
151 outcnt = 0;
152 putc('.');
155 #elif defined(USE_BZIP2)
158 * bzip2 declarations
161 void bz_internal_error(int i)
163 char msg[128];
165 sprintf(msg, "Bzip2 internal error: %d", i);
166 error(msg);
169 #include "bzip2_inflate.c"
171 static int
172 bunzip2(void)
174 bz_stream bzstream;
175 int ret = 0;
177 bzstream.bzalloc = 0;
178 bzstream.bzfree = 0;
179 bzstream.opaque = 0;
180 bzstream.avail_in = 0;
182 if ((ret = BZ2_bzDecompressInit(&bzstream, 0, 1)) != BZ_OK)
183 return ret;
185 for (;;) {
186 if (bzstream.avail_in == 0) {
187 fill_inbuf();
188 bzstream.next_in = inbuf;
189 bzstream.avail_in = insize;
191 bzstream.next_out = &outbuf[bytes_out];
192 bzstream.avail_out = WSIZE;
193 if ((ret = BZ2_bzDecompress(&bzstream)) != BZ_OK)
194 break;
195 bytes_out = bzstream.total_out_lo32;
196 putc('.');
199 if (ret == BZ_STREAM_END)
200 ret = BZ2_bzDecompressEnd(&bzstream);
202 if (ret == BZ_OK)
203 ret = 0;
205 return ret;
208 #endif /* defined(USE_GZIP) */
210 extern char input_data[];
211 extern int input_len;
213 static void
214 load(void)
216 int ret = 0;
218 /* Offset from beginning of flash */
219 #ifdef CONFIG_XIP
220 inoff = ((ulong)text_end - (ulong)text_start) + ((ulong)input_data - (ulong)data_start);
221 #else
222 inoff = (ulong) input_data - (ulong) text_start;
223 #endif /* CONFIG_XIP */
224 outbuf = (uchar *) LOADADDR;
225 bytes_out = 0;
226 inbuf = malloc(INBUFSIZ); /* input buffer */
228 #if defined(USE_GZIP)
229 window = malloc(WSIZE);
230 printf("Decompressing...");
231 makecrc();
232 ret = gunzip();
233 #elif defined(USE_BZIP2)
234 /* Small decompression algorithm uses up to 2300k of memory */
235 printf("Decompressing...");
236 ret = bunzip2();
237 #else
238 printf("Copying...");
239 while (bytes_out < input_len) {
240 fill_inbuf();
241 memcpy(&outbuf[bytes_out], inbuf, insize);
242 bytes_out += insize;
244 #endif /* defined(USE_GZIP) */
245 if (ret) {
246 printf("error %d\n", ret);
247 } else
248 printf("done\n");
251 static void
252 sflash_self(chipcregs_t *cc)
254 unsigned char *start = text_start;
255 unsigned char *end = data_end;
256 unsigned char *cur = start;
257 unsigned int erasesize, len;
259 while (cur < end) {
260 /* Erase sector */
261 printf("Erasing sector 0x%x...", (cur - start));
262 if ((erasesize = sflash_erase(cc, cur - start)) < 0) {
263 printf("error\n");
264 break;
266 while (sflash_poll(cc, cur - start));
267 printf("done\n");
269 /* Write sector */
270 printf("Writing sector 0x%x...", (cur - start));
271 while (erasesize) {
272 if ((len = sflash_write(cc, cur - start, erasesize, cur)) < 0)
273 break;
274 while (sflash_poll(cc, cur - start));
275 cur += len;
276 erasesize -= len;
278 if (erasesize) {
279 printf("error\n");
280 break;
282 printf("done\n");
286 void
287 c_main(unsigned long ra)
289 /* Basic initialization */
290 sbh = (sb_t *)osl_init();
292 #ifndef CFG_UNCACHED
293 /* Initialize and turn caches on */
294 caches_on();
295 #endif /* CFG_UNCACHED */
297 cc = sb_setcore(sbh, SB_CC, 0);
299 /* Initialize serial flash */
300 sflash = cc ? sflash_init(cc) : NULL;
302 /* Copy self to flash if we booted from SDRAM */
303 if (PHYSADDR(ra) < SB_FLASH1) {
304 if (sflash)
305 sflash_self(cc);
308 /* Load binary */
309 load();
311 /* Flush all caches */
312 blast_dcache();
313 blast_icache();
315 /* Jump to load address */
316 ((void (*)(void)) LOADADDR)();