Fix configurations with more than 4GB of memory
[qemu-kvm/fedora.git] / hw / ecc.c
blob970ede806a1c48782d2cced9a1880a2d2aa53881
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 #include "vl.h"
14 * Pre-calculated 256-way 1 byte column parity. Table borrowed from Linux.
16 static const uint8_t nand_ecc_precalc_table[] = {
17 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
18 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
19 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
20 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
21 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
22 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
23 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
24 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
25 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
26 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
27 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
28 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
29 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
30 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
31 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
32 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
33 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
34 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
35 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
36 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
37 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
38 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
39 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
40 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
41 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
42 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
43 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
44 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
45 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
46 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
47 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
48 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
51 /* Update ECC parity count. */
52 uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
54 uint8_t idx = nand_ecc_precalc_table[sample];
56 s->cp ^= idx & 0x3f;
57 if (idx & 0x40) {
58 s->lp[0] ^= ~s->count;
59 s->lp[1] ^= s->count;
61 s->count ++;
63 return sample;
66 /* Reinitialise the counters. */
67 void ecc_reset(struct ecc_state_s *s)
69 s->lp[0] = 0x0000;
70 s->lp[1] = 0x0000;
71 s->cp = 0x00;
72 s->count = 0;
75 /* Save/restore */
76 void ecc_put(QEMUFile *f, struct ecc_state_s *s)
78 qemu_put_8s(f, &s->cp);
79 qemu_put_be16s(f, &s->lp[0]);
80 qemu_put_be16s(f, &s->lp[1]);
81 qemu_put_be16s(f, &s->count);
84 void ecc_get(QEMUFile *f, struct ecc_state_s *s)
86 qemu_get_8s(f, &s->cp);
87 qemu_get_be16s(f, &s->lp[0]);
88 qemu_get_be16s(f, &s->lp[1]);
89 qemu_get_be16s(f, &s->count);