* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / ppc / chrpboot / main.c
blob80db69a7b10896bc00b90c622a9fc66602a57a76
1 /*
2 * Copyright (C) Paul Mackerras 1997.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9 #include "../coffboot/nonstdio.h"
10 #include "../coffboot/zlib.h"
12 extern void *finddevice(const char *);
13 extern int getprop(void *, const char *, void *, int);
14 void gunzip(void *, int, unsigned char *, int *);
16 #define get_16be(x) (*(unsigned short *)(x))
17 #define get_32be(x) (*(unsigned *)(x))
19 #define RAM_START 0x00000000
20 #define RAM_END (8<<20)
22 #define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
23 #define PROG_START 0x00010000
25 char *avail_ram;
26 char *end_avail;
28 extern char _end[];
29 extern char image_data[];
30 extern int image_len;
31 extern char initrd_data[];
32 extern int initrd_len;
35 chrpboot(int a1, int a2, void *prom)
37 int ns, oh, i;
38 unsigned sa, len;
39 void *dst;
40 unsigned char *im;
41 unsigned initrd_start, initrd_size;
42 extern char _start;
44 printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
46 if (initrd_len) {
47 initrd_size = initrd_len;
48 initrd_start = (RAM_END - initrd_size) & ~0xFFF;
49 a1 = initrd_start;
50 a2 = initrd_size;
51 printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r", initrd_start,
52 initrd_data,initrd_size);
53 memcpy((char *)initrd_start, initrd_data, initrd_size);
54 end_avail = (char *)initrd_start;
55 } else
56 end_avail = (char *) RAM_END;
57 im = image_data;
58 len = image_len;
59 dst = (void *) PROG_START;
60 if (im[0] == 0x1f && im[1] == 0x8b) {
61 avail_ram = (char *)RAM_FREE;
62 printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
63 gunzip(dst, 0x400000, im, &len);
64 printf("done %u bytes\n\r", len);
65 } else {
66 memmove(dst, im, len);
69 flush_cache(dst, len);
71 sa = (unsigned long)PROG_START;
72 printf("start address = 0x%x\n\r", sa);
74 (*(void (*)())sa)(0, 0, prom, a1, a2);
76 printf("returned?\n\r");
78 pause();
81 void *zalloc(void *x, unsigned items, unsigned size)
83 void *p = avail_ram;
85 size *= items;
86 size = (size + 7) & -8;
87 avail_ram += size;
88 if (avail_ram > end_avail) {
89 printf("oops... out of memory\n\r");
90 pause();
92 return p;
95 void zfree(void *x, void *addr, unsigned nb)
99 #define HEAD_CRC 2
100 #define EXTRA_FIELD 4
101 #define ORIG_NAME 8
102 #define COMMENT 0x10
103 #define RESERVED 0xe0
105 #define DEFLATED 8
107 void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
109 z_stream s;
110 int r, i, flags;
112 /* skip header */
113 i = 10;
114 flags = src[3];
115 if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
116 printf("bad gzipped data\n\r");
117 exit();
119 if ((flags & EXTRA_FIELD) != 0)
120 i = 12 + src[10] + (src[11] << 8);
121 if ((flags & ORIG_NAME) != 0)
122 while (src[i++] != 0)
124 if ((flags & COMMENT) != 0)
125 while (src[i++] != 0)
127 if ((flags & HEAD_CRC) != 0)
128 i += 2;
129 if (i >= *lenp) {
130 printf("gunzip: ran out of data in header\n\r");
131 exit();
134 s.zalloc = zalloc;
135 s.zfree = zfree;
136 r = inflateInit2(&s, -MAX_WBITS);
137 if (r != Z_OK) {
138 printf("inflateInit2 returned %d\n\r", r);
139 exit();
141 s.next_in = src + i;
142 s.avail_in = *lenp - i;
143 s.next_out = dst;
144 s.avail_out = dstlen;
145 r = inflate(&s, Z_FINISH);
146 if (r != Z_OK && r != Z_STREAM_END) {
147 printf("inflate returned %d msg: %s\n\r", r, s.msg);
148 exit();
150 *lenp = s.next_out - (unsigned char *) dst;
151 inflateEnd(&s);