Index: emcore/trunk/target/ipodclassic/storage_ata-target.h |
— | — | @@ -31,7 +31,7 @@ |
32 | 32 | extern uint64_t ata_total_sectors;
|
33 | 33 |
|
34 | 34 | #ifdef ATA_HAVE_BBT
|
35 | | -extern uint16_t ata_bbt[ATA_BBT_PAGES][0x20];
|
| 35 | +extern uint16_t (*ata_bbt)[0x20];
|
36 | 36 | extern uint64_t ata_virtual_sectors;
|
37 | 37 |
|
38 | 38 | int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write);
|
Index: emcore/trunk/target/ipodclassic/storage_ata.c |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 |
|
44 | 44 | #ifdef ATA_HAVE_BBT
|
45 | 45 | #include "panic.h"
|
46 | | -uint16_t ata_bbt[ATA_BBT_PAGES][0x20];
|
| 46 | +uint16_t (*ata_bbt)[0x20];
|
47 | 47 | uint64_t ata_virtual_sectors;
|
48 | 48 | uint32_t ata_last_offset;
|
49 | 49 | uint64_t ata_last_phys;
|
— | — | @@ -337,49 +337,51 @@ |
338 | 338 | {
|
339 | 339 | #ifdef ATA_HAVE_BBT
|
340 | 340 | if (sector + count > ata_virtual_sectors) RET_ERR(0);
|
341 | | - while (count)
|
342 | | - {
|
343 | | - uint32_t offset;
|
344 | | - uint32_t l0idx = sector >> 15;
|
345 | | - uint32_t l0offs = sector & 0x7fff;
|
346 | | - uint32_t cnt = MIN(count, 0x8000 - l0offs);
|
347 | | - uint32_t l0data = ata_bbt[0][l0idx << 1];
|
348 | | - uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
|
349 | | - if (l0data < 0x8000) offset = l0data + base;
|
350 | | - else
|
| 341 | + if (ata_bbt)
|
| 342 | + while (count)
|
351 | 343 | {
|
352 | | - uint32_t l1idx = (sector >> 10) & 0x1f;
|
353 | | - uint32_t l1offs = sector & 0x3ff;
|
354 | | - cnt = MIN(count, 0x400 - l1offs);
|
355 | | - uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
|
356 | | - if (l1data < 0x8000) offset = l1data + base;
|
| 344 | + uint32_t offset;
|
| 345 | + uint32_t l0idx = sector >> 15;
|
| 346 | + uint32_t l0offs = sector & 0x7fff;
|
| 347 | + uint32_t cnt = MIN(count, 0x8000 - l0offs);
|
| 348 | + uint32_t l0data = ata_bbt[0][l0idx << 1];
|
| 349 | + uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
|
| 350 | + if (l0data < 0x8000) offset = l0data + base;
|
357 | 351 | else
|
358 | 352 | {
|
359 | | - uint32_t l2idx = (sector >> 5) & 0x1f;
|
360 | | - uint32_t l2offs = sector & 0x1f;
|
361 | | - cnt = MIN(count, 0x20 - l2offs);
|
362 | | - uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
|
363 | | - if (l2data < 0x8000) offset = l2data + base;
|
| 353 | + uint32_t l1idx = (sector >> 10) & 0x1f;
|
| 354 | + uint32_t l1offs = sector & 0x3ff;
|
| 355 | + cnt = MIN(count, 0x400 - l1offs);
|
| 356 | + uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
|
| 357 | + if (l1data < 0x8000) offset = l1data + base;
|
364 | 358 | else
|
365 | 359 | {
|
366 | | - uint32_t l3idx = sector & 0x1f;
|
367 | | - uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
|
368 | | - for (cnt = 1; cnt < count && l3idx + cnt < 0x20; cnt++)
|
369 | | - if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != l3data)
|
370 | | - break;
|
371 | | - offset = l3data + base;
|
| 360 | + uint32_t l2idx = (sector >> 5) & 0x1f;
|
| 361 | + uint32_t l2offs = sector & 0x1f;
|
| 362 | + cnt = MIN(count, 0x20 - l2offs);
|
| 363 | + uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
|
| 364 | + if (l2data < 0x8000) offset = l2data + base;
|
| 365 | + else
|
| 366 | + {
|
| 367 | + uint32_t l3idx = sector & 0x1f;
|
| 368 | + uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
|
| 369 | + for (cnt = 1; cnt < count && l3idx + cnt < 0x20; cnt++)
|
| 370 | + if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != l3data)
|
| 371 | + break;
|
| 372 | + offset = l3data + base;
|
| 373 | + }
|
372 | 374 | }
|
373 | 375 | }
|
| 376 | + uint64_t phys = sector + offset;
|
| 377 | + if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
|
| 378 | + ata_last_offset = offset;
|
| 379 | + ata_last_phys = phys + cnt;
|
| 380 | + PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
|
| 381 | + buffer += cnt * SECTOR_SIZE;
|
| 382 | + sector += cnt;
|
| 383 | + count -= cnt;
|
374 | 384 | }
|
375 | | - uint64_t phys = sector + offset;
|
376 | | - if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
|
377 | | - ata_last_offset = offset;
|
378 | | - ata_last_phys = phys + cnt;
|
379 | | - PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
|
380 | | - buffer += cnt * SECTOR_SIZE;
|
381 | | - sector += cnt;
|
382 | | - count -= cnt;
|
383 | | - }
|
| 385 | + else PASS_RC(ata_rw_sectors_internal(sector, count, buffer, write), 0, 0);
|
384 | 386 | return 0;
|
385 | 387 | }
|
386 | 388 |
|
— | — | @@ -529,28 +531,31 @@ |
530 | 532 | ata_total_sectors = 0;
|
531 | 533 | #ifdef ATA_HAVE_BBT
|
532 | 534 | mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
|
533 | | - memset(ata_bbt, 0, sizeof(ata_bbt));
|
| 535 | + ata_bbt = NULL;
|
534 | 536 | ata_power_up();
|
535 | | - uint32_t* buf = (uint32_t*)(ata_bbt[ARRAYLEN(ata_bbt) - 64]);
|
536 | | - ata_bbt_read_sectors(0, 1, buf);
|
537 | | - if (!memcmp(buf, "emBIbbth", 8))
|
| 537 | + uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
|
| 538 | + if (buf)
|
538 | 539 | {
|
539 | | - ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
|
540 | | - uint32_t count = buf[0x1ff];
|
541 | | - if (count > (ATA_BBT_PAGES >> 6))
|
542 | | - panicf(PANIC_KILLTHREAD, "ATA: BBT too big! (%d pages, limit: %d)\n", count << 6, ATA_BBT_PAGES);
|
543 | | - uint32_t i;
|
544 | | - uint32_t cnt;
|
545 | | - for (i = 0; i < count; i += cnt)
|
| 540 | + ata_bbt_read_sectors(0, 1, buf);
|
| 541 | + if (!memcmp(buf, "emBIbbth", 8))
|
546 | 542 | {
|
547 | | - uint32_t phys = buf[0x200 + i];
|
548 | | - for (cnt = 1; cnt < count; cnt++)
|
549 | | - if (buf[0x200 + i + cnt] != phys + cnt)
|
550 | | - break;
|
551 | | - ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
|
| 543 | + ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
|
| 544 | + uint32_t count = buf[0x1ff];
|
| 545 | + ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
|
| 546 | + uint32_t i;
|
| 547 | + uint32_t cnt;
|
| 548 | + for (i = 0; i < count; i += cnt)
|
| 549 | + {
|
| 550 | + uint32_t phys = buf[0x200 + i];
|
| 551 | + for (cnt = 1; cnt < count; cnt++)
|
| 552 | + if (buf[0x200 + i + cnt] != phys + cnt)
|
| 553 | + break;
|
| 554 | + ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
|
| 555 | + }
|
552 | 556 | }
|
| 557 | + else ata_virtual_sectors = ata_total_sectors;
|
| 558 | + free(buf);
|
553 | 559 | }
|
554 | | - else ata_virtual_sectors = ata_total_sectors;
|
555 | 560 | mutex_unlock(&ata_mutex);
|
556 | 561 | #endif
|
557 | 562 | thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
|
Index: emcore/trunk/target/ipodclassic/config.h |
— | — | @@ -38,7 +38,6 @@ |
39 | 39 |
|
40 | 40 |
|
41 | 41 | #define ATA_HAVE_BBT
|
42 | | -#define ATA_BBT_PAGES 2304
|
43 | 42 |
|
44 | 43 |
|
45 | 44 | #endif |
\ No newline at end of file |