diff options
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | 163 |
1 files changed, 85 insertions, 78 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c index 2c11ab5340..0ce268ac30 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | |||
@@ -83,7 +83,7 @@ struct ftl_log_type | |||
83 | 83 | ||
84 | /* Pages that are still up to date in this block, i.e. need to be | 84 | /* Pages that are still up to date in this block, i.e. need to be |
85 | moved when this vBlock is deallocated. */ | 85 | moved when this vBlock is deallocated. */ |
86 | uint16_t pagescurrent; | 86 | uint16_t pagescurrent; |
87 | 87 | ||
88 | /* A flag whether all pages are still sequential in this block. | 88 | /* A flag whether all pages are still sequential in this block. |
89 | Initialized to 1 on allocation, zeroed as soon as anything is | 89 | Initialized to 1 on allocation, zeroed as soon as anything is |
@@ -112,9 +112,9 @@ struct ftl_cxt_type | |||
112 | 112 | ||
113 | /* Count of currently free pages in the block pool */ | 113 | /* Count of currently free pages in the block pool */ |
114 | uint16_t freecount; | 114 | uint16_t freecount; |
115 | 115 | ||
116 | /* Index to the first free block in the blockpool ring buffer */ | 116 | /* Index to the first free block in the blockpool ring buffer */ |
117 | uint16_t nextfreeidx; | 117 | uint16_t nextfreeidx; |
118 | 118 | ||
119 | /* This is a counter that is used to better distribute block | 119 | /* This is a counter that is used to better distribute block |
120 | wear. It is incremented on every block erase, and if it | 120 | wear. It is incremented on every block erase, and if it |
@@ -129,7 +129,7 @@ struct ftl_cxt_type | |||
129 | uint16_t blockpool[0x14]; | 129 | uint16_t blockpool[0x14]; |
130 | 130 | ||
131 | /* Alignment to 32 bits */ | 131 | /* Alignment to 32 bits */ |
132 | uint16_t field_36; | 132 | uint16_t field_36; |
133 | 133 | ||
134 | /* vPages where the block map is stored */ | 134 | /* vPages where the block map is stored */ |
135 | uint32_t ftl_map_pages[8]; | 135 | uint32_t ftl_map_pages[8]; |
@@ -138,23 +138,23 @@ struct ftl_cxt_type | |||
138 | uint8_t field_58[0x28]; | 138 | uint8_t field_58[0x28]; |
139 | 139 | ||
140 | /* vPages where the erase counters are stored */ | 140 | /* vPages where the erase counters are stored */ |
141 | uint32_t ftl_erasectr_pages[8]; | 141 | uint32_t ftl_erasectr_pages[8]; |
142 | 142 | ||
143 | /* Seems to be padding */ | 143 | /* Seems to be padding */ |
144 | uint8_t field_A0[0x70]; | 144 | uint8_t field_A0[0x70]; |
145 | 145 | ||
146 | /* Pointer to ftl_map used by Whimory, not used by us */ | 146 | /* Pointer to ftl_map used by Whimory, not used by us */ |
147 | uint32_t ftl_map_ptr; | 147 | uint32_t ftl_map_ptr; |
148 | 148 | ||
149 | /* Pointer to ftl_erasectr used by Whimory, not used by us */ | 149 | /* Pointer to ftl_erasectr used by Whimory, not used by us */ |
150 | uint32_t ftl_erasectr_ptr; | 150 | uint32_t ftl_erasectr_ptr; |
151 | 151 | ||
152 | /* Pointer to ftl_log used by Whimory, not used by us */ | 152 | /* Pointer to ftl_log used by Whimory, not used by us */ |
153 | uint32_t ftl_log_ptr; | 153 | uint32_t ftl_log_ptr; |
154 | 154 | ||
155 | /* Flag used to indicate that some erase counter pages should be committed | 155 | /* Flag used to indicate that some erase counter pages should be committed |
156 | as they were changed more than 100 times since the last commit. */ | 156 | as they were changed more than 100 times since the last commit. */ |
157 | uint32_t erasedirty; | 157 | uint32_t erasedirty; |
158 | 158 | ||
159 | /* Seems to be unused */ | 159 | /* Seems to be unused */ |
160 | uint16_t field_120; | 160 | uint16_t field_120; |
@@ -163,7 +163,7 @@ struct ftl_cxt_type | |||
163 | counter pages. This is also a ring buffer, and the oldest | 163 | counter pages. This is also a ring buffer, and the oldest |
164 | page gets swapped with the least used page from the block | 164 | page gets swapped with the least used page from the block |
165 | pool ring buffer when a new one is allocated. */ | 165 | pool ring buffer when a new one is allocated. */ |
166 | uint16_t ftlctrlblocks[3]; | 166 | uint16_t ftlctrlblocks[3]; |
167 | 167 | ||
168 | /* The last used vPage number from ftlctrlblocks */ | 168 | /* The last used vPage number from ftlctrlblocks */ |
169 | uint32_t ftlctrlpage; | 169 | uint32_t ftlctrlpage; |
@@ -173,7 +173,7 @@ struct ftl_cxt_type | |||
173 | uint32_t clean_flag; | 173 | uint32_t clean_flag; |
174 | 174 | ||
175 | /* Seems to be unused, but gets loaded from flash by Whimory. */ | 175 | /* Seems to be unused, but gets loaded from flash by Whimory. */ |
176 | uint8_t field_130[0x15C]; | 176 | uint8_t field_130[0x15C]; |
177 | 177 | ||
178 | } __attribute__((packed)) FTLCxtType; | 178 | } __attribute__((packed)) FTLCxtType; |
179 | 179 | ||
@@ -185,7 +185,7 @@ typedef struct ftl_vfl_cxt_type | |||
185 | 185 | ||
186 | /* Cross-bank update sequence number, incremented on every VFL | 186 | /* Cross-bank update sequence number, incremented on every VFL |
187 | context commit on any bank. */ | 187 | context commit on any bank. */ |
188 | uint32_t usn; | 188 | uint32_t usn; |
189 | 189 | ||
190 | /* See ftl_cxt.ftlctrlblocks. This is stored to the VFL contexts | 190 | /* See ftl_cxt.ftlctrlblocks. This is stored to the VFL contexts |
191 | in order to be able to find the most recent FTL context copy | 191 | in order to be able to find the most recent FTL context copy |
@@ -194,14 +194,14 @@ typedef struct ftl_vfl_cxt_type | |||
194 | uint16_t ftlctrlblocks[3]; | 194 | uint16_t ftlctrlblocks[3]; |
195 | 195 | ||
196 | /* Alignment to 32 bits */ | 196 | /* Alignment to 32 bits */ |
197 | uint8_t field_A[2]; | 197 | uint8_t field_A[2]; |
198 | 198 | ||
199 | /* Decrementing update counter for VFL context commits per bank */ | 199 | /* Decrementing update counter for VFL context commits per bank */ |
200 | uint32_t updatecount; | 200 | uint32_t updatecount; |
201 | 201 | ||
202 | /* Number of the currently active VFL context block, it's an index | 202 | /* Number of the currently active VFL context block, it's an index |
203 | into vflcxtblocks. */ | 203 | into vflcxtblocks. */ |
204 | uint16_t activecxtblock; | 204 | uint16_t activecxtblock; |
205 | 205 | ||
206 | /* Number of the first free page in the active FTL context block */ | 206 | /* Number of the first free page in the active FTL context block */ |
207 | uint16_t nextcxtpage; | 207 | uint16_t nextcxtpage; |
@@ -217,31 +217,31 @@ typedef struct ftl_vfl_cxt_type | |||
217 | uint16_t spareused; | 217 | uint16_t spareused; |
218 | 218 | ||
219 | /* pBlock number of the first spare block */ | 219 | /* pBlock number of the first spare block */ |
220 | uint16_t firstspare; | 220 | uint16_t firstspare; |
221 | 221 | ||
222 | /* Total number of spare blocks */ | 222 | /* Total number of spare blocks */ |
223 | uint16_t sparecount; | 223 | uint16_t sparecount; |
224 | 224 | ||
225 | /* Block remap table. Contains the vBlock number the n-th spare | 225 | /* Block remap table. Contains the vBlock number the n-th spare |
226 | block is used as a replacement for. 0 = unused, 0xFFFF = bad. */ | 226 | block is used as a replacement for. 0 = unused, 0xFFFF = bad. */ |
227 | uint16_t remaptable[0x334]; | 227 | uint16_t remaptable[0x334]; |
228 | 228 | ||
229 | /* Bad block table. Each bit represents 8 blocks. 1 = OK, 0 = Bad. | 229 | /* Bad block table. Each bit represents 8 blocks. 1 = OK, 0 = Bad. |
230 | If the entry is zero, you should look at the remap table to see | 230 | If the entry is zero, you should look at the remap table to see |
231 | if the block is remapped, and if yes, where the replacement is. */ | 231 | if the block is remapped, and if yes, where the replacement is. */ |
232 | uint8_t bbt[0x11A]; | 232 | uint8_t bbt[0x11A]; |
233 | 233 | ||
234 | /* pBlock numbers used to store the VFL context. This is a ring | 234 | /* pBlock numbers used to store the VFL context. This is a ring |
235 | buffer. On a VFL context write, always 8 pages are written, | 235 | buffer. On a VFL context write, always 8 pages are written, |
236 | and it passes if at least 4 of them can be read back. */ | 236 | and it passes if at least 4 of them can be read back. */ |
237 | uint16_t vflcxtblocks[4]; | 237 | uint16_t vflcxtblocks[4]; |
238 | 238 | ||
239 | /* Blocks scheduled for remapping are stored at the end of the | 239 | /* Blocks scheduled for remapping are stored at the end of the |
240 | remap table. This is the first index used for them. */ | 240 | remap table. This is the first index used for them. */ |
241 | uint16_t scheduledstart; | 241 | uint16_t scheduledstart; |
242 | 242 | ||
243 | /* Probably padding */ | 243 | /* Probably padding */ |
244 | uint8_t field_7AC[0x4C]; | 244 | uint8_t field_7AC[0x4C]; |
245 | 245 | ||
246 | /* First checksum (addition) */ | 246 | /* First checksum (addition) */ |
247 | uint32_t checksum1; | 247 | uint32_t checksum1; |
@@ -265,17 +265,17 @@ union ftl_spare_data_type | |||
265 | 265 | ||
266 | /* The update sequence number of that page, | 266 | /* The update sequence number of that page, |
267 | copied from ftl_cxt.nextblockusn on write */ | 267 | copied from ftl_cxt.nextblockusn on write */ |
268 | uint32_t usn; | 268 | uint32_t usn; |
269 | 269 | ||
270 | /* Seems to be unused */ | 270 | /* Seems to be unused */ |
271 | uint8_t field_8; | 271 | uint8_t field_8; |
272 | 272 | ||
273 | /* Type field, 0x40 (data page) or 0x41 (last data page of block) */ | 273 | /* Type field, 0x40 (data page) or 0x41 (last data page of block) */ |
274 | uint8_t type; | 274 | uint8_t type; |
275 | 275 | ||
276 | /* ECC mark, usually 0xFF. If an error occurred while reading the | 276 | /* ECC mark, usually 0xFF. If an error occurred while reading the |
277 | page during a copying operation earlier, this will be 0x55. */ | 277 | page during a copying operation earlier, this will be 0x55. */ |
278 | uint8_t eccmark; | 278 | uint8_t eccmark; |
279 | 279 | ||
280 | /* Seems to be unused */ | 280 | /* Seems to be unused */ |
281 | uint8_t field_B; | 281 | uint8_t field_B; |
@@ -297,10 +297,10 @@ union ftl_spare_data_type | |||
297 | 297 | ||
298 | /* Index of the thing inside the page, | 298 | /* Index of the thing inside the page, |
299 | for example number / index of the map or erase counter page */ | 299 | for example number / index of the map or erase counter page */ |
300 | uint16_t idx; | 300 | uint16_t idx; |
301 | 301 | ||
302 | /* Seems to be unused */ | 302 | /* Seems to be unused */ |
303 | uint8_t field_6; | 303 | uint8_t field_6; |
304 | 304 | ||
305 | /* Seems to be unused */ | 305 | /* Seems to be unused */ |
306 | uint8_t field_7; | 306 | uint8_t field_7; |
@@ -318,7 +318,7 @@ union ftl_spare_data_type | |||
318 | 318 | ||
319 | /* ECC mark, usually 0xFF. If an error occurred while reading the | 319 | /* ECC mark, usually 0xFF. If an error occurred while reading the |
320 | page during a copying operation earlier, this will be 0x55. */ | 320 | page during a copying operation earlier, this will be 0x55. */ |
321 | uint8_t eccmark; | 321 | uint8_t eccmark; |
322 | 322 | ||
323 | /* Seems to be unused */ | 323 | /* Seems to be unused */ |
324 | uint8_t field_B; | 324 | uint8_t field_B; |
@@ -339,14 +339,14 @@ struct ftl_trouble_type | |||
339 | { | 339 | { |
340 | 340 | ||
341 | /* vBlock number of the block giving trouble */ | 341 | /* vBlock number of the block giving trouble */ |
342 | uint16_t block; | 342 | uint16_t block; |
343 | 343 | ||
344 | /* Bank of the block giving trouble */ | 344 | /* Bank of the block giving trouble */ |
345 | uint8_t bank; | 345 | uint8_t bank; |
346 | 346 | ||
347 | /* Error counter, incremented by 3 on error, decremented by 1 on erase, | 347 | /* Error counter, incremented by 3 on error, decremented by 1 on erase, |
348 | remaping will be done when it reaches 6. */ | 348 | remaping will be done when it reaches 6. */ |
349 | uint8_t errors; | 349 | uint8_t errors; |
350 | 350 | ||
351 | } __attribute__((packed)); | 351 | } __attribute__((packed)); |
352 | 352 | ||
@@ -359,47 +359,57 @@ const struct nand_device_info_type* ftl_nand_type; | |||
359 | uint32_t ftl_banks; | 359 | uint32_t ftl_banks; |
360 | 360 | ||
361 | /* Block map, used vor pBlock to vBlock mapping */ | 361 | /* Block map, used vor pBlock to vBlock mapping */ |
362 | uint16_t ftl_map[0x2000]; | 362 | uint16_t ftl_map[0x2000]; |
363 | 363 | ||
364 | /* VFL context for each bank */ | 364 | /* VFL context for each bank */ |
365 | struct ftl_vfl_cxt_type ftl_vfl_cxt[4]; | 365 | struct ftl_vfl_cxt_type ftl_vfl_cxt[4]; |
366 | 366 | ||
367 | /* FTL context */ | 367 | /* FTL context */ |
368 | struct ftl_cxt_type ftl_cxt; | 368 | struct ftl_cxt_type ftl_cxt; |
369 | 369 | ||
370 | /* Temporary data buffer for internal use by the FTL */ | 370 | /* Temporary data buffers for internal use by the FTL */ |
371 | uint8_t ftl_buffer[0x800] __attribute__((aligned(16))); | 371 | uint8_t ftl_buffer[0x800] __attribute__((aligned(16))); |
372 | 372 | ||
373 | /* Temporary spare byte buffer for internal use by the FTL */ | 373 | /* Temporary spare byte buffer for internal use by the FTL */ |
374 | union ftl_spare_data_type ftl_sparebuffer __attribute__((aligned(16))); | 374 | union ftl_spare_data_type ftl_sparebuffer __attribute__((aligned(16))); |
375 | 375 | ||
376 | 376 | ||
377 | #ifndef FTL_READONLY | 377 | #ifndef FTL_READONLY |
378 | 378 | ||
379 | /* Lowlevel BBT for each bank */ | 379 | /* Lowlevel BBT for each bank */ |
380 | uint8_t ftl_bbt[4][0x410]; | 380 | uint8_t ftl_bbt[4][0x410]; |
381 | 381 | ||
382 | /* Erase countes for the vBlocks */ | 382 | /* Erase countes for the vBlocks */ |
383 | uint16_t ftl_erasectr[0x2000]; | 383 | uint16_t ftl_erasectr[0x2000]; |
384 | 384 | ||
385 | /* Used by ftl_log */ | 385 | /* Used by ftl_log */ |
386 | uint16_t ftl_offsets[0x11][0x200]; | 386 | uint16_t ftl_offsets[0x11][0x200]; |
387 | 387 | ||
388 | /* Structs keeping record of scattered page blocks */ | 388 | /* Structs keeping record of scattered page blocks */ |
389 | struct ftl_log_type ftl_log[0x11]; | 389 | struct ftl_log_type ftl_log[0x11]; |
390 | 390 | ||
391 | /* Global cross-bank update sequence number of the VFL context */ | 391 | /* Global cross-bank update sequence number of the VFL context */ |
392 | uint32_t ftl_vfl_usn; | 392 | uint32_t ftl_vfl_usn; |
393 | 393 | ||
394 | /* Keeps track (temporarily) of troublesome blocks */ | 394 | /* Keeps track (temporarily) of troublesome blocks */ |
395 | struct ftl_trouble_type ftl_troublelog[5]; | 395 | struct ftl_trouble_type ftl_troublelog[5]; |
396 | 396 | ||
397 | /* Counts erase counter page changes, after 100 of them the affected | 397 | /* Counts erase counter page changes, after 100 of them the affected |
398 | page will be committed to the flash. */ | 398 | page will be committed to the flash. */ |
399 | uint8_t ftl_erasectr_dirt[8]; | 399 | uint8_t ftl_erasectr_dirt[8]; |
400 | 400 | ||
401 | /* Buffer needed for copying pages around while moving or committing blocks. | ||
402 | This can't be shared with ftl_buffer, because this one could be overwritten | ||
403 | during the copying operation in order to e.g. commit a CXT. */ | ||
404 | uint8_t ftl_copybuffer[0x800] __attribute__((aligned(16))); | ||
405 | |||
406 | /* Needed to store the old scattered page offsets in order to be able to roll | ||
407 | back if something fails while compacting a scattered page block. */ | ||
408 | uint16_t ftl_offsets_backup[0x200] __attribute__((aligned(16))); | ||
409 | |||
401 | #endif | 410 | #endif |
402 | 411 | ||
412 | |||
403 | static struct mutex ftl_mtx; | 413 | static struct mutex ftl_mtx; |
404 | 414 | ||
405 | 415 | ||
@@ -413,28 +423,28 @@ uint32_t ftl_find_devinfo(uint32_t bank) | |||
413 | - ((*ftl_nand_type).blocks / 10); | 423 | - ((*ftl_nand_type).blocks / 10); |
414 | uint32_t block, page, pagenum; | 424 | uint32_t block, page, pagenum; |
415 | for (block = (*ftl_nand_type).blocks - 1; block >= lowestBlock; block--) | 425 | for (block = (*ftl_nand_type).blocks - 1; block >= lowestBlock; block--) |
416 | { | 426 | { |
417 | page = (*ftl_nand_type).pagesperblock - 8; | 427 | page = (*ftl_nand_type).pagesperblock - 8; |
418 | for (; page < (*ftl_nand_type).pagesperblock; page++) | 428 | for (; page < (*ftl_nand_type).pagesperblock; page++) |
419 | { | 429 | { |
420 | pagenum = block * (*ftl_nand_type).pagesperblock + page; | 430 | pagenum = block * (*ftl_nand_type).pagesperblock + page; |
421 | if ((nand_read_page(bank, pagenum, ftl_buffer, | 431 | if ((nand_read_page(bank, pagenum, ftl_buffer, |
422 | &ftl_sparebuffer, 1, 0) & 0x11F) != 0) | 432 | &ftl_sparebuffer, 1, 0) & 0x11F) != 0) |
423 | continue; | 433 | continue; |
424 | if (memcmp(ftl_buffer, "DEVICEINFOSIGN\0", 0x10) == 0) | 434 | if (memcmp(ftl_buffer, "DEVICEINFOSIGN\0", 0x10) == 0) |
425 | return pagenum; | 435 | return pagenum; |
426 | } | 436 | } |
427 | } | 437 | } |
428 | return 0; | 438 | return 0; |
429 | } | 439 | } |
430 | 440 | ||
431 | 441 | ||
432 | /* Checks if all banks have proper device info pages */ | 442 | /* Checks if all banks have proper device info pages */ |
433 | uint32_t ftl_has_devinfo(void) | 443 | uint32_t ftl_has_devinfo(void) |
434 | { | 444 | { |
435 | uint32_t i; | 445 | uint32_t i; |
436 | for (i = 0; i < ftl_banks; i++) if (ftl_find_devinfo(i) == 0) return 0; | 446 | for (i = 0; i < ftl_banks; i++) if (ftl_find_devinfo(i) == 0) return 0; |
437 | return 1; | 447 | return 1; |
438 | } | 448 | } |
439 | 449 | ||
440 | 450 | ||
@@ -442,33 +452,33 @@ uint32_t ftl_has_devinfo(void) | |||
442 | This is based on some cryptic disassembly and not fully understood yet. */ | 452 | This is based on some cryptic disassembly and not fully understood yet. */ |
443 | uint32_t ftl_load_bbt(uint32_t bank, uint8_t* bbt) | 453 | uint32_t ftl_load_bbt(uint32_t bank, uint8_t* bbt) |
444 | { | 454 | { |
445 | uint32_t i, j; | 455 | uint32_t i, j; |
446 | uint32_t pagebase, page = ftl_find_devinfo(bank), page2; | 456 | uint32_t pagebase, page = ftl_find_devinfo(bank), page2; |
447 | uint32_t unk1, unk2, unk3; | 457 | uint32_t unk1, unk2, unk3; |
448 | if (page == 0) return 1; | 458 | if (page == 0) return 1; |
449 | pagebase = page & ~((*ftl_nand_type).pagesperblock - 1); | 459 | pagebase = page & ~((*ftl_nand_type).pagesperblock - 1); |
450 | if ((nand_read_page(bank, page, ftl_buffer, | 460 | if ((nand_read_page(bank, page, ftl_buffer, |
451 | (uint32_t*)0, 1, 0) & 0x11F) != 0) return 1; | 461 | (uint32_t*)0, 1, 0) & 0x11F) != 0) return 1; |
452 | if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1; | 462 | if (memcmp(&ftl_buffer[0x18], "BBT", 4) != 0) return 1; |
453 | unk1 = ((uint16_t*)ftl_buffer)[0x10]; | 463 | unk1 = ((uint16_t*)ftl_buffer)[0x10]; |
454 | unk2 = ((uint16_t*)ftl_buffer)[0x11]; | 464 | unk2 = ((uint16_t*)ftl_buffer)[0x11]; |
455 | unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 10] | 465 | unk3 = ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 10] |
456 | + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 11]; | 466 | + ((uint16_t*)ftl_buffer)[((uint32_t*)ftl_buffer)[4] * 0xC + 11]; |
457 | for (i = 0; i < unk1; i++) | 467 | for (i = 0; i < unk1; i++) |
458 | { | 468 | { |
459 | for (j = 0; ; j++) | 469 | for (j = 0; ; j++) |
460 | { | 470 | { |
461 | page2 = unk2 + i + unk3 * j; | 471 | page2 = unk2 + i + unk3 * j; |
462 | if (page2 >= (uint32_t)((*ftl_nand_type).pagesperblock - 8)) | 472 | if (page2 >= (uint32_t)((*ftl_nand_type).pagesperblock - 8)) |
463 | break; | 473 | break; |
464 | if ((nand_read_page(bank, pagebase + page2, ftl_buffer, | 474 | if ((nand_read_page(bank, pagebase + page2, ftl_buffer, |
465 | (void*)0, 1, 0) & 0x11F) == 0) | 475 | (void*)0, 1, 0) & 0x11F) == 0) |
466 | { | 476 | { |
467 | memcpy(bbt, ftl_buffer, 0x410); | 477 | memcpy(bbt, ftl_buffer, 0x410); |
468 | return 0; | 478 | return 0; |
469 | } | 479 | } |
470 | } | 480 | } |
471 | } | 481 | } |
472 | return 1; | 482 | return 1; |
473 | } | 483 | } |
474 | 484 | ||
@@ -929,7 +939,7 @@ uint32_t ftl_vfl_open(void) | |||
929 | { | 939 | { |
930 | if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx], | 940 | if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx], |
931 | k, ftl_buffer, | 941 | k, ftl_buffer, |
932 | &ftl_sparebuffer) != 0) | 942 | &ftl_sparebuffer) != 0) |
933 | break; | 943 | break; |
934 | last = k; | 944 | last = k; |
935 | } | 945 | } |
@@ -1306,19 +1316,18 @@ uint32_t ftl_next_ctrl_pool_page(void) | |||
1306 | uint32_t ftl_copy_page(uint32_t source, uint32_t destination, | 1316 | uint32_t ftl_copy_page(uint32_t source, uint32_t destination, |
1307 | uint32_t lpn, uint32_t type) | 1317 | uint32_t lpn, uint32_t type) |
1308 | { | 1318 | { |
1309 | uint8_t buffer[0x800]; | ||
1310 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; | 1319 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; |
1311 | uint32_t rc = ftl_vfl_read(source, buffer, | 1320 | uint32_t rc = ftl_vfl_read(source, ftl_copybuffer, |
1312 | &ftl_sparebuffer, 1, 1) & 0x11F; | 1321 | &ftl_sparebuffer, 1, 1) & 0x11F; |
1313 | memset(&ftl_sparebuffer, 0xFF, 0x40); | 1322 | memset(&ftl_sparebuffer, 0xFF, 0x40); |
1314 | ftl_sparebuffer.user.lpn = lpn; | 1323 | ftl_sparebuffer.user.lpn = lpn; |
1315 | ftl_sparebuffer.user.usn = ++ftl_cxt.nextblockusn; | 1324 | ftl_sparebuffer.user.usn = ++ftl_cxt.nextblockusn; |
1316 | ftl_sparebuffer.user.type = 0x40; | 1325 | ftl_sparebuffer.user.type = 0x40; |
1317 | if ((rc & 2) != 0) memset(buffer, 0, 0x800); | 1326 | if ((rc & 2) != 0) memset(ftl_copybuffer, 0, 0x800); |
1318 | else if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; | 1327 | else if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; |
1319 | if (type == 1 && destination % ppb == ppb - 1) | 1328 | if (type == 1 && destination % ppb == ppb - 1) |
1320 | ftl_sparebuffer.user.type = 0x41; | 1329 | ftl_sparebuffer.user.type = 0x41; |
1321 | return ftl_vfl_write(destination, buffer, &ftl_sparebuffer); | 1330 | return ftl_vfl_write(destination, ftl_copybuffer, &ftl_sparebuffer); |
1322 | } | 1331 | } |
1323 | #endif | 1332 | #endif |
1324 | 1333 | ||
@@ -1330,11 +1339,10 @@ uint32_t ftl_copy_block(uint32_t source, uint32_t destination) | |||
1330 | uint32_t i; | 1339 | uint32_t i; |
1331 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; | 1340 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; |
1332 | uint32_t error = 0; | 1341 | uint32_t error = 0; |
1333 | uint8_t buffer[0x800]; | ||
1334 | ftl_cxt.nextblockusn++; | 1342 | ftl_cxt.nextblockusn++; |
1335 | for (i = 0; i < ppb; i++) | 1343 | for (i = 0; i < ppb; i++) |
1336 | { | 1344 | { |
1337 | uint32_t rc = ftl_read(source * ppb + i, 1, buffer); | 1345 | uint32_t rc = ftl_read(source * ppb + i, 1, ftl_copybuffer); |
1338 | memset(&ftl_sparebuffer, 0xFF, 0x40); | 1346 | memset(&ftl_sparebuffer, 0xFF, 0x40); |
1339 | ftl_sparebuffer.user.lpn = source * ppb + i; | 1347 | ftl_sparebuffer.user.lpn = source * ppb + i; |
1340 | ftl_sparebuffer.user.usn = ftl_cxt.nextblockusn; | 1348 | ftl_sparebuffer.user.usn = ftl_cxt.nextblockusn; |
@@ -1342,7 +1350,7 @@ uint32_t ftl_copy_block(uint32_t source, uint32_t destination) | |||
1342 | if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; | 1350 | if (rc != 0) ftl_sparebuffer.user.eccmark = 0x55; |
1343 | if (i == ppb - 1) ftl_sparebuffer.user.type = 0x41; | 1351 | if (i == ppb - 1) ftl_sparebuffer.user.type = 0x41; |
1344 | if (ftl_vfl_write(destination * ppb + i, | 1352 | if (ftl_vfl_write(destination * ppb + i, |
1345 | buffer, &ftl_sparebuffer) != 0) | 1353 | ftl_copybuffer, &ftl_sparebuffer) != 0) |
1346 | { | 1354 | { |
1347 | error = 1; | 1355 | error = 1; |
1348 | break; | 1356 | break; |
@@ -1383,7 +1391,6 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry) | |||
1383 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; | 1391 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; |
1384 | uint32_t error; | 1392 | uint32_t error; |
1385 | struct ftl_log_type backup; | 1393 | struct ftl_log_type backup; |
1386 | uint16_t backup_pageoffsets[0x200]; | ||
1387 | if ((*entry).pagescurrent == 0) | 1394 | if ((*entry).pagescurrent == 0) |
1388 | { | 1395 | { |
1389 | ftl_release_pool_block((*entry).scatteredvblock); | 1396 | ftl_release_pool_block((*entry).scatteredvblock); |
@@ -1391,7 +1398,7 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry) | |||
1391 | return 0; | 1398 | return 0; |
1392 | } | 1399 | } |
1393 | backup = *entry; | 1400 | backup = *entry; |
1394 | memcpy(backup_pageoffsets, (*entry).pageoffsets, 0x400); | 1401 | memcpy(ftl_offsets_backup, (*entry).pageoffsets, 0x400); |
1395 | for (i = 0; i < 4; i++) | 1402 | for (i = 0; i < 4; i++) |
1396 | { | 1403 | { |
1397 | uint32_t block = ftl_allocate_pool_block(); | 1404 | uint32_t block = ftl_allocate_pool_block(); |
@@ -1425,7 +1432,7 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry) | |||
1425 | break; | 1432 | break; |
1426 | } | 1433 | } |
1427 | *entry = backup; | 1434 | *entry = backup; |
1428 | memcpy((*entry).pageoffsets, backup_pageoffsets, 0x400); | 1435 | memcpy((*entry).pageoffsets, ftl_offsets_backup, 0x400); |
1429 | } | 1436 | } |
1430 | return error; | 1437 | return error; |
1431 | } | 1438 | } |
@@ -1850,7 +1857,7 @@ uint32_t ftl_init(void) | |||
1850 | { | 1857 | { |
1851 | mutex_init(&ftl_mtx); | 1858 | mutex_init(&ftl_mtx); |
1852 | uint32_t i; | 1859 | uint32_t i; |
1853 | uint32_t result = 0; | 1860 | uint32_t result = 0; |
1854 | uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip; | 1861 | uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip; |
1855 | if (nand_device_init() != 0) //return 1; | 1862 | if (nand_device_init() != 0) //return 1; |
1856 | panicf("FTL: Lowlevel NAND driver init failed!"); | 1863 | panicf("FTL: Lowlevel NAND driver init failed!"); |
@@ -1874,7 +1881,7 @@ uint32_t ftl_init(void) | |||
1874 | else if ((result & 2) != 2) blockwiped = 0; | 1881 | else if ((result & 2) != 2) blockwiped = 0; |
1875 | } | 1882 | } |
1876 | 1883 | ||
1877 | founddevinfo = ftl_has_devinfo(); | 1884 | founddevinfo = ftl_has_devinfo(); |
1878 | 1885 | ||
1879 | repaired = 0; | 1886 | repaired = 0; |
1880 | skip = 0; | 1887 | skip = 0; |
@@ -1904,7 +1911,7 @@ uint32_t ftl_init(void) | |||
1904 | (However there is curently no point in this, as iLoader would already | 1911 | (However there is curently no point in this, as iLoader would already |
1905 | fail if this would be the case.) | 1912 | fail if this would be the case.) |
1906 | 1913 | ||
1907 | nand_block_erase(0, 0); | 1914 | nand_block_erase(0, 0); |
1908 | */ | 1915 | */ |
1909 | 1916 | ||
1910 | 1917 | ||