Add PowerPC power-management state check callback.
[qemu] / hw / ecc.c
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 #include "vl.h"
12
13 /*
14  * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
15  */
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,
49 };
50
51 /* Update ECC parity count.  */
52 uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
53 {
54     uint8_t idx = nand_ecc_precalc_table[sample];
55
56     s->cp ^= idx & 0x3f;
57     if (idx & 0x40) {
58         s->lp[0] ^= ~s->count;
59         s->lp[1] ^= s->count;
60     }
61     s->count ++;
62
63     return sample;
64 }
65
66 /* Reinitialise the counters.  */
67 void ecc_reset(struct ecc_state_s *s)
68 {
69     s->lp[0] = 0x0000;
70     s->lp[1] = 0x0000;
71     s->cp = 0x00;
72     s->count = 0;
73 }
74
75 /* Save/restore */
76 void ecc_put(QEMUFile *f, struct ecc_state_s *s)
77 {
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);
82 }
83
84 void ecc_get(QEMUFile *f, struct ecc_state_s *s)
85 {
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);
90 }