Reset buffer pointers after CR/LF, by Jim Paris.
[qemu/dscho.git] / ecc.h
blobe8e39426f5778ca79720f70a09e3ce1c5ba02c2b
1 /*
2 * Calculate Error-correcting Codes. Used by NAND Flash controllers
3 * (not by NAND chips).
5 * Copyright (c) 2006 Openedhand Ltd.
6 * Written by Andrzej Zaborowski <balrog@zabor.org>
8 * This code is licensed under the GNU GPL v2.
9 */
11 struct ecc_state_s {
12 uint8_t cp; /* Column parity */
13 uint16_t lp[2]; /* Line parity */
14 uint16_t count;
18 * Pre-calculated 256-way 1 byte column parity. Table borrowed from Linux.
20 static const uint8_t nand_ecc_precalc_table[] = {
21 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
22 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
23 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
24 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
25 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
26 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
27 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
28 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
29 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
30 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
31 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
32 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
33 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
34 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
35 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
36 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
37 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
38 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
39 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
40 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
41 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
42 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
43 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
44 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
45 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
46 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
47 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
48 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
49 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
50 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
51 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
52 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
55 /* Update ECC parity count. */
56 static inline uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
58 uint8_t idx = nand_ecc_precalc_table[sample];
60 s->cp ^= idx & 0x3f;
61 if (idx & 0x40) {
62 s->lp[0] ^= ~s->count;
63 s->lp[1] ^= s->count;
65 s->count ++;
67 return sample;
70 /* Reinitialise the counters. */
71 static inline void ecc_reset(struct ecc_state_s *s)
73 s->lp[0] = 0x0000;
74 s->lp[1] = 0x0000;
75 s->cp = 0x00;
76 s->count = 0;
79 /* Save/restore */
80 static inline void ecc_put(QEMUFile *f, struct ecc_state_s *s)
82 qemu_put_8s(f, &s->cp);
83 qemu_put_be16s(f, &s->lp[0]);
84 qemu_put_be16s(f, &s->lp[1]);
85 qemu_put_be16s(f, &s->count);
88 static inline void ecc_get(QEMUFile *f, struct ecc_state_s *s)
90 qemu_get_8s(f, &s->cp);
91 qemu_get_be16s(f, &s->lp[0]);
92 qemu_get_be16s(f, &s->lp[1]);
93 qemu_get_be16s(f, &s->count);