Index: embios/trunk/init.c |
— | — | @@ -77,6 +77,11 @@ |
78 | 78 | static const char initthreadname[] INITCONST_ATTR = "Initialization thread";
|
79 | 79 | static uint32_t initstack[0x400] INITSTACK_ATTR;
|
80 | 80 | extern int _loadspaceend;
|
| 81 | +#ifdef HAVE_STORAGE
|
| 82 | +static const char storageinitthreadname[] INITCONST_ATTR = "Storage init thread";
|
| 83 | +static uint32_t storageinitstack[0x400] INITBSS_ATTR;
|
| 84 | +static struct wakeup storageinitwakeup;
|
| 85 | +#endif
|
81 | 86 | struct bootinfo_t bootinfo_src INITHEAD_ATTR =
|
82 | 87 | {
|
83 | 88 | .signature = "emBIboot",
|
— | — | @@ -168,6 +173,23 @@ |
169 | 174 | cputs(CONSOLE_BOOT, "Waiting for USB commands\n\n");
|
170 | 175 | }
|
171 | 176 |
|
| 177 | +#ifdef HAVE_STORAGE
|
| 178 | +void storageinitthread() INITCODE_ATTR;
|
| 179 | +void storageinitthread()
|
| 180 | +{
|
| 181 | + DEBUGF("Initializing storage drivers...");
|
| 182 | + storage_init();
|
| 183 | + DEBUGF("Initializing storage subsystem...");
|
| 184 | + disk_init_subsystem();
|
| 185 | + DEBUGF("Reading partition tables...");
|
| 186 | + disk_init();
|
| 187 | + DEBUGF("Mounting partitions...");
|
| 188 | + disk_mount_all();
|
| 189 | + DEBUGF("Storage init finished.");
|
| 190 | + wakeup_signal(&storageinitwakeup);
|
| 191 | +}
|
| 192 | +#endif
|
| 193 | +
|
172 | 194 | void initthread() INITCODE_ATTR;
|
173 | 195 | void initthread()
|
174 | 196 | {
|
— | — | @@ -175,10 +197,15 @@ |
176 | 198 | i2c_init();
|
177 | 199 | #endif
|
178 | 200 | power_init();
|
| 201 | + cputs(CONSOLE_BOOT, welcomestring);
|
| 202 | +#ifdef HAVE_STORAGE
|
| 203 | + wakeup_init(&storageinitwakeup);
|
| 204 | + int storagethread = thread_create(storageinitthreadname, storageinitthread, storageinitstack,
|
| 205 | + sizeof(storageinitstack), USER_THREAD, 127, true);
|
| 206 | +#endif
|
179 | 207 | #ifdef HAVE_USB
|
180 | 208 | usb_init();
|
181 | 209 | #endif
|
182 | | - cputs(CONSOLE_BOOT, welcomestring);
|
183 | 210 | #ifdef HAVE_BACKLIGHT
|
184 | 211 | backlight_init();
|
185 | 212 | #endif
|
— | — | @@ -185,19 +212,25 @@ |
186 | 213 | #ifdef HAVE_BUTTON
|
187 | 214 | button_init();
|
188 | 215 | #endif
|
189 | | -#ifdef HAVE_STORAGE
|
190 | | - DEBUGF("Initializing storage drivers...");
|
191 | | - storage_init();
|
192 | | - DEBUGF("Initializing storage subsystem...");
|
193 | | - disk_init_subsystem();
|
194 | | - DEBUGF("Reading partition tables...");
|
195 | | - disk_init();
|
196 | | - DEBUGF("Mounting partitions...");
|
197 | | - disk_mount_all();
|
198 | | -#endif
|
199 | 216 | #ifdef HAVE_TARGETINIT_LATE
|
200 | 217 | targetinit_late();
|
201 | 218 | #endif
|
| 219 | +#ifdef HAVE_STORAGE
|
| 220 | + while (true)
|
| 221 | + {
|
| 222 | + if (wakeup_wait(&storageinitwakeup, 100000) == THREAD_OK) break;
|
| 223 | + enum thread_state state = thread_get_state(storagethread);
|
| 224 | + if (state == THREAD_DEFUNCT || state == THREAD_DEFUNCT_ACK)
|
| 225 | + {
|
| 226 | + if (wakeup_wait(&storageinitwakeup, 0) == THREAD_OK) break;
|
| 227 | + thread_terminate(storagethread);
|
| 228 | + break;
|
| 229 | + }
|
| 230 | + }
|
| 231 | +#endif
|
| 232 | +#ifdef HAVE_TARGETINIT_VERYLATE
|
| 233 | + targetinit_verylate();
|
| 234 | +#endif
|
202 | 235 | DEBUGF("Finished initialisation sequence");
|
203 | 236 | boot();
|
204 | 237 | }
|
Index: embios/trunk/panic.c |
— | — | @@ -37,19 +37,18 @@ |
38 | 38 |
|
39 | 39 | void handle_panic(enum panic_severity severity)
|
40 | 40 | {
|
41 | | - int i;
|
42 | | - if (severity == PANIC_KILLTHREAD) thread_exit();
|
43 | | - else
|
| 41 | + uint32_t mode = enter_critical_section();
|
| 42 | + if (severity == PANIC_KILLUSERTHREADS)
|
44 | 43 | {
|
45 | | - uint32_t mode = enter_critical_section();
|
| 44 | + int i;
|
46 | 45 | for (i = 0; i < MAX_THREADS; i++)
|
47 | 46 | if (scheduler_threads[i].type == USER_THREAD)
|
48 | 47 | scheduler_threads[i].state = THREAD_SUSPENDED;
|
49 | | - current_thread->state = THREAD_DEFUNCT_ACK;
|
50 | | - current_thread->block_type = THREAD_DEFUNCT_PANIC;
|
51 | | - leave_critical_section(mode);
|
52 | | - context_switch();
|
53 | 48 | }
|
| 49 | + current_thread->state = THREAD_DEFUNCT_ACK;
|
| 50 | + current_thread->block_type = THREAD_DEFUNCT_PANIC;
|
| 51 | + leave_critical_section(mode);
|
| 52 | + context_switch();
|
54 | 53 | }
|
55 | 54 |
|
56 | 55 | void panic(enum panic_severity severity, const char* string)
|
Index: embios/trunk/target/ipodnano2g/nand.c |
— | — | @@ -346,7 +346,7 @@ |
347 | 347 | for (i = 0; i < 4; i++)
|
348 | 348 | if (nand_type[i] >= 0)
|
349 | 349 | if (nand_reset(i))
|
350 | | - panicf(PANIC_FATAL, "nand_power_up: nand_reset(bank=%d) failed.", (unsigned int)i);
|
| 350 | + panicf(PANIC_KILLTHREAD, "nand_power_up: nand_reset(bank=%d) failed.", (unsigned int)i);
|
351 | 351 | nand_powered = 1;
|
352 | 352 | nand_last_activity_value = USEC_TIMER;
|
353 | 353 | mutex_unlock(&nand_mtx);
|
— | — | @@ -382,11 +382,11 @@ |
383 | 383 | uint8_t* spare = nand_spare;
|
384 | 384 | if (sparebuffer) spare = (uint8_t*)sparebuffer;
|
385 | 385 | if ((uint32_t)databuffer & (CACHEALIGN_SIZE - 1))
|
386 | | - panicf(PANIC_KILLUSERTHREADS,
|
| 386 | + panicf(PANIC_KILLTHREAD,
|
387 | 387 | "nand_read_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
|
388 | 388 | (unsigned int)databuffer, bank, page);
|
389 | 389 | if ((uint32_t)sparebuffer & (CACHEALIGN_SIZE - 1))
|
390 | | - panicf(PANIC_KILLUSERTHREADS,
|
| 390 | + panicf(PANIC_KILLTHREAD,
|
391 | 391 | "nand_read_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
|
392 | 392 | (unsigned int)sparebuffer, bank, page);
|
393 | 393 | mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
|
— | — | @@ -467,11 +467,11 @@ |
468 | 468 | uint8_t* spare = nand_spare;
|
469 | 469 | if (sparebuffer) spare = (uint8_t*)sparebuffer;
|
470 | 470 | if ((uint32_t)databuffer & 0xf)
|
471 | | - panicf(PANIC_KILLUSERTHREADS,
|
| 471 | + panicf(PANIC_KILLTHREAD,
|
472 | 472 | "nand_write_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
|
473 | 473 | (unsigned int)databuffer, bank, page);
|
474 | 474 | if ((uint32_t)sparebuffer & 0xf)
|
475 | | - panicf(PANIC_KILLUSERTHREADS,
|
| 475 | + panicf(PANIC_KILLTHREAD,
|
476 | 476 | "nand_write_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
|
477 | 477 | (unsigned int)sparebuffer, bank, page);
|
478 | 478 | mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
|
Index: embios/trunk/target/ipodnano2g/ftl.c |
— | — | @@ -615,7 +615,8 @@ |
616 | 616 | ftl_vfl_cxt[bank].nextcxtpage = 0;
|
617 | 617 | if (ftl_vfl_store_cxt(bank) == 0) return 0;
|
618 | 618 | }
|
619 | | - panicf(PANIC_FATAL, "VFL: Failed to commit VFL CXT!");
|
| 619 | + ftl_initialized = false;
|
| 620 | + panicf(PANIC_KILLTHREAD, "VFL: Failed to commit VFL CXT!");
|
620 | 621 | return 1;
|
621 | 622 | }
|
622 | 623 | #endif
|
— | — | @@ -729,7 +730,8 @@ |
730 | 731 | static void ftl_vfl_schedule_block_for_remap(uint32_t bank, uint32_t block)
|
731 | 732 | {
|
732 | 733 | if (ftl_vfl_check_remap_scheduled(bank, block) == 1) return;
|
733 | | - panicf(PANIC_FATAL, "FTL: Scheduling bank %u block %u for remap!",
|
| 734 | + ftl_initialized = false;
|
| 735 | + panicf(PANIC_KILLTHREAD, "FTL: Scheduling bank %u block %u for remap!",
|
734 | 736 | (unsigned)bank, (unsigned)block);
|
735 | 737 | if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused)
|
736 | 738 | return;
|
— | — | @@ -816,7 +818,8 @@ |
817 | 819 | {
|
818 | 820 | uint32_t i;
|
819 | 821 | uint32_t newblock = 0, newidx;
|
820 | | - panicf(PANIC_FATAL, "FTL: Remapping bank %u block %u!",
|
| 822 | + ftl_initialized = false;
|
| 823 | + panicf(PANIC_KILLTHREAD, "FTL: Remapping bank %u block %u!",
|
821 | 824 | (unsigned)bank, (unsigned)block);
|
822 | 825 | if (bank >= ftl_banks || block >= ftl_nand_type->blocks) return 0;
|
823 | 826 | for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++)
|
— | — | @@ -1009,7 +1012,8 @@ |
1010 | 1013 | if (nand_read_page(bank[ftl_banks], physpage[ftl_banks],
|
1011 | 1014 | ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
|
1012 | 1015 | {
|
1013 | | - panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
|
| 1016 | + ftl_initialized = false;
|
| 1017 | + panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
|
1014 | 1018 | (unsigned)(vpage + i - ftl_banks),
|
1015 | 1019 | (unsigned)bank[ftl_banks],
|
1016 | 1020 | (unsigned)physpage[ftl_banks]);
|
— | — | @@ -1021,7 +1025,8 @@ |
1022 | 1026 | if (nand_read_page(bank[0], physpage[0], ftl_buffer,
|
1023 | 1027 | &ftl_sparebuffer[0], 1, 1) & 0x11F)
|
1024 | 1028 | {
|
1025 | | - panicf(PANIC_FATAL, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
|
| 1029 | + ftl_initialized = false;
|
| 1030 | + panicf(PANIC_KILLTHREAD, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
|
1026 | 1031 | (unsigned)(vpage + i), (unsigned)bank[0], (unsigned)physpage[0]);
|
1027 | 1032 | ftl_vfl_log_trouble(bank[0], block[0]);
|
1028 | 1033 | }
|
— | — | @@ -1032,7 +1037,8 @@ |
1033 | 1038 | if (nand_read_page(bank[i - 1], physpage[i - 1],
|
1034 | 1039 | ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
|
1035 | 1040 | {
|
1036 | | - panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
|
| 1041 | + ftl_initialized = false;
|
| 1042 | + panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
|
1037 | 1043 | (unsigned)(vpage + count - i),
|
1038 | 1044 | (unsigned)bank[i - 1], (unsigned)physpage[i - 1]);
|
1039 | 1045 | ftl_vfl_log_trouble(bank[i - 1], block[i - 1]);
|
— | — | @@ -1113,9 +1119,12 @@ |
1114 | 1120 | if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx],
|
1115 | 1121 | last, ftl_buffer,
|
1116 | 1122 | &ftl_sparebuffer[0]) != 0)
|
1117 | | - panicf(PANIC_FATAL, "FTL: Re-reading VFL CXT block "
|
1118 | | - "on bank %u failed!?", (unsigned)i);
|
| 1123 | + {
|
| 1124 | + ftl_initialized = false;
|
| 1125 | + panicf(PANIC_KILLTHREAD, "FTL: Re-reading VFL CXT block "
|
| 1126 | + "on bank %u failed!?", (unsigned)i);
|
1119 | 1127 | //return 1;
|
| 1128 | + }
|
1120 | 1129 | memcpy(&ftl_vfl_cxt[i], ftl_buffer, 0x800);
|
1121 | 1130 | if (ftl_vfl_verify_checksum(i) != 0) return 1;
|
1122 | 1131 | #ifndef FTL_READONLY
|
— | — | @@ -1329,6 +1338,11 @@ |
1330 | 1339 | if (count == 0) return 0;
|
1331 | 1340 |
|
1332 | 1341 | mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
|
| 1342 | + if (!ftl_initialized)
|
| 1343 | + {
|
| 1344 | + mutex_unlock(&ftl_mtx);
|
| 1345 | + return -1;
|
| 1346 | + }
|
1333 | 1347 |
|
1334 | 1348 | for (i = 0; i < count; i++)
|
1335 | 1349 | {
|
— | — | @@ -1422,7 +1436,8 @@ |
1423 | 1437 | }
|
1424 | 1438 | if (rc != 0)
|
1425 | 1439 | {
|
1426 | | - panicf(PANIC_FATAL, "FTL: Block erase failed on bank %u block %u",
|
| 1440 | + ftl_initialized = false;
|
| 1441 | + panicf(PANIC_KILLTHREAD, "FTL: Block erase failed on bank %u block %u",
|
1427 | 1442 | (unsigned)i, (unsigned)block);
|
1428 | 1443 | if (pblock != block)
|
1429 | 1444 | {
|
— | — | @@ -1471,7 +1486,11 @@ |
1472 | 1487 | bestidx = idx;
|
1473 | 1488 | }
|
1474 | 1489 | }
|
1475 | | - if (bestidx == 0xFFFFFFFF) panicf(PANIC_FATAL, "FTL: Out of pool blocks!");
|
| 1490 | + if (bestidx == 0xFFFFFFFF0)
|
| 1491 | + {
|
| 1492 | + ftl_initialized = false;
|
| 1493 | + panicf(PANIC_KILLTHREAD, "FTL: Out of pool blocks!");
|
| 1494 | + }
|
1476 | 1495 | block = ftl_cxt.blockpool[bestidx];
|
1477 | 1496 | if (bestidx != ftl_cxt.nextfreeidx)
|
1478 | 1497 | {
|
— | — | @@ -1479,7 +1498,10 @@ |
1480 | 1499 | ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block;
|
1481 | 1500 | }
|
1482 | 1501 | if (block > (uint32_t)ftl_nand_type->userblocks + 0x17)
|
1483 | | - panicf(PANIC_FATAL, "FTL: Bad block number in pool: %u", (unsigned)block);
|
| 1502 | + {
|
| 1503 | + ftl_initialized = false;
|
| 1504 | + panicf(PANIC_KILLTHREAD, "FTL: Bad block number in pool: %u", (unsigned)block);
|
| 1505 | + }
|
1484 | 1506 | if (ftl_erase_block(block) != 0) return 0xFFFFFFFF;
|
1485 | 1507 | if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0;
|
1486 | 1508 | ftl_cxt.freecount--;
|
— | — | @@ -1493,7 +1515,10 @@ |
1494 | 1516 | static void ftl_release_pool_block(uint32_t block)
|
1495 | 1517 | {
|
1496 | 1518 | if (block >= (uint32_t)ftl_nand_type->userblocks + 0x17)
|
1497 | | - panicf(PANIC_FATAL, "FTL: Tried to release block %u", (unsigned)block);
|
| 1519 | + {
|
| 1520 | + ftl_initialized = false;
|
| 1521 | + panicf(PANIC_KILLTHREAD, "FTL: Tried to release block %u", (unsigned)block);
|
| 1522 | + }
|
1498 | 1523 | uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++;
|
1499 | 1524 | if (idx >= 0x14) idx -= 0x14;
|
1500 | 1525 | ftl_cxt.blockpool[idx] = block;
|
— | — | @@ -1863,7 +1888,11 @@ |
1864 | 1889 |
|
1865 | 1890 | if (entry == NULL)
|
1866 | 1891 | {
|
1867 | | - if (ftl_cxt.freecount < 3) panicf(PANIC_FATAL, "FTL: Detected a pool block leak!");
|
| 1892 | + if (ftl_cxt.freecount < 3)
|
| 1893 | + {
|
| 1894 | + ftl_initialized = false;
|
| 1895 | + panicf(PANIC_KILLTHREAD, "FTL: Detected a pool block leak!");
|
| 1896 | + }
|
1868 | 1897 | else if (ftl_cxt.freecount == 3)
|
1869 | 1898 | if (ftl_remove_scattered_block(NULL) != 0)
|
1870 | 1899 | return NULL;
|
— | — | @@ -1994,6 +2023,11 @@ |
1995 | 2024 | if (count == 0) return 0;
|
1996 | 2025 |
|
1997 | 2026 | mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
|
| 2027 | + if (!ftl_initialized)
|
| 2028 | + {
|
| 2029 | + mutex_unlock(&ftl_mtx);
|
| 2030 | + return -1;
|
| 2031 | + }
|
1998 | 2032 |
|
1999 | 2033 | if (ftl_cxt.clean_flag == 1)
|
2000 | 2034 | {
|
— | — | @@ -2125,8 +2159,12 @@ |
2126 | 2160 | }
|
2127 | 2161 | i += cnt;
|
2128 | 2162 | }
|
2129 | | - else panicf(PANIC_FATAL, "FTL: Write error: %u %u %u!",
|
2130 | | - (unsigned)sector, (unsigned)count, (unsigned)i);
|
| 2163 | + else
|
| 2164 | + {
|
| 2165 | + ftl_initialized = false;
|
| 2166 | + panicf(PANIC_KILLTHREAD, "FTL: Write error: %u %u %u!",
|
| 2167 | + (unsigned)sector, (unsigned)count, (unsigned)i);
|
| 2168 | + }
|
2131 | 2169 | }
|
2132 | 2170 | if (logentry->pagesused == ppb) ftl_remove_scattered_block(logentry);
|
2133 | 2171 | }
|
— | — | @@ -2166,6 +2204,11 @@ |
2167 | 2205 | if (ftl_cxt.clean_flag == 1) return 0;
|
2168 | 2206 |
|
2169 | 2207 | mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
|
| 2208 | + if (!ftl_initialized)
|
| 2209 | + {
|
| 2210 | + mutex_unlock(&ftl_mtx);
|
| 2211 | + return -1;
|
| 2212 | + }
|
2170 | 2213 |
|
2171 | 2214 | #ifdef FTL_TRACE
|
2172 | 2215 | DEBUGF("FTL: Syncing");
|
— | — | @@ -2543,7 +2586,7 @@ |
2544 | 2587 | uint32_t i;
|
2545 | 2588 | int rc;
|
2546 | 2589 | if ((rc = nand_device_init()) != 0)
|
2547 | | - panicf(PANIC_FATAL, "FTL: Lowlevel NAND driver init failed: %d", rc);
|
| 2590 | + panicf(PANIC_KILLTHREAD, "FTL: Lowlevel NAND driver init failed: %d", rc);
|
2548 | 2591 | ftl_banks = 0;
|
2549 | 2592 | for (i = 0; i < 4; i++)
|
2550 | 2593 | if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
|
— | — | @@ -2561,7 +2604,7 @@ |
2562 | 2605 | ftl_initialized = true;
|
2563 | 2606 | return 0;
|
2564 | 2607 | }
|
2565 | | - cputs(CONSOLE_BOOT, "The FTL seems to be damaged. Forcing check.\n");
|
| 2608 | + cputs(CONSOLE_BOOT, "The FTL seems to be unclean. Forcing check.\n");
|
2566 | 2609 | if (ftl_repair() != 0)
|
2567 | 2610 | cputs(CONSOLE_BOOT, "FTL recovery failed. Use disk mode to recover.\n");
|
2568 | 2611 | else
|
Index: embios/trunk/thread.c |
— | — | @@ -453,6 +453,11 @@ |
454 | 454 | return ret;
|
455 | 455 | }
|
456 | 456 |
|
| 457 | +enum thread_state thread_get_state(int thread)
|
| 458 | +{
|
| 459 | + return scheduler_threads[thread].state;
|
| 460 | +}
|
| 461 | +
|
457 | 462 | void thread_exit()
|
458 | 463 | {
|
459 | 464 | thread_terminate(-1);
|
Index: embios/trunk/thread.h |
— | — | @@ -115,6 +115,7 @@ |
116 | 116 | int thread_suspend(int thread);
|
117 | 117 | int thread_resume(int thread);
|
118 | 118 | int thread_terminate(int thread);
|
| 119 | +enum thread_state thread_get_state(int thread);
|
119 | 120 | void thread_exit();
|
120 | 121 | void mutex_init(struct mutex* obj) ICODE_ATTR;
|
121 | 122 | int mutex_lock(struct mutex* obj, int timeout) ICODE_ATTR;
|