~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/ecc.c

  • Committer: pbrook
  • Date: 2006-10-22 00:18:54 UTC
  • Revision ID: git-v1:e6e5906b6e0a81718066ca43aef57515026c6624
ColdFire target.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2196 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "hw.h"
12
 
#include "flash.h"
13
 
 
14
 
/*
15
 
 * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
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
 
/* Update ECC parity count.  */
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
 
/* Reinitialise the counters.  */
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
 
/* Save/restore */
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
 
}