1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11: #include "hw.h"
12: #include "flash.h"
13:
14:
15:
16:
17: static const uint8_t nand_ecc_precalc_table[] = {
18: 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
19: 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
20: 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
21: 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
22: 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
23: 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
24: 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
25: 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
26: 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
27: 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
28: 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
29: 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
30: 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
31: 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
32: 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
33: 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
34: 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
35: 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
36: 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
37: 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
38: 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
39: 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
40: 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
41: 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
42: 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
43: 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
44: 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
45: 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
46: 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
47: 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
48: 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
49: 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
50: };
51:
52:
53: uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
54: {
55: uint8_t idx = nand_ecc_precalc_table[sample];
56:
57: s->cp ^= idx & 0x3f;
58: if (idx & 0x40) {
59: s->lp[0] ^= ~s->count;
60: s->lp[1] ^= s->count;
61: }
62: s->count ++;
63:
64: return sample;
65: }
66:
67:
68: void ecc_reset(struct ecc_state_s *s)
69: {
70: s->lp[0] = 0x0000;
71: s->lp[1] = 0x0000;
72: s->cp = 0x00;
73: s->count = 0;
74: }
75:
76:
77: void ecc_put(QEMUFile *f, struct ecc_state_s *s)
78: {
79: qemu_put_8s(f, &s->cp);
80: qemu_put_be16s(f, &s->lp[0]);
81: qemu_put_be16s(f, &s->lp[1]);
82: qemu_put_be16s(f, &s->count);
83: }
84:
85: void ecc_get(QEMUFile *f, struct ecc_state_s *s)
86: {
87: qemu_get_8s(f, &s->cp);
88: qemu_get_be16s(f, &s->lp[0]);
89: qemu_get_be16s(f, &s->lp[1]);
90: qemu_get_be16s(f, &s->count);
91: }