Date:2010-10-14 16:11:47 (13 years 5 months ago)
Author:Bas Wijnen
Commit:7e8cc1d25eeee91fbfa3ce753c486d347bdcb6af
Message:use proper place for 2 GB ecc

Files: mips/nand.hhp (7 diffs)

Change Details

mips/nand.hhp
5858static unsigned block_bits
5959static unsigned size_bits
6060static unsigned word_size
61static unsigned ecc_start
6162
6263static void unbusy ():
6364    while !(gpio_get_port (2) & (1 << 30)):
...... 
117118    unsigned num_planes_bits = d >> 2 & 3
118119    unsigned plane_bits = 26 + (d >> 4 & 7)
119120    size_bits = plane_bits + num_planes_bits - 3
121    if page_bits == 11:
122        ecc_start = 6
123    else if page_bits == 12:
124        ecc_start = 12
125    else:
126        debug ("unknown nand type; assuming ecc offset to be 6. This is probably wrong!\n")
127        ecc_start = 6
120128
121129static bool read (unsigned a, char *buffer):
122130    unsigned column = a & ((1 << page_bits) - 1)
...... 
134142    // 33: 9-byte ecc of 4th 512 bytes
135143    // 42: unused
136144    // 64: end of space
137    unsigned col = (1 << page_bits) + 6 + 9 * (column >> 9)
145
146    // For 2 GB nand:
147    // 0-11: unused/bad block markers
148    // 12-89: 8 times 9-byte ecc
149    // 90-127: unused
150    // 128: end of space
151    unsigned col = (1 << page_bits) + ecc_start + 9 * (column >> 9)
138152    cmd (CMD_READ0)
139153    addr (col)
140154    addr (col >> 8)
...... 
143157    addr (row >> 16)
144158    cmd (CMD_READSTART)
145159    //debug ("parity data:")
160    bool parity_all_ff = true
146161    for unsigned t = 0; t < 9; ++t:
147162        error[t] = rdata ()
163        if parity_all_ff && (error[t] & 0xff) != 0xff:
164            parity_all_ff = false
148165        //debug (" %x", error[t] & 0xff)
149166    //debug ("\n")
150167    cmd (CMD_RNDOUT)
...... 
153170    cmd (CMD_RNDOUTSTART)
154171    EMC_NFINTS = 0
155172    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
173    bool all_ff = true
156174    for unsigned t = 0; t < 0x200; ++t:
157175        buffer[t] = rdata ()
158    for unsigned t = 0; t < 9; ++t:
159        ((volatile char *)&EMC_NFPAR (0))[t] = error[t]
160    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
161    while !(EMC_NFINTS & EMC_NFINTS_DECF):
162        DELAY ()
163    unsigned ints = EMC_NFINTS
164    if ints & EMC_NFINTS_UNCOR:
165        debug ("uncorrectable error in nand at %x\n", a)
166        return false
167    unsigned errs = (ints & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
168    for unsigned i = 0; i < errs; ++i:
169        unsigned err = EMC_NFERR (i)
170        unsigned index = (err >> 16) - 1
171        unsigned mask = err & 0x1ff
172        unsigned bit = index * 9
173        unsigned offset= bit & 7
174        unsigned byte = bit / 8
175        debug ("correcting %x on %x+%d\n", mask, byte, offset)
176        unsigned data = buffer[byte] | buffer[byte + 1] << 8
177        data ^= mask << offset
178        buffer[byte] = data
179        buffer[byte + 1] = data >> 8
176        if all_ff && (buffer[t] & 0xff) != 0xff:
177            all_ff = false
178    if !all_ff || !parity_all_ff:
179        for unsigned t = 0; t < 9; ++t:
180            ((volatile char *)&EMC_NFPAR (0))[t] = error[t]
181        EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
182        while !(EMC_NFINTS & EMC_NFINTS_DECF):
183            DELAY ()
184        unsigned ints = EMC_NFINTS
185        if ints & EMC_NFINTS_UNCOR:
186            debug ("uncorrectable error in nand at %x\n", a)
187            return false
188        unsigned errs = (ints & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
189        for unsigned i = 0; i < errs; ++i:
190            unsigned err = EMC_NFERR (i)
191            unsigned index = (err >> 16) - 1
192            unsigned mask = err & 0x1ff
193            unsigned bit = index * 9
194            unsigned offset= bit & 7
195            unsigned byte = bit / 8
196            debug ("correcting %x on %x+%d\n", mask, byte, offset)
197            unsigned data = buffer[byte] | buffer[byte + 1] << 8
198            data ^= mask << offset
199            buffer[byte] = data
200            buffer[byte + 1] = data >> 8
180201    #if 0
181202    for unsigned i = 0; i < 0x10; ++i:
182203        if (buffer[i] & 0xff) < 0x10:
...... 
228249    // 33: 9-byte ecc of 4th 512 bytes
229250    // 42: unused
230251    // 64: end of space
231    for unsigned i = 0; i < 6; ++i:
232        wdata (0)
252
253    // For 2 GB nand:
254    // 0-11: unused/bad block markers
255    // 12-89: 8 times 9-byte ecc
256    // 90-127: unused
257    // 128: end of space
258    for unsigned i = 0; i < ecc_start; ++i:
259        wdata (i == 4 ? 0 : 0xff)
233260    for unsigned i = 0; i < 1 << (page_bits - 9); ++i:
234261        for unsigned j = 0; j < 9; ++j:
235262            wdata (ecc[i][j])
...... 
268295            unsigned offset= bit & 7
269296            unsigned byte = bit / 8
270297            debug ("error detected by parity: %x on %x+%d\n", mask, byte, offset)
271    for unsigned i = 0; i < 6; ++i:
272        if rdata () != 0:
273            debug ("extra data not 0 at byte %d\n", i)
298    for unsigned i = 0; i < ecc_start; ++i:
299        if rdata () != (i == 4 ? 0 : 0xff):
300            debug ("incorrect extra data at byte %d\n", i)
274301    for unsigned i = 0; i < 1 << (page_bits - 9); ++i:
275302        for unsigned j = 0; j < 9; ++j:
276303            unsigned r = rdata () & 0xff

Archive Download the corresponding diff file

Branches:
master



interactive