symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/ecc.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 }