Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Wrapper around the kernel's pre-boot decompression library.
  4 *
  5 * Copyright (C) IBM Corporation 2016.
 
 
 
 
 
  6 */
  7
  8#include "elf.h"
  9#include "page.h"
 10#include "string.h"
 11#include "stdio.h"
 12#include "ops.h"
 13#include "reg.h"
 14#include "types.h"
 15
 16/*
 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
 19 * includes work.
 20 */
 21
 22#define STATIC static
 23#define INIT
 
 24
 25/*
 26 * The build process will copy the required zlib source files and headers
 27 * out of lib/ and "fix" the includes so they do not pull in other kernel
 28 * headers.
 29 */
 30
 31#ifdef CONFIG_KERNEL_GZIP
 32#	include "decompress_inflate.c"
 33#endif
 34
 35#ifdef CONFIG_KERNEL_XZ
 36#	include "xz_config.h"
 37#	include "../../../lib/decompress_unxz.c"
 38#endif
 39
 40/* globals for tracking the state of the decompression */
 41static unsigned long decompressed_bytes;
 42static unsigned long limit;
 43static unsigned long skip;
 44static char *output_buffer;
 45
 46/*
 47 * flush() is called by __decompress() when the decompressor's scratch buffer is
 48 * full.
 49 */
 50static long flush(void *v, unsigned long buffer_size)
 51{
 52	unsigned long end = decompressed_bytes + buffer_size;
 53	unsigned long size = buffer_size;
 54	unsigned long offset = 0;
 55	char *in = v;
 56	char *out;
 57
 58	/*
 59	 * if we hit our decompression limit, we need to fake an error to abort
 60	 * the in-progress decompression.
 61	 */
 62	if (decompressed_bytes >= limit)
 63		return -1;
 64
 65	/* skip this entire block */
 66	if (end <= skip) {
 67		decompressed_bytes += buffer_size;
 68		return buffer_size;
 69	}
 70
 71	/* skip some data at the start, but keep the rest of the block */
 72	if (decompressed_bytes < skip && end > skip) {
 73		offset = skip - decompressed_bytes;
 74
 75		in += offset;
 76		size -= offset;
 77		decompressed_bytes += offset;
 78	}
 79
 80	out = &output_buffer[decompressed_bytes - skip];
 81	size = min(decompressed_bytes + size, limit) - decompressed_bytes;
 82
 83	memcpy(out, in, size);
 84	decompressed_bytes += size;
 85
 86	return buffer_size;
 87}
 88
 89static void print_err(char *s)
 90{
 91	/* suppress the "error" when we terminate the decompressor */
 92	if (decompressed_bytes >= limit)
 93		return;
 94
 95	printf("Decompression error: '%s'\n\r", s);
 96}
 97
 98/**
 99 * partial_decompress - decompresses part or all of a compressed buffer
100 * @inbuf:       input buffer
101 * @input_size:  length of the input buffer
102 * @outbuf:      output buffer
103 * @output_size: length of the output buffer
104 * @skip         number of output bytes to ignore
105 *
106 * This function takes compressed data from inbuf, decompresses and write it to
107 * outbuf. Once output_size bytes are written to the output buffer, or the
108 * stream is exhausted the function will return the number of bytes that were
109 * decompressed. Otherwise it will return whatever error code the decompressor
110 * reported (NB: This is specific to each decompressor type).
111 *
112 * The skip functionality is mainly there so the program and discover
113 * the size of the compressed image so that it can ask firmware (if present)
114 * for an appropriately sized buffer.
115 */
116long partial_decompress(void *inbuf, unsigned long input_size,
117	void *outbuf, unsigned long output_size, unsigned long _skip)
118{
119	int ret;
120
121	/*
122	 * The skipped bytes needs to be included in the size of data we want
123	 * to decompress.
124	 */
125	output_size += _skip;
126
127	decompressed_bytes = 0;
128	output_buffer = outbuf;
129	limit = output_size;
130	skip = _skip;
131
132	ret = __decompress(inbuf, input_size, NULL, flush, outbuf,
133		output_size, NULL, print_err);
134
135	/*
136	 * If decompression was aborted due to an actual error rather than
137	 * a fake error that we used to abort, then we should report it.
138	 */
139	if (decompressed_bytes < limit)
140		return ret;
141
142	return decompressed_bytes - skip;
143}
v4.10.11
 
  1/*
  2 * Wrapper around the kernel's pre-boot decompression library.
  3 *
  4 * Copyright (C) IBM Corporation 2016.
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public License
  8 * as published by the Free Software Foundation; either version
  9 * 2 of the License, or (at your option) any later version.
 10 */
 11
 12#include "elf.h"
 13#include "page.h"
 14#include "string.h"
 15#include "stdio.h"
 16#include "ops.h"
 17#include "reg.h"
 18#include "types.h"
 19
 20/*
 21 * The decompressor_*.c files play #ifdef games so they can be used in both
 22 * pre-boot and regular kernel code. We need these definitions to make the
 23 * includes work.
 24 */
 25
 26#define STATIC static
 27#define INIT
 28#define __always_inline inline
 29
 30/*
 31 * The build process will copy the required zlib source files and headers
 32 * out of lib/ and "fix" the includes so they do not pull in other kernel
 33 * headers.
 34 */
 35
 36#ifdef CONFIG_KERNEL_GZIP
 37#	include "decompress_inflate.c"
 38#endif
 39
 40#ifdef CONFIG_KERNEL_XZ
 41#	include "xz_config.h"
 42#	include "../../../lib/decompress_unxz.c"
 43#endif
 44
 45/* globals for tracking the state of the decompression */
 46static unsigned long decompressed_bytes;
 47static unsigned long limit;
 48static unsigned long skip;
 49static char *output_buffer;
 50
 51/*
 52 * flush() is called by __decompress() when the decompressor's scratch buffer is
 53 * full.
 54 */
 55static long flush(void *v, unsigned long buffer_size)
 56{
 57	unsigned long end = decompressed_bytes + buffer_size;
 58	unsigned long size = buffer_size;
 59	unsigned long offset = 0;
 60	char *in = v;
 61	char *out;
 62
 63	/*
 64	 * if we hit our decompression limit, we need to fake an error to abort
 65	 * the in-progress decompression.
 66	 */
 67	if (decompressed_bytes >= limit)
 68		return -1;
 69
 70	/* skip this entire block */
 71	if (end <= skip) {
 72		decompressed_bytes += buffer_size;
 73		return buffer_size;
 74	}
 75
 76	/* skip some data at the start, but keep the rest of the block */
 77	if (decompressed_bytes < skip && end > skip) {
 78		offset = skip - decompressed_bytes;
 79
 80		in += offset;
 81		size -= offset;
 82		decompressed_bytes += offset;
 83	}
 84
 85	out = &output_buffer[decompressed_bytes - skip];
 86	size = min(decompressed_bytes + size, limit) - decompressed_bytes;
 87
 88	memcpy(out, in, size);
 89	decompressed_bytes += size;
 90
 91	return buffer_size;
 92}
 93
 94static void print_err(char *s)
 95{
 96	/* suppress the "error" when we terminate the decompressor */
 97	if (decompressed_bytes >= limit)
 98		return;
 99
100	printf("Decompression error: '%s'\n\r", s);
101}
102
103/**
104 * partial_decompress - decompresses part or all of a compressed buffer
105 * @inbuf:       input buffer
106 * @input_size:  length of the input buffer
107 * @outbuf:      input buffer
108 * @output_size: length of the input buffer
109 * @skip         number of output bytes to ignore
110 *
111 * This function takes compressed data from inbuf, decompresses and write it to
112 * outbuf. Once output_size bytes are written to the output buffer, or the
113 * stream is exhausted the function will return the number of bytes that were
114 * decompressed. Otherwise it will return whatever error code the decompressor
115 * reported (NB: This is specific to each decompressor type).
116 *
117 * The skip functionality is mainly there so the program and discover
118 * the size of the compressed image so that it can ask firmware (if present)
119 * for an appropriately sized buffer.
120 */
121long partial_decompress(void *inbuf, unsigned long input_size,
122	void *outbuf, unsigned long output_size, unsigned long _skip)
123{
124	int ret;
125
126	/*
127	 * The skipped bytes needs to be included in the size of data we want
128	 * to decompress.
129	 */
130	output_size += _skip;
131
132	decompressed_bytes = 0;
133	output_buffer = outbuf;
134	limit = output_size;
135	skip = _skip;
136
137	ret = __decompress(inbuf, input_size, NULL, flush, outbuf,
138		output_size, NULL, print_err);
139
140	/*
141	 * If decompression was aborted due to an actual error rather than
142	 * a fake error that we used to abort, then we should report it.
143	 */
144	if (decompressed_bytes < limit)
145		return ret;
146
147	return decompressed_bytes - skip;
148}