xref: /linux/lib/842/842.h (revision b24413180f5600bcb3bb70fbed5cf186b60864bd)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
22da572c9SDan Streetman 
32da572c9SDan Streetman #ifndef __842_H__
42da572c9SDan Streetman #define __842_H__
52da572c9SDan Streetman 
62da572c9SDan Streetman /* The 842 compressed format is made up of multiple blocks, each of
72da572c9SDan Streetman  * which have the format:
82da572c9SDan Streetman  *
92da572c9SDan Streetman  * <template>[arg1][arg2][arg3][arg4]
102da572c9SDan Streetman  *
112da572c9SDan Streetman  * where there are between 0 and 4 template args, depending on the specific
122da572c9SDan Streetman  * template operation.  For normal operations, each arg is either a specific
132da572c9SDan Streetman  * number of data bytes to add to the output buffer, or an index pointing
142da572c9SDan Streetman  * to a previously-written number of data bytes to copy to the output buffer.
152da572c9SDan Streetman  *
162da572c9SDan Streetman  * The template code is a 5-bit value.  This code indicates what to do with
172da572c9SDan Streetman  * the following data.  Template codes from 0 to 0x19 should use the template
182da572c9SDan Streetman  * table, the static "decomp_ops" table used in decompress.  For each template
192da572c9SDan Streetman  * (table row), there are between 1 and 4 actions; each action corresponds to
202da572c9SDan Streetman  * an arg following the template code bits.  Each action is either a "data"
212da572c9SDan Streetman  * type action, or a "index" type action, and each action results in 2, 4, or 8
222da572c9SDan Streetman  * bytes being written to the output buffer.  Each template (i.e. all actions
232da572c9SDan Streetman  * in the table row) will add up to 8 bytes being written to the output buffer.
242da572c9SDan Streetman  * Any row with less than 4 actions is padded with noop actions, indicated by
252da572c9SDan Streetman  * N0 (for which there is no corresponding arg in the compressed data buffer).
262da572c9SDan Streetman  *
272da572c9SDan Streetman  * "Data" actions, indicated in the table by D2, D4, and D8, mean that the
282da572c9SDan Streetman  * corresponding arg is 2, 4, or 8 bytes, respectively, in the compressed data
292da572c9SDan Streetman  * buffer should be copied directly to the output buffer.
302da572c9SDan Streetman  *
312da572c9SDan Streetman  * "Index" actions, indicated in the table by I2, I4, and I8, mean the
322da572c9SDan Streetman  * corresponding arg is an index parameter that points to, respectively, a 2,
332da572c9SDan Streetman  * 4, or 8 byte value already in the output buffer, that should be copied to
342da572c9SDan Streetman  * the end of the output buffer.  Essentially, the index points to a position
352da572c9SDan Streetman  * in a ring buffer that contains the last N bytes of output buffer data.
362da572c9SDan Streetman  * The number of bits for each index's arg are: 8 bits for I2, 9 bits for I4,
372da572c9SDan Streetman  * and 8 bits for I8.  Since each index points to a 2, 4, or 8 byte section,
382da572c9SDan Streetman  * this means that I2 can reference 512 bytes ((2^8 bits = 256) * 2 bytes), I4
392da572c9SDan Streetman  * can reference 2048 bytes ((2^9 = 512) * 4 bytes), and I8 can reference 2048
402da572c9SDan Streetman  * bytes ((2^8 = 256) * 8 bytes).  Think of it as a kind-of ring buffer for
412da572c9SDan Streetman  * each of I2, I4, and I8 that are updated for each byte written to the output
422da572c9SDan Streetman  * buffer.  In this implementation, the output buffer is directly used for each
432da572c9SDan Streetman  * index; there is no additional memory required.  Note that the index is into
442da572c9SDan Streetman  * a ring buffer, not a sliding window; for example, if there have been 260
452da572c9SDan Streetman  * bytes written to the output buffer, an I2 index of 0 would index to byte 256
462da572c9SDan Streetman  * in the output buffer, while an I2 index of 16 would index to byte 16 in the
472da572c9SDan Streetman  * output buffer.
482da572c9SDan Streetman  *
492da572c9SDan Streetman  * There are also 3 special template codes; 0x1b for "repeat", 0x1c for
502da572c9SDan Streetman  * "zeros", and 0x1e for "end".  The "repeat" operation is followed by a 6 bit
512da572c9SDan Streetman  * arg N indicating how many times to repeat.  The last 8 bytes written to the
522da572c9SDan Streetman  * output buffer are written again to the output buffer, N + 1 times.  The
532da572c9SDan Streetman  * "zeros" operation, which has no arg bits, writes 8 zeros to the output
542da572c9SDan Streetman  * buffer.  The "end" operation, which also has no arg bits, signals the end
552da572c9SDan Streetman  * of the compressed data.  There may be some number of padding (don't care,
562da572c9SDan Streetman  * but usually 0) bits after the "end" operation bits, to fill the buffer
572da572c9SDan Streetman  * length to a specific byte multiple (usually a multiple of 8, 16, or 32
582da572c9SDan Streetman  * bytes).
592da572c9SDan Streetman  *
602da572c9SDan Streetman  * This software implementation also uses one of the undefined template values,
612da572c9SDan Streetman  * 0x1d as a special "short data" template code, to represent less than 8 bytes
622da572c9SDan Streetman  * of uncompressed data.  It is followed by a 3 bit arg N indicating how many
632da572c9SDan Streetman  * data bytes will follow, and then N bytes of data, which should be copied to
642da572c9SDan Streetman  * the output buffer.  This allows the software 842 compressor to accept input
652da572c9SDan Streetman  * buffers that are not an exact multiple of 8 bytes long.  However, those
662da572c9SDan Streetman  * compressed buffers containing this sw-only template will be rejected by
672da572c9SDan Streetman  * the 842 hardware decompressor, and must be decompressed with this software
682da572c9SDan Streetman  * library.  The 842 software compression module includes a parameter to
692da572c9SDan Streetman  * disable using this sw-only "short data" template, and instead simply
702da572c9SDan Streetman  * reject any input buffer that is not a multiple of 8 bytes long.
712da572c9SDan Streetman  *
722da572c9SDan Streetman  * After all actions for each operation code are processed, another template
732da572c9SDan Streetman  * code is in the next 5 bits.  The decompression ends once the "end" template
742da572c9SDan Streetman  * code is detected.
752da572c9SDan Streetman  */
762da572c9SDan Streetman 
772da572c9SDan Streetman #include <linux/module.h>
782da572c9SDan Streetman #include <linux/kernel.h>
792da572c9SDan Streetman #include <linux/bitops.h>
80ea0b3984SHaren Myneni #include <linux/crc32.h>
812da572c9SDan Streetman #include <asm/unaligned.h>
822da572c9SDan Streetman 
832da572c9SDan Streetman #include <linux/sw842.h>
842da572c9SDan Streetman 
852da572c9SDan Streetman /* special templates */
862da572c9SDan Streetman #define OP_REPEAT	(0x1B)
872da572c9SDan Streetman #define OP_ZEROS	(0x1C)
882da572c9SDan Streetman #define OP_END		(0x1E)
892da572c9SDan Streetman 
902da572c9SDan Streetman /* sw only template - this is not in the hw design; it's used only by this
912da572c9SDan Streetman  * software compressor and decompressor, to allow input buffers that aren't
922da572c9SDan Streetman  * a multiple of 8.
932da572c9SDan Streetman  */
942da572c9SDan Streetman #define OP_SHORT_DATA	(0x1D)
952da572c9SDan Streetman 
962da572c9SDan Streetman /* additional bits of each op param */
972da572c9SDan Streetman #define OP_BITS		(5)
982da572c9SDan Streetman #define REPEAT_BITS	(6)
992da572c9SDan Streetman #define SHORT_DATA_BITS	(3)
1002da572c9SDan Streetman #define I2_BITS		(8)
1012da572c9SDan Streetman #define I4_BITS		(9)
1022da572c9SDan Streetman #define I8_BITS		(8)
103ea0b3984SHaren Myneni #define CRC_BITS	(32)
1042da572c9SDan Streetman 
1052da572c9SDan Streetman #define REPEAT_BITS_MAX		(0x3f)
1062da572c9SDan Streetman #define SHORT_DATA_BITS_MAX	(0x7)
1072da572c9SDan Streetman 
1082da572c9SDan Streetman /* Arbitrary values used to indicate action */
1092da572c9SDan Streetman #define OP_ACTION	(0x70)
1102da572c9SDan Streetman #define OP_ACTION_INDEX	(0x10)
1112da572c9SDan Streetman #define OP_ACTION_DATA	(0x20)
1122da572c9SDan Streetman #define OP_ACTION_NOOP	(0x40)
1132da572c9SDan Streetman #define OP_AMOUNT	(0x0f)
1142da572c9SDan Streetman #define OP_AMOUNT_0	(0x00)
1152da572c9SDan Streetman #define OP_AMOUNT_2	(0x02)
1162da572c9SDan Streetman #define OP_AMOUNT_4	(0x04)
1172da572c9SDan Streetman #define OP_AMOUNT_8	(0x08)
1182da572c9SDan Streetman 
1192da572c9SDan Streetman #define D2		(OP_ACTION_DATA  | OP_AMOUNT_2)
1202da572c9SDan Streetman #define D4		(OP_ACTION_DATA  | OP_AMOUNT_4)
1212da572c9SDan Streetman #define D8		(OP_ACTION_DATA  | OP_AMOUNT_8)
1222da572c9SDan Streetman #define I2		(OP_ACTION_INDEX | OP_AMOUNT_2)
1232da572c9SDan Streetman #define I4		(OP_ACTION_INDEX | OP_AMOUNT_4)
1242da572c9SDan Streetman #define I8		(OP_ACTION_INDEX | OP_AMOUNT_8)
1252da572c9SDan Streetman #define N0		(OP_ACTION_NOOP  | OP_AMOUNT_0)
1262da572c9SDan Streetman 
1272da572c9SDan Streetman /* the max of the regular templates - not including the special templates */
1282da572c9SDan Streetman #define OPS_MAX		(0x1a)
1292da572c9SDan Streetman 
1302da572c9SDan Streetman #endif
131