Statistics
| Branch: | Revision:

root / hw / ecc.c @ ee118d95

History | View | Annotate | Download (2.8 kB)

1 3e3d5815 balrog
/*
2 3e3d5815 balrog
 * Calculate Error-correcting Codes. Used by NAND Flash controllers
3 3e3d5815 balrog
 * (not by NAND chips).
4 3e3d5815 balrog
 *
5 3e3d5815 balrog
 * Copyright (c) 2006 Openedhand Ltd.
6 3e3d5815 balrog
 * Written by Andrzej Zaborowski <balrog@zabor.org>
7 3e3d5815 balrog
 *
8 3e3d5815 balrog
 * This code is licensed under the GNU GPL v2.
9 3e3d5815 balrog
 */
10 3e3d5815 balrog
11 87ecb68b pbrook
#include "hw.h"
12 87ecb68b pbrook
#include "flash.h"
13 3e3d5815 balrog
14 3e3d5815 balrog
/*
15 3e3d5815 balrog
 * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
16 3e3d5815 balrog
 */
17 3e3d5815 balrog
static const uint8_t nand_ecc_precalc_table[] = {
18 3e3d5815 balrog
    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
19 3e3d5815 balrog
    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
20 3e3d5815 balrog
    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
21 3e3d5815 balrog
    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
22 3e3d5815 balrog
    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
23 3e3d5815 balrog
    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
24 3e3d5815 balrog
    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
25 3e3d5815 balrog
    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
26 3e3d5815 balrog
    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
27 3e3d5815 balrog
    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
28 3e3d5815 balrog
    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
29 3e3d5815 balrog
    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
30 3e3d5815 balrog
    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
31 3e3d5815 balrog
    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
32 3e3d5815 balrog
    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
33 3e3d5815 balrog
    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
34 3e3d5815 balrog
    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
35 3e3d5815 balrog
    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
36 3e3d5815 balrog
    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
37 3e3d5815 balrog
    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
38 3e3d5815 balrog
    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
39 3e3d5815 balrog
    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
40 3e3d5815 balrog
    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
41 3e3d5815 balrog
    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
42 3e3d5815 balrog
    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
43 3e3d5815 balrog
    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
44 3e3d5815 balrog
    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
45 3e3d5815 balrog
    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
46 3e3d5815 balrog
    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
47 3e3d5815 balrog
    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
48 3e3d5815 balrog
    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
49 3e3d5815 balrog
    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
50 3e3d5815 balrog
};
51 3e3d5815 balrog
52 3e3d5815 balrog
/* Update ECC parity count.  */
53 bc24a225 Paul Brook
uint8_t ecc_digest(ECCState *s, uint8_t sample)
54 3e3d5815 balrog
{
55 3e3d5815 balrog
    uint8_t idx = nand_ecc_precalc_table[sample];
56 3e3d5815 balrog
57 3e3d5815 balrog
    s->cp ^= idx & 0x3f;
58 3e3d5815 balrog
    if (idx & 0x40) {
59 3e3d5815 balrog
        s->lp[0] ^= ~s->count;
60 3e3d5815 balrog
        s->lp[1] ^= s->count;
61 3e3d5815 balrog
    }
62 3e3d5815 balrog
    s->count ++;
63 3e3d5815 balrog
64 3e3d5815 balrog
    return sample;
65 3e3d5815 balrog
}
66 3e3d5815 balrog
67 3e3d5815 balrog
/* Reinitialise the counters.  */
68 bc24a225 Paul Brook
void ecc_reset(ECCState *s)
69 3e3d5815 balrog
{
70 3e3d5815 balrog
    s->lp[0] = 0x0000;
71 3e3d5815 balrog
    s->lp[1] = 0x0000;
72 3e3d5815 balrog
    s->cp = 0x00;
73 3e3d5815 balrog
    s->count = 0;
74 3e3d5815 balrog
}
75 aa941b94 balrog
76 aa941b94 balrog
/* Save/restore */
77 bc24a225 Paul Brook
void ecc_put(QEMUFile *f, ECCState *s)
78 aa941b94 balrog
{
79 aa941b94 balrog
    qemu_put_8s(f, &s->cp);
80 aa941b94 balrog
    qemu_put_be16s(f, &s->lp[0]);
81 aa941b94 balrog
    qemu_put_be16s(f, &s->lp[1]);
82 aa941b94 balrog
    qemu_put_be16s(f, &s->count);
83 aa941b94 balrog
}
84 aa941b94 balrog
85 bc24a225 Paul Brook
void ecc_get(QEMUFile *f, ECCState *s)
86 aa941b94 balrog
{
87 aa941b94 balrog
    qemu_get_8s(f, &s->cp);
88 aa941b94 balrog
    qemu_get_be16s(f, &s->lp[0]);
89 aa941b94 balrog
    qemu_get_be16s(f, &s->lp[1]);
90 aa941b94 balrog
    qemu_get_be16s(f, &s->count);
91 aa941b94 balrog
}