1 #include <xen/errno.h>
2 #include <xen/init.h>
3 #include <xen/lib.h>
4 #include <xen/mm.h>
5
6 #define HEAPORDER 3
7
8 static unsigned char *__initdata window;
9 #define memptr long
10 static memptr __initdata free_mem_ptr;
11 static memptr __initdata free_mem_end_ptr;
12
13 #define WSIZE 0x80000000
14
15 static unsigned char *__initdata inbuf;
16 static unsigned __initdata insize;
17
18 /* Index of next byte to be processed in inbuf: */
19 static unsigned __initdata inptr;
20
21 /* Bytes in output buffer: */
22 static unsigned __initdata outcnt;
23
24 #define OF(args) args
25 #define STATIC static
26
27 #define memzero(s, n) memset((s), 0, (n))
28
29 typedef unsigned char uch;
30 typedef unsigned short ush;
31 typedef unsigned long ulg;
32
33 #define INIT __init
34 #define INITDATA __initdata
35
36 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
37
38 /* Diagnostic functions */
39 #ifdef DEBUG
40 # define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0)
41 # define Trace(x) do { fprintf x; } while (0)
42 # define Tracev(x) do { if (verbose) fprintf x ; } while (0)
43 # define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0)
44 # define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0)
45 # define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0)
46 #else
47 # define Assert(cond, msg)
48 # define Trace(x)
49 # define Tracev(x)
50 # define Tracevv(x)
51 # define Tracec(c, x)
52 # define Tracecv(c, x)
53 #endif
54
55 static long __initdata bytes_out;
56 static void flush_window(void);
57
error(char * x)58 static __init void error(char *x)
59 {
60 panic("%s", x);
61 }
62
fill_inbuf(void)63 static __init int fill_inbuf(void)
64 {
65 error("ran out of input data");
66 return 0;
67 }
68
69
70 #include "inflate.c"
71
flush_window(void)72 static __init void flush_window(void)
73 {
74 /*
75 * The window is equal to the output buffer therefore only need to
76 * compute the crc.
77 */
78 unsigned long c = crc;
79 unsigned n;
80 unsigned char *in, ch;
81
82 in = window;
83 for ( n = 0; n < outcnt; n++ )
84 {
85 ch = *in++;
86 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
87 }
88 crc = c;
89
90 bytes_out += (unsigned long)outcnt;
91 outcnt = 0;
92 }
93
gzip_check(char * image,unsigned long image_len)94 __init int gzip_check(char *image, unsigned long image_len)
95 {
96 unsigned char magic0, magic1;
97
98 if ( image_len < 2 )
99 return 0;
100
101 magic0 = (unsigned char)image[0];
102 magic1 = (unsigned char)image[1];
103
104 return (magic0 == 0x1f) && ((magic1 == 0x8b) || (magic1 == 0x9e));
105 }
106
perform_gunzip(char * output,char * image,unsigned long image_len)107 __init int perform_gunzip(char *output, char *image, unsigned long image_len)
108 {
109 int rc;
110
111 if ( !gzip_check(image, image_len) )
112 return 1;
113
114 window = (unsigned char *)output;
115
116 free_mem_ptr = (unsigned long)alloc_xenheap_pages(HEAPORDER, 0);
117 free_mem_end_ptr = free_mem_ptr + (PAGE_SIZE << HEAPORDER);
118
119 inbuf = (unsigned char *)image;
120 insize = image_len;
121 inptr = 0;
122
123 makecrc();
124
125 if ( gunzip() < 0 )
126 {
127 rc = -EINVAL;
128 }
129 else
130 {
131 rc = 0;
132 }
133
134 free_xenheap_pages((void *)free_mem_ptr, HEAPORDER);
135
136 return rc;
137 }
138