diff options
Diffstat (limited to 'arch/xtensa/boot/lib/zmem.c')
-rw-r--r-- | arch/xtensa/boot/lib/zmem.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c new file mode 100644 index 000000000000..d9862aa8ca25 --- /dev/null +++ b/arch/xtensa/boot/lib/zmem.c | |||
@@ -0,0 +1,79 @@ | |||
1 | #include <linux/zlib.h> | ||
2 | |||
3 | /* bits taken from ppc */ | ||
4 | |||
5 | extern void *avail_ram, *end_avail; | ||
6 | |||
7 | void exit (void) | ||
8 | { | ||
9 | for (;;); | ||
10 | } | ||
11 | |||
12 | void *zalloc(unsigned size) | ||
13 | { | ||
14 | void *p = avail_ram; | ||
15 | |||
16 | size = (size + 7) & -8; | ||
17 | avail_ram += size; | ||
18 | if (avail_ram > end_avail) { | ||
19 | //puts("oops... out of memory\n"); | ||
20 | //pause(); | ||
21 | exit (); | ||
22 | } | ||
23 | return p; | ||
24 | } | ||
25 | |||
26 | #define HEAD_CRC 2 | ||
27 | #define EXTRA_FIELD 4 | ||
28 | #define ORIG_NAME 8 | ||
29 | #define COMMENT 0x10 | ||
30 | #define RESERVED 0xe0 | ||
31 | |||
32 | #define DEFLATED 8 | ||
33 | |||
34 | void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) | ||
35 | { | ||
36 | z_stream s; | ||
37 | int r, i, flags; | ||
38 | |||
39 | /* skip header */ | ||
40 | i = 10; | ||
41 | flags = src[3]; | ||
42 | if (src[2] != DEFLATED || (flags & RESERVED) != 0) { | ||
43 | //puts("bad gzipped data\n"); | ||
44 | exit(); | ||
45 | } | ||
46 | if ((flags & EXTRA_FIELD) != 0) | ||
47 | i = 12 + src[10] + (src[11] << 8); | ||
48 | if ((flags & ORIG_NAME) != 0) | ||
49 | while (src[i++] != 0) | ||
50 | ; | ||
51 | if ((flags & COMMENT) != 0) | ||
52 | while (src[i++] != 0) | ||
53 | ; | ||
54 | if ((flags & HEAD_CRC) != 0) | ||
55 | i += 2; | ||
56 | if (i >= *lenp) { | ||
57 | //puts("gunzip: ran out of data in header\n"); | ||
58 | exit(); | ||
59 | } | ||
60 | |||
61 | s.workspace = zalloc(zlib_inflate_workspacesize()); | ||
62 | r = zlib_inflateInit2(&s, -MAX_WBITS); | ||
63 | if (r != Z_OK) { | ||
64 | //puts("inflateInit2 returned "); puthex(r); puts("\n"); | ||
65 | exit(); | ||
66 | } | ||
67 | s.next_in = src + i; | ||
68 | s.avail_in = *lenp - i; | ||
69 | s.next_out = dst; | ||
70 | s.avail_out = dstlen; | ||
71 | r = zlib_inflate(&s, Z_FINISH); | ||
72 | if (r != Z_OK && r != Z_STREAM_END) { | ||
73 | //puts("inflate returned "); puthex(r); puts("\n"); | ||
74 | exit(); | ||
75 | } | ||
76 | *lenp = s.next_out - (unsigned char *) dst; | ||
77 | zlib_inflateEnd(&s); | ||
78 | } | ||
79 | |||