c154d6979898841730bcff583068b8ffaff789b4
[openocd.git] / src / flash / nand_ecc.c
1 /*
2 * This file contains an ECC algorithm from Toshiba that allows for detection
3 * and correction of 1-bit errors in a 256 byte block of data.
4 *
5 * [ Extracted from the initial code found in some early Linux versions.
6 * The current Linux code is bigger while being faster, but this is of
7 * no real benefit when the bottleneck largely remains the JTAG link. ]
8 *
9 * Copyright (C) 2000-2004 Steven J. Hill (sjhill at realitydiluted.com)
10 * Toshiba America Electronics Components, Inc.
11 *
12 * Copyright (C) 2006 Thomas Gleixner <tglx at linutronix.de>
13 *
14 * This file is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 or (at your option) any
17 * later version.
18 *
19 * This file is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this file; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 *
28 * As a special exception, if other files instantiate templates or use
29 * macros or inline functions from these files, or you compile these
30 * files and link them with other works to produce a work based on these
31 * files, these files do not by themselves cause the resulting work to be
32 * covered by the GNU General Public License. However the source code for
33 * these files must still be made available in accordance with section (3)
34 * of the GNU General Public License.
35 *
36 * This exception does not invalidate any other reasons why a work based on
37 * this file might be covered by the GNU General Public License.
38 */
39
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include "nand.h"
45
46 /*
47 * Pre-calculated 256-way 1 byte column parity
48 */
49 static const uint8_t nand_ecc_precalc_table[] = {
50 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
51 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
52 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
53 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
54 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
55 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
56 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
57 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
58 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
59 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
60 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
61 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
62 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
63 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
64 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
65 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
66 };
67
68 /*
69 * nand_calculate_ecc - Calculate 3-byte ECC for 256-byte block
70 */
71 int nand_calculate_ecc(struct nand_device_s *device, const uint8_t *dat, uint8_t *ecc_code)
72 {
73 uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
74 int i;
75
76 /* Initialize variables */
77 reg1 = reg2 = reg3 = 0;
78
79 /* Build up column parity */
80 for (i = 0; i < 256; i++) {
81 /* Get CP0 - CP5 from table */
82 idx = nand_ecc_precalc_table[*dat++];
83 reg1 ^= (idx & 0x3f);
84
85 /* All bit XOR = 1 ? */
86 if (idx & 0x40) {
87 reg3 ^= (uint8_t) i;
88 reg2 ^= ~((uint8_t) i);
89 }
90 }
91
92 /* Create non-inverted ECC code from line parity */
93 tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */
94 tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
95 tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
96 tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
97 tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
98 tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
99 tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
100 tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
101
102 tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */
103 tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
104 tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
105 tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
106 tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
107 tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
108 tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
109 tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
110
111 /* Calculate final ECC code */
112 #ifdef NAND_ECC_SMC
113 ecc_code[0] = ~tmp2;
114 ecc_code[1] = ~tmp1;
115 #else
116 ecc_code[0] = ~tmp1;
117 ecc_code[1] = ~tmp2;
118 #endif
119 ecc_code[2] = ((~reg1) << 2) | 0x03;
120
121 return 0;
122 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)