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.
13 extern void *finddevice(const char *);
14 extern int getprop(void *, const char *, void *, int);
15 void gunzip(void *, int, unsigned char *, int *);
17 #define get_16be(x) (*(unsigned short *)(x))
18 #define get_32be(x) (*(unsigned *)(x))
20 #define RAM_START 0xc0000000
21 #define PROG_START RAM_START
22 #define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */
24 #define RAM_FREE (RAM_START + 0x540000) /* after image of coffboot */
29 coffboot(int a1
, int a2
, void *prom
)
33 struct external_filehdr
*eh
;
34 struct external_scnhdr
*sp
;
35 struct external_scnhdr
*isect
, *rsect
;
40 unsigned initrd_start
, initrd_size
;
42 printf("coffboot starting\n");
43 options
= finddevice("/options");
44 if (options
== (void *) -1)
46 if (getprop(options
, "load-base", &loadbase
, sizeof(loadbase
))
47 != sizeof(loadbase
)) {
48 printf("error getting load-base\n");
51 setup_bats(RAM_START
);
53 loadbase
+= RAM_START
;
54 eh
= (struct external_filehdr
*) loadbase
;
55 ns
= get_16be(eh
->f_nscns
);
56 oh
= get_16be(eh
->f_opthdr
);
58 sp
= (struct external_scnhdr
*) (loadbase
+ sizeof(struct external_filehdr
) + oh
);
60 for (i
= 0; i
< ns
; ++i
, ++sp
) {
61 if (strcmp(sp
->s_name
, "image") == 0)
63 else if (strcmp(sp
->s_name
, "initrd") == 0)
67 printf("image section not found\n");
71 if (rsect
!= NULL
&& (initrd_size
= get_32be(rsect
->s_size
)) != 0) {
72 initrd_start
= (RAM_END
- initrd_size
) & ~0xFFF;
75 printf("initial ramdisk at %x (%u bytes)\n",
76 initrd_start
, initrd_size
);
77 memcpy((char *) initrd_start
,
78 (char *) (loadbase
+ get_32be(rsect
->s_scnptr
)),
80 end_avail
= (char *) initrd_start
;
82 end_avail
= (char *) RAM_END
;
85 im
= (unsigned char *)(loadbase
+ get_32be(isect
->s_scnptr
));
86 len
= get_32be(isect
->s_size
);
87 dst
= (void *) PROG_START
;
89 if (im
[0] == 0x1f && im
[1] == 0x8b) {
90 void *cp
= (void *) RAM_FREE
;
91 avail_ram
= (void *) (RAM_FREE
+ ((len
+ 7) & -8));
93 printf("gunzipping... ");
94 gunzip(dst
, 0x400000, cp
, &len
);
98 memmove(dst
, im
, len
);
101 flush_cache(dst
, len
);
103 sa
= (unsigned long)dst
;
104 printf("start address = 0x%x\n", sa
);
109 (*(void (*)())sa
)(a1
, a2
, prom
);
111 printf("returned?\n");
116 void *zalloc(void *x
, unsigned items
, unsigned size
)
121 size
= (size
+ 7) & -8;
123 if (avail_ram
> end_avail
) {
124 printf("oops... out of memory\n");
130 void zfree(void *x
, void *addr
, unsigned nb
)
135 #define EXTRA_FIELD 4
138 #define RESERVED 0xe0
142 void gunzip(void *dst
, int dstlen
, unsigned char *src
, int *lenp
)
150 if (src
[2] != DEFLATED
|| (flags
& RESERVED
) != 0) {
151 printf("bad gzipped data\n");
154 if ((flags
& EXTRA_FIELD
) != 0)
155 i
= 12 + src
[10] + (src
[11] << 8);
156 if ((flags
& ORIG_NAME
) != 0)
157 while (src
[i
++] != 0)
159 if ((flags
& COMMENT
) != 0)
160 while (src
[i
++] != 0)
162 if ((flags
& HEAD_CRC
) != 0)
165 printf("gunzip: ran out of data in header\n");
171 r
= inflateInit2(&s
, -MAX_WBITS
);
173 printf("inflateInit2 returned %d\n", r
);
177 s
.avail_in
= *lenp
- i
;
179 s
.avail_out
= dstlen
;
180 printf("doing inflate\n");
181 r
= inflate(&s
, Z_FINISH
);
182 printf("done inflate\n");
183 if (r
!= Z_OK
&& r
!= Z_STREAM_END
) {
184 printf("inflate returned %d\n", r
);
187 *lenp
= s
.next_out
- (unsigned char *) dst
;
188 printf("doing end\n");