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.
12 #include <linux/string.h>
13 #include <linux/zlib.h>
14 #include <asm/bootinfo.h>
17 /* Information from the linker */
18 extern char __sysmap_begin
, __sysmap_end
;
20 extern int strcmp(const char *s1
, const char *s2
);
21 extern char *avail_ram
, *avail_high
;
22 extern char *end_avail
;
24 unsigned int heap_use
, heap_max
;
28 struct memchunk
*next
;
31 static struct memchunk
*freechunks
;
33 static void *zalloc(unsigned size
)
36 struct memchunk
**mpp
, *mp
;
38 size
= (size
+ 7) & -8;
40 if (heap_use
> heap_max
)
42 for (mpp
= &freechunks
; (mp
= *mpp
) != 0; mpp
= &mp
->next
) {
43 if (mp
->size
== size
) {
50 if (avail_ram
> avail_high
)
51 avail_high
= avail_ram
;
52 if (avail_ram
> end_avail
) {
53 printf("oops... out of memory\n\r");
65 void gunzip(void *dst
, int dstlen
, unsigned char *src
, int *lenp
)
73 if (src
[2] != Z_DEFLATED
|| (flags
& RESERVED
) != 0) {
74 printf("bad gzipped data\n\r");
77 if ((flags
& EXTRA_FIELD
) != 0)
78 i
= 12 + src
[10] + (src
[11] << 8);
79 if ((flags
& ORIG_NAME
) != 0)
82 if ((flags
& COMMENT
) != 0)
85 if ((flags
& HEAD_CRC
) != 0)
88 printf("gunzip: ran out of data in header\n\r");
92 /* Initialize ourself. */
93 s
.workspace
= zalloc(zlib_inflate_workspacesize());
94 r
= zlib_inflateInit2(&s
, -MAX_WBITS
);
96 printf("zlib_inflateInit2 returned %d\n\r", r
);
100 s
.avail_in
= *lenp
- i
;
102 s
.avail_out
= dstlen
;
103 r
= zlib_inflate(&s
, Z_FINISH
);
104 if (r
!= Z_OK
&& r
!= Z_STREAM_END
) {
105 printf("inflate returned %d msg: %s\n\r", r
, s
.msg
);
108 *lenp
= s
.next_out
- (unsigned char *) dst
;
112 /* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
113 * a machine type for BI_MACHTYPE, and the location where the end of the
114 * bootloader is (PROG_START + PROG_SIZE)
116 void make_bi_recs(unsigned long addr
, char *name
, unsigned int mach
,
117 unsigned long progend
)
119 unsigned long sysmap_size
;
120 struct bi_record
*rec
;
122 /* Figure out the size of a possible System.map we're going to
125 sysmap_size
= (unsigned long)(&__sysmap_end
) -
126 (unsigned long)(&__sysmap_begin
);
128 /* leave a 1MB gap then align to the next 1MB boundary */
129 addr
= _ALIGN(addr
+ (1<<20) - 1, (1<<20));
130 /* oldworld machine seem very unhappy about this. -- Tom */
132 claim(addr
, 0x1000, 0);
134 rec
= (struct bi_record
*)addr
;
136 rec
->size
= sizeof(struct bi_record
);
137 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
139 rec
->tag
= BI_BOOTLOADER_ID
;
140 sprintf( (char *)rec
->data
, name
);
141 rec
->size
= sizeof(struct bi_record
) + strlen(name
) + 1;
142 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
144 rec
->tag
= BI_MACHTYPE
;
147 rec
->size
= sizeof(struct bi_record
) + 2 * sizeof(unsigned long);
148 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
151 rec
->tag
= BI_SYSMAP
;
152 rec
->data
[0] = (unsigned long)(&__sysmap_begin
);
153 rec
->data
[1] = sysmap_size
;
154 rec
->size
= sizeof(struct bi_record
) + 2 *
155 sizeof(unsigned long);
156 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
160 rec
->size
= sizeof(struct bi_record
);
161 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);