qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ecc.c (3038B)


      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  * Contributions after 2012-01-13 are licensed under the terms of the
     11  * GNU GPL, version 2 or (at your option) any later version.
     12  */
     13 
     14 #include "qemu/osdep.h"
     15 #include "migration/vmstate.h"
     16 #include "hw/block/flash.h"
     17 
     18 /*
     19  * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
     20  */
     21 static const uint8_t nand_ecc_precalc_table[] = {
     22     0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
     23     0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
     24     0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
     25     0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
     26     0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
     27     0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
     28     0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
     29     0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
     30     0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
     31     0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
     32     0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
     33     0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
     34     0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
     35     0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
     36     0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
     37     0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
     38     0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
     39     0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
     40     0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
     41     0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
     42     0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
     43     0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
     44     0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
     45     0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
     46     0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
     47     0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
     48     0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
     49     0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
     50     0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
     51     0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
     52     0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
     53     0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
     54 };
     55 
     56 /* Update ECC parity count.  */
     57 uint8_t ecc_digest(ECCState *s, uint8_t sample)
     58 {
     59     uint8_t idx = nand_ecc_precalc_table[sample];
     60 
     61     s->cp ^= idx & 0x3f;
     62     if (idx & 0x40) {
     63         s->lp[0] ^= ~s->count;
     64         s->lp[1] ^= s->count;
     65     }
     66     s->count ++;
     67 
     68     return sample;
     69 }
     70 
     71 /* Reinitialise the counters.  */
     72 void ecc_reset(ECCState *s)
     73 {
     74     s->lp[0] = 0x0000;
     75     s->lp[1] = 0x0000;
     76     s->cp = 0x00;
     77     s->count = 0;
     78 }
     79 
     80 /* Save/restore */
     81 const VMStateDescription vmstate_ecc_state = {
     82     .name = "ecc-state",
     83     .version_id = 0,
     84     .minimum_version_id = 0,
     85     .fields = (VMStateField[]) {
     86         VMSTATE_UINT8(cp, ECCState),
     87         VMSTATE_UINT16_ARRAY(lp, ECCState, 2),
     88         VMSTATE_UINT16(count, ECCState),
     89         VMSTATE_END_OF_LIST(),
     90     },
     91 };