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 */
19 extern int strcmp(const char *s1
, const char *s2
);
20 extern char *avail_ram
, *avail_high
;
21 extern char *end_avail
;
23 unsigned int heap_use
, heap_max
;
27 struct memchunk
*next
;
30 static struct memchunk
*freechunks
;
32 static void *zalloc(unsigned size
)
35 struct memchunk
**mpp
, *mp
;
37 size
= (size
+ 7) & -8;
39 if (heap_use
> heap_max
)
41 for (mpp
= &freechunks
; (mp
= *mpp
) != 0; mpp
= &mp
->next
) {
42 if (mp
->size
== size
) {
49 if (avail_ram
> avail_high
)
50 avail_high
= avail_ram
;
51 if (avail_ram
> end_avail
) {
52 printf("oops... out of memory\n\r");
64 void gunzip(void *dst
, int dstlen
, unsigned char *src
, int *lenp
)
72 if (src
[2] != Z_DEFLATED
|| (flags
& RESERVED
) != 0) {
73 printf("bad gzipped data\n\r");
76 if ((flags
& EXTRA_FIELD
) != 0)
77 i
= 12 + src
[10] + (src
[11] << 8);
78 if ((flags
& ORIG_NAME
) != 0)
81 if ((flags
& COMMENT
) != 0)
84 if ((flags
& HEAD_CRC
) != 0)
87 printf("gunzip: ran out of data in header\n\r");
91 /* Initialize ourself. */
92 s
.workspace
= zalloc(zlib_inflate_workspacesize());
93 r
= zlib_inflateInit2(&s
, -MAX_WBITS
);
95 printf("zlib_inflateInit2 returned %d\n\r", r
);
99 s
.avail_in
= *lenp
- i
;
101 s
.avail_out
= dstlen
;
102 r
= zlib_inflate(&s
, Z_FINISH
);
103 if (r
!= Z_OK
&& r
!= Z_STREAM_END
) {
104 printf("inflate returned %d msg: %s\n\r", r
, s
.msg
);
107 *lenp
= s
.next_out
- (unsigned char *) dst
;
111 /* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
112 * a machine type for BI_MACHTYPE, and the location where the end of the
113 * bootloader is (PROG_START + PROG_SIZE)
115 void make_bi_recs(unsigned long addr
, char *name
, unsigned int mach
,
116 unsigned long progend
)
118 struct bi_record
*rec
;
121 /* leave a 1MB gap then align to the next 1MB boundary */
122 addr
= _ALIGN(addr
+ (1<<20) - 1, (1<<20));
123 /* oldworld machine seem very unhappy about this. -- Tom */
125 claim(addr
, 0x1000, 0);
127 rec
= (struct bi_record
*)addr
;
129 rec
->size
= sizeof(struct bi_record
);
130 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
132 rec
->tag
= BI_BOOTLOADER_ID
;
133 sprintf( (char *)rec
->data
, name
);
134 rec
->size
= sizeof(struct bi_record
) + strlen(name
) + 1;
135 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
137 rec
->tag
= BI_MACHTYPE
;
140 rec
->size
= sizeof(struct bi_record
) + 2 * sizeof(unsigned long);
141 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);
144 rec
->size
= sizeof(struct bi_record
);
145 rec
= (struct bi_record
*)((unsigned long)rec
+ rec
->size
);