2019-05-30 06:57:50 +07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
lib: add shared BCH ECC library
This is a new software BCH encoding/decoding library, similar to the shared
Reed-Solomon library.
Binary BCH (Bose-Chaudhuri-Hocquenghem) codes are widely used to correct
errors in NAND flash devices requiring more than 1-bit ecc correction; they
are generally better suited for NAND flash than RS codes because NAND bit
errors do not occur in bursts. Latest SLC NAND devices typically require at
least 4-bit ecc protection per 512 bytes block.
This library provides software encoding/decoding, but may also be used with
ASIC/SoC hardware BCH engines to perform error correction. It is being
currently used for this purpose on an OMAP3630 board (4bit/8bit HW BCH). It
has also been used to decode raw dumps of NAND devices with on-die BCH ecc
engines (e.g. Micron 4bit ecc SLC devices).
Latest NAND devices (including SLC) can exhibit high error rates (typically
a dozen or more bitflips per hour during stress tests); in order to
minimize the performance impact of error correction, this library
implements recently developed algorithms for fast polynomial root finding
(see bch.c header for details) instead of the traditional exhaustive Chien
root search; a few performance figures are provided below:
Platform: arm926ejs @ 468 MHz, 32 KiB icache, 16 KiB dcache
BCH ecc : 4-bit per 512 bytes
Encoding average throughput: 250 Mbits/s
Error correction time (compared with Chien search):
average worst average (Chien) worst (Chien)
----------------------------------------------------------
1 bit 8.5 µs 11 µs 200 µs 383 µs
2 bit 9.7 µs 12.5 µs 477 µs 728 µs
3 bit 18.1 µs 20.6 µs 758 µs 1010 µs
4 bit 19.5 µs 23 µs 1028 µs 1280 µs
In the above figures, "worst" is meant in terms of error pattern, not in
terms of cache miss / page faults effects (not taken into account here).
The library has been extensively tested on the following platforms: x86,
x86_64, arm926ejs, omap3630, qemu-ppc64, qemu-mips.
Signed-off-by: Ivan Djelic <ivan.djelic@parrot.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2011-03-11 17:05:32 +07:00
|
|
|
/*
|
|
|
|
* Generic binary BCH encoding/decoding library
|
|
|
|
*
|
|
|
|
* Copyright © 2011 Parrot S.A.
|
|
|
|
*
|
|
|
|
* Author: Ivan Djelic <ivan.djelic@parrot.com>
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
*
|
|
|
|
* This library provides runtime configurable encoding/decoding of binary
|
|
|
|
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
|
|
|
|
*/
|
|
|
|
#ifndef _BCH_H
|
|
|
|
#define _BCH_H
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct bch_control - BCH control structure
|
|
|
|
* @m: Galois field order
|
|
|
|
* @n: maximum codeword size in bits (= 2^m-1)
|
|
|
|
* @t: error correction capability in bits
|
|
|
|
* @ecc_bits: ecc exact size in bits, i.e. generator polynomial degree (<=m*t)
|
|
|
|
* @ecc_bytes: ecc max size (m*t bits) in bytes
|
|
|
|
* @a_pow_tab: Galois field GF(2^m) exponentiation lookup table
|
|
|
|
* @a_log_tab: Galois field GF(2^m) log lookup table
|
|
|
|
* @mod8_tab: remainder generator polynomial lookup tables
|
|
|
|
* @ecc_buf: ecc parity words buffer
|
|
|
|
* @ecc_buf2: ecc parity words buffer
|
|
|
|
* @xi_tab: GF(2^m) base for solving degree 2 polynomial roots
|
|
|
|
* @syn: syndrome buffer
|
|
|
|
* @cache: log-based polynomial representation buffer
|
|
|
|
* @elp: error locator polynomial
|
|
|
|
* @poly_2t: temporary polynomials of degree 2t
|
|
|
|
*/
|
|
|
|
struct bch_control {
|
|
|
|
unsigned int m;
|
|
|
|
unsigned int n;
|
|
|
|
unsigned int t;
|
|
|
|
unsigned int ecc_bits;
|
|
|
|
unsigned int ecc_bytes;
|
|
|
|
/* private: */
|
|
|
|
uint16_t *a_pow_tab;
|
|
|
|
uint16_t *a_log_tab;
|
|
|
|
uint32_t *mod8_tab;
|
|
|
|
uint32_t *ecc_buf;
|
|
|
|
uint32_t *ecc_buf2;
|
|
|
|
unsigned int *xi_tab;
|
|
|
|
unsigned int *syn;
|
|
|
|
int *cache;
|
|
|
|
struct gf_poly *elp;
|
|
|
|
struct gf_poly *poly_2t[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bch_control *init_bch(int m, int t, unsigned int prim_poly);
|
|
|
|
|
|
|
|
void free_bch(struct bch_control *bch);
|
|
|
|
|
|
|
|
void encode_bch(struct bch_control *bch, const uint8_t *data,
|
|
|
|
unsigned int len, uint8_t *ecc);
|
|
|
|
|
|
|
|
int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len,
|
|
|
|
const uint8_t *recv_ecc, const uint8_t *calc_ecc,
|
|
|
|
const unsigned int *syn, unsigned int *errloc);
|
|
|
|
|
|
|
|
#endif /* _BCH_H */
|