| 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 |