Fix MIPS cache configuration, by Aurelien Jarno.
[qemu] / ecc.h
1 /*
2  * Calculate Error-correcting Codes. Used by NAND Flash controllers
3  * (not by NAND chips).
4  *
5  * Copyright (c) 2006 Openedhand Ltd.
6  * Written by Andrzej Zaborowski <balrog@zabor.org>
7  *
8  * This code is licensed under the GNU GPL v2.
9  */
10
11 struct ecc_state_s {
12     uint8_t cp;         /* Column parity */
13     uint16_t lp[2];     /* Line parity */
14     uint16_t count;
15 };
16
17 /*
18  * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
19  */
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,
53 };
54
55 /* Update ECC parity count.  */
56 static inline uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
57 {
58     uint8_t idx = nand_ecc_precalc_table[sample];
59
60     s->cp ^= idx & 0x3f;
61     if (idx & 0x40) {
62         s->lp[0] ^= ~s->count;
63         s->lp[1] ^= s->count;
64     }
65     s->count ++;
66
67     return sample;
68 }
69
70 /* Reinitialise the counters.  */
71 static inline void ecc_reset(struct ecc_state_s *s)
72 {
73     s->lp[0] = 0x0000;
74     s->lp[1] = 0x0000;
75     s->cp = 0x00;
76     s->count = 0;
77 }
78
79 /* Save/restore */
80 static inline void ecc_put(QEMUFile *f, struct ecc_state_s *s)
81 {
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);
86 }
87
88 static inline void ecc_get(QEMUFile *f, struct ecc_state_s *s)
89 {
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);
94 }