2 * 842 Software Decompression
4 * Copyright (C) 2015 Dan Streetman, IBM Corp
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * See 842.h for details of the 842 compressed format.
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 #define MODULE_NAME "842_decompress"
23 #include "842_debugfs.h"
25 /* rolling fifo sizes */
26 #define I2_FIFO_SIZE (2 * (1 << I2_BITS))
27 #define I4_FIFO_SIZE (4 * (1 << I4_BITS))
28 #define I8_FIFO_SIZE (8 * (1 << I8_BITS))
30 static u8 decomp_ops
[OPS_MAX
][4] = {
68 #define beN_to_cpu(d, s) \
69 ((s) == 2 ? be16_to_cpu(get_unaligned((__be16 *)d)) : \
70 (s) == 4 ? be32_to_cpu(get_unaligned((__be32 *)d)) : \
71 (s) == 8 ? be64_to_cpu(get_unaligned((__be64 *)d)) : \
74 static int next_bits(struct sw842_param
*p
, u64
*d
, u8 n
);
76 static int __split_next_bits(struct sw842_param
*p
, u64
*d
, u8 n
, u8 s
)
82 pr_debug("split_next_bits invalid n %u s %u\n", n
, s
);
86 ret
= next_bits(p
, &tmp
, n
- s
);
89 ret
= next_bits(p
, d
, s
);
96 static int next_bits(struct sw842_param
*p
, u64
*d
, u8 n
)
98 u8
*in
= p
->in
, b
= p
->bit
, bits
= b
+ n
;
101 pr_debug("next_bits invalid n %u\n", n
);
105 /* split this up if reading > 8 bytes, or if we're at the end of
106 * the input buffer and would read past the end
109 return __split_next_bits(p
, d
, n
, 32);
110 else if (p
->ilen
< 8 && bits
> 32 && bits
<= 56)
111 return __split_next_bits(p
, d
, n
, 16);
112 else if (p
->ilen
< 4 && bits
> 16 && bits
<= 24)
113 return __split_next_bits(p
, d
, n
, 8);
115 if (DIV_ROUND_UP(bits
, 8) > p
->ilen
)
119 *d
= *in
>> (8 - bits
);
121 *d
= be16_to_cpu(get_unaligned((__be16
*)in
)) >> (16 - bits
);
123 *d
= be32_to_cpu(get_unaligned((__be32
*)in
)) >> (32 - bits
);
125 *d
= be64_to_cpu(get_unaligned((__be64
*)in
)) >> (64 - bits
);
127 *d
&= GENMASK_ULL(n
- 1, 0);
133 p
->ilen
-= p
->bit
/ 8;
140 static int do_data(struct sw842_param
*p
, u8 n
)
148 ret
= next_bits(p
, &v
, n
* 8);
154 put_unaligned(cpu_to_be16((u16
)v
), (__be16
*)p
->out
);
157 put_unaligned(cpu_to_be32((u32
)v
), (__be32
*)p
->out
);
160 put_unaligned(cpu_to_be64((u64
)v
), (__be64
*)p
->out
);
172 static int __do_index(struct sw842_param
*p
, u8 size
, u8 bits
, u64 fsize
)
174 u64 index
, offset
, total
= round_down(p
->out
- p
->ostart
, 8);
177 ret
= next_bits(p
, &index
, bits
);
181 offset
= index
* size
;
183 /* a ring buffer of fsize is used; correct the offset */
185 /* this is where the current fifo is */
186 u64 section
= round_down(total
, fsize
);
187 /* the current pos in the fifo */
188 u64 pos
= total
- section
;
190 /* if the offset is past/at the pos, we need to
191 * go back to the last fifo section
199 if (offset
+ size
> total
) {
200 pr_debug("index%x %lx points past end %lx\n", size
,
201 (unsigned long)offset
, (unsigned long)total
);
205 if (size
!= 2 && size
!= 4 && size
!= 8)
206 WARN(1, "__do_index invalid size %x\n", size
);
208 pr_debug("index%x to %lx off %lx adjoff %lx tot %lx data %lx\n",
209 size
, (unsigned long)index
,
210 (unsigned long)(index
* size
), (unsigned long)offset
,
211 (unsigned long)total
,
212 (unsigned long)beN_to_cpu(&p
->ostart
[offset
], size
));
214 memcpy(p
->out
, &p
->ostart
[offset
], size
);
221 static int do_index(struct sw842_param
*p
, u8 n
)
225 return __do_index(p
, 2, I2_BITS
, I2_FIFO_SIZE
);
227 return __do_index(p
, 4, I4_BITS
, I4_FIFO_SIZE
);
229 return __do_index(p
, 8, I8_BITS
, I8_FIFO_SIZE
);
235 static int do_op(struct sw842_param
*p
, u8 o
)
242 for (i
= 0; i
< 4; i
++) {
243 u8 op
= decomp_ops
[o
][i
];
245 pr_debug("op is %x\n", op
);
247 switch (op
& OP_ACTION
) {
249 ret
= do_data(p
, op
& OP_AMOUNT
);
251 case OP_ACTION_INDEX
:
252 ret
= do_index(p
, op
& OP_AMOUNT
);
257 pr_err("Internal error, invalid op %x\n", op
);
265 if (sw842_template_counts
)
266 atomic_inc(&template_count
[o
]);
274 * Decompress the 842-compressed buffer of length @ilen at @in
275 * to the output buffer @out, using no more than @olen bytes.
277 * The compressed buffer must be only a single 842-compressed buffer,
278 * with the standard format described in the comments in 842.h
279 * Processing will stop when the 842 "END" template is detected,
280 * not the end of the buffer.
282 * Returns: 0 on success, error on failure. The @olen parameter
283 * will contain the number of output bytes written on success, or
286 int sw842_decompress(const u8
*in
, unsigned int ilen
,
287 u8
*out
, unsigned int *olen
)
289 struct sw842_param p
;
291 u64 op
, rep
, tmp
, bytes
, total
;
306 ret
= next_bits(&p
, &op
, OP_BITS
);
310 pr_debug("template is %lx\n", (unsigned long)op
);
314 ret
= next_bits(&p
, &rep
, REPEAT_BITS
);
318 if (p
.out
== out
) /* no previous bytes */
324 if (rep
* 8 > p
.olen
)
328 memcpy(p
.out
, p
.out
- 8, 8);
333 if (sw842_template_counts
)
334 atomic_inc(&template_repeat_count
);
345 if (sw842_template_counts
)
346 atomic_inc(&template_zeros_count
);
350 ret
= next_bits(&p
, &bytes
, SHORT_DATA_BITS
);
354 if (!bytes
|| bytes
> SHORT_DATA_BITS_MAX
)
357 while (bytes
-- > 0) {
358 ret
= next_bits(&p
, &tmp
, 8);
366 if (sw842_template_counts
)
367 atomic_inc(&template_short_data_count
);
371 if (sw842_template_counts
)
372 atomic_inc(&template_end_count
);
375 default: /* use template */
381 } while (op
!= OP_END
);
384 * crc(0:31) is saved in compressed data starting with the
385 * next bit after End of stream template.
387 ret
= next_bits(&p
, &crc
, CRC_BITS
);
392 * Validate CRC saved in compressed data.
394 if (crc
!= (u64
)crc32_be(0, out
, total
- p
.olen
)) {
395 pr_debug("CRC mismatch for decompression\n");
399 if (unlikely((total
- p
.olen
) > UINT_MAX
))
402 *olen
= total
- p
.olen
;
406 EXPORT_SYMBOL_GPL(sw842_decompress
);
408 static int __init
sw842_init(void)
410 if (sw842_template_counts
)
411 sw842_debugfs_create();
415 module_init(sw842_init
);
417 static void __exit
sw842_exit(void)
419 if (sw842_template_counts
)
420 sw842_debugfs_remove();
422 module_exit(sw842_exit
);
424 MODULE_LICENSE("GPL");
425 MODULE_DESCRIPTION("Software 842 Decompressor");
426 MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");