1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Wrapper around the kernel's pre-boot decompression library.
5 * Copyright (C) IBM Corporation 2016.
17 * The decompressor_*.c files play #ifdef games so they can be used in both
18 * pre-boot and regular kernel code. We need these definitions to make the
24 #define __always_inline inline
27 * The build process will copy the required zlib source files and headers
28 * out of lib/ and "fix" the includes so they do not pull in other kernel
32 #ifdef CONFIG_KERNEL_GZIP
33 # include "decompress_inflate.c"
36 #ifdef CONFIG_KERNEL_XZ
37 # include "xz_config.h"
38 # include "../../../lib/decompress_unxz.c"
41 /* globals for tracking the state of the decompression */
42 static unsigned long decompressed_bytes
;
43 static unsigned long limit
;
44 static unsigned long skip
;
45 static char *output_buffer
;
48 * flush() is called by __decompress() when the decompressor's scratch buffer is
51 static long flush(void *v
, unsigned long buffer_size
)
53 unsigned long end
= decompressed_bytes
+ buffer_size
;
54 unsigned long size
= buffer_size
;
55 unsigned long offset
= 0;
60 * if we hit our decompression limit, we need to fake an error to abort
61 * the in-progress decompression.
63 if (decompressed_bytes
>= limit
)
66 /* skip this entire block */
68 decompressed_bytes
+= buffer_size
;
72 /* skip some data at the start, but keep the rest of the block */
73 if (decompressed_bytes
< skip
&& end
> skip
) {
74 offset
= skip
- decompressed_bytes
;
78 decompressed_bytes
+= offset
;
81 out
= &output_buffer
[decompressed_bytes
- skip
];
82 size
= min(decompressed_bytes
+ size
, limit
) - decompressed_bytes
;
84 memcpy(out
, in
, size
);
85 decompressed_bytes
+= size
;
90 static void print_err(char *s
)
92 /* suppress the "error" when we terminate the decompressor */
93 if (decompressed_bytes
>= limit
)
96 printf("Decompression error: '%s'\n\r", s
);
100 * partial_decompress - decompresses part or all of a compressed buffer
101 * @inbuf: input buffer
102 * @input_size: length of the input buffer
103 * @outbuf: input buffer
104 * @output_size: length of the input buffer
105 * @skip number of output bytes to ignore
107 * This function takes compressed data from inbuf, decompresses and write it to
108 * outbuf. Once output_size bytes are written to the output buffer, or the
109 * stream is exhausted the function will return the number of bytes that were
110 * decompressed. Otherwise it will return whatever error code the decompressor
111 * reported (NB: This is specific to each decompressor type).
113 * The skip functionality is mainly there so the program and discover
114 * the size of the compressed image so that it can ask firmware (if present)
115 * for an appropriately sized buffer.
117 long partial_decompress(void *inbuf
, unsigned long input_size
,
118 void *outbuf
, unsigned long output_size
, unsigned long _skip
)
123 * The skipped bytes needs to be included in the size of data we want
126 output_size
+= _skip
;
128 decompressed_bytes
= 0;
129 output_buffer
= outbuf
;
133 ret
= __decompress(inbuf
, input_size
, NULL
, flush
, outbuf
,
134 output_size
, NULL
, print_err
);
137 * If decompression was aborted due to an actual error rather than
138 * a fake error that we used to abort, then we should report it.
140 if (decompressed_bytes
< limit
)
143 return decompressed_bytes
- skip
;