Skip to content

Commit 437aa56

Browse files
idjelicDavid Woodhouse
authored and
David Woodhouse
committed
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 <[email protected]> Signed-off-by: David Woodhouse <[email protected]>
1 parent 2c1c5f1 commit 437aa56

File tree

4 files changed

+1487
-0
lines changed

4 files changed

+1487
-0
lines changed

include/linux/bch.h

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Generic binary BCH encoding/decoding library
3+
*
4+
* This program is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 as published by
6+
* the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT
9+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11+
* more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program; if not, write to the Free Software Foundation, Inc., 51
15+
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16+
*
17+
* Copyright © 2011 Parrot S.A.
18+
*
19+
* Author: Ivan Djelic <[email protected]>
20+
*
21+
* Description:
22+
*
23+
* This library provides runtime configurable encoding/decoding of binary
24+
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
25+
*/
26+
#ifndef _BCH_H
27+
#define _BCH_H
28+
29+
#include <linux/types.h>
30+
31+
/**
32+
* struct bch_control - BCH control structure
33+
* @m: Galois field order
34+
* @n: maximum codeword size in bits (= 2^m-1)
35+
* @t: error correction capability in bits
36+
* @ecc_bits: ecc exact size in bits, i.e. generator polynomial degree (<=m*t)
37+
* @ecc_bytes: ecc max size (m*t bits) in bytes
38+
* @a_pow_tab: Galois field GF(2^m) exponentiation lookup table
39+
* @a_log_tab: Galois field GF(2^m) log lookup table
40+
* @mod8_tab: remainder generator polynomial lookup tables
41+
* @ecc_buf: ecc parity words buffer
42+
* @ecc_buf2: ecc parity words buffer
43+
* @xi_tab: GF(2^m) base for solving degree 2 polynomial roots
44+
* @syn: syndrome buffer
45+
* @cache: log-based polynomial representation buffer
46+
* @elp: error locator polynomial
47+
* @poly_2t: temporary polynomials of degree 2t
48+
*/
49+
struct bch_control {
50+
unsigned int m;
51+
unsigned int n;
52+
unsigned int t;
53+
unsigned int ecc_bits;
54+
unsigned int ecc_bytes;
55+
/* private: */
56+
uint16_t *a_pow_tab;
57+
uint16_t *a_log_tab;
58+
uint32_t *mod8_tab;
59+
uint32_t *ecc_buf;
60+
uint32_t *ecc_buf2;
61+
unsigned int *xi_tab;
62+
unsigned int *syn;
63+
int *cache;
64+
struct gf_poly *elp;
65+
struct gf_poly *poly_2t[4];
66+
};
67+
68+
struct bch_control *init_bch(int m, int t, unsigned int prim_poly);
69+
70+
void free_bch(struct bch_control *bch);
71+
72+
void encode_bch(struct bch_control *bch, const uint8_t *data,
73+
unsigned int len, uint8_t *ecc);
74+
75+
int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len,
76+
const uint8_t *recv_ecc, const uint8_t *calc_ecc,
77+
const unsigned int *syn, unsigned int *errloc);
78+
79+
#endif /* _BCH_H */

lib/Kconfig

+39
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,45 @@ config REED_SOLOMON_ENC16
154154
config REED_SOLOMON_DEC16
155155
boolean
156156

157+
#
158+
# BCH support is selected if needed
159+
#
160+
config BCH
161+
tristate
162+
163+
config BCH_CONST_PARAMS
164+
boolean
165+
help
166+
Drivers may select this option to force specific constant
167+
values for parameters 'm' (Galois field order) and 't'
168+
(error correction capability). Those specific values must
169+
be set by declaring default values for symbols BCH_CONST_M
170+
and BCH_CONST_T.
171+
Doing so will enable extra compiler optimizations,
172+
improving encoding and decoding performance up to 2x for
173+
usual (m,t) values (typically such that m*t < 200).
174+
When this option is selected, the BCH library supports
175+
only a single (m,t) configuration. This is mainly useful
176+
for NAND flash board drivers requiring known, fixed BCH
177+
parameters.
178+
179+
config BCH_CONST_M
180+
int
181+
range 5 15
182+
help
183+
Constant value for Galois field order 'm'. If 'k' is the
184+
number of data bits to protect, 'm' should be chosen such
185+
that (k + m*t) <= 2**m - 1.
186+
Drivers should declare a default value for this symbol if
187+
they select option BCH_CONST_PARAMS.
188+
189+
config BCH_CONST_T
190+
int
191+
help
192+
Constant value for error correction capability in bits 't'.
193+
Drivers should declare a default value for this symbol if
194+
they select option BCH_CONST_PARAMS.
195+
157196
#
158197
# Textsearch support is select'ed if needed
159198
#

lib/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
6767
obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
6868
obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
6969
obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
70+
obj-$(CONFIG_BCH) += bch.o
7071
obj-$(CONFIG_LZO_COMPRESS) += lzo/
7172
obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
7273
obj-$(CONFIG_XZ_DEC) += xz/

0 commit comments

Comments
 (0)