diff options
author | Michael Sparmann <theseven@rockbox.org> | 2011-12-28 16:06:13 +0000 |
---|---|---|
committer | Michael Sparmann <theseven@rockbox.org> | 2011-12-28 16:06:13 +0000 |
commit | 4c12aa1f08b1a60c0280fba1c864719a9b24471e (patch) | |
tree | 47779d0f8ac8feeb6e0d073d5205eab1ac3f43d1 /firmware/target/arm | |
parent | a7a78b3b52923467cd3879ce2f5c9ff74662b8fa (diff) | |
download | rockbox-4c12aa1f08b1a60c0280fba1c864719a9b24471e.tar.gz rockbox-4c12aa1f08b1a60c0280fba1c864719a9b24471e.zip |
iPod Classic: HDD endianness change
This commit changes the default HDD endianness to the correct one,
but stays compatible with the old endianness.
If an MBR with the wrong endianness is detected, it will
automatically enable word swapping and issue a warning splash.
To permanently fix this you'll need to upgrade emCORE to at least r836.
This will wipe all data! A post-r836 build of emCORE will be
officially released during the next couple of days.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31455 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h | 5 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c | 36 |
2 files changed, 31 insertions, 10 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h b/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h index 50e591253e..6edc239e1b 100644 --- a/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h +++ b/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h | |||
@@ -64,11 +64,6 @@ | |||
64 | } | 64 | } |
65 | 65 | ||
66 | #define TIMEOUT_EXPIRED(a,b) TIME_AFTER(USEC_TIMER,a + b) | 66 | #define TIMEOUT_EXPIRED(a,b) TIME_AFTER(USEC_TIMER,a + b) |
67 | #define udelay(duration) \ | ||
68 | { \ | ||
69 | long timestamp = USEC_TIMER; \ | ||
70 | while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \ | ||
71 | } | ||
72 | 67 | ||
73 | 68 | ||
74 | #define MMC_CMD_GO_IDLE_STATE 0 | 69 | #define MMC_CMD_GO_IDLE_STATE 0 |
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c index 2952c36324..dbf0ce9dd4 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include "s5l8702.h" | 32 | #include "s5l8702.h" |
33 | #include "led.h" | 33 | #include "led.h" |
34 | #include "ata_idle_notify.h" | 34 | #include "ata_idle_notify.h" |
35 | #include "fat.h" | ||
36 | #include "splash.h" | ||
35 | 37 | ||
36 | 38 | ||
37 | #ifndef ATA_RETRIES | 39 | #ifndef ATA_RETRIES |
@@ -49,6 +51,7 @@ | |||
49 | static uint8_t ceata_taskfile[16] __attribute__((aligned(16))); | 51 | static uint8_t ceata_taskfile[16] __attribute__((aligned(16))); |
50 | static uint16_t ata_identify_data[0x100] __attribute__((aligned(16))); | 52 | static uint16_t ata_identify_data[0x100] __attribute__((aligned(16))); |
51 | static bool ceata; | 53 | static bool ceata; |
54 | static bool ata_swap; | ||
52 | static bool ata_lba48; | 55 | static bool ata_lba48; |
53 | static bool ata_dma; | 56 | static bool ata_dma; |
54 | static uint64_t ata_total_sectors; | 57 | static uint64_t ata_total_sectors; |
@@ -512,15 +515,14 @@ static int ata_identify(uint16_t* buf) | |||
512 | } | 515 | } |
513 | else | 516 | else |
514 | { | 517 | { |
518 | uint32_t old = ATA_CFG; | ||
519 | ATA_CFG |= BIT(6); | ||
515 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); | 520 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); |
516 | ata_write_cbr(&ATA_PIO_DVR, 0); | 521 | ata_write_cbr(&ATA_PIO_DVR, 0); |
517 | ata_write_cbr(&ATA_PIO_CSD, 0xec); | 522 | ata_write_cbr(&ATA_PIO_CSD, 0xec); |
518 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); | 523 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); |
519 | for (i = 0; i < 0x100; i++) | 524 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); |
520 | { | 525 | ATA_CFG = old; |
521 | uint16_t word = ata_read_cbr(&ATA_PIO_DTR); | ||
522 | buf[i] = (word >> 8) | (word << 8); | ||
523 | } | ||
524 | } | 526 | } |
525 | return 0; | 527 | return 0; |
526 | } | 528 | } |
@@ -586,6 +588,7 @@ static int ata_power_up(void) | |||
586 | sleep(HZ / 5); | 588 | sleep(HZ / 5); |
587 | ATA_PIO_TIME = 0x191f7; | 589 | ATA_PIO_TIME = 0x191f7; |
588 | ATA_PIO_LHR = 0; | 590 | ATA_PIO_LHR = 0; |
591 | if (!ata_swap) ATA_CFG = BIT(6); | ||
589 | while (!(ATA_PIO_READY & BIT(1))) yield(); | 592 | while (!(ATA_PIO_READY & BIT(1))) yield(); |
590 | PASS_RC(ata_identify(ata_identify_data), 2, 0); | 593 | PASS_RC(ata_identify(ata_identify_data), 2, 0); |
591 | uint32_t piotime = 0x11f3; | 594 | uint32_t piotime = 0x11f3; |
@@ -1095,12 +1098,35 @@ int ata_init(void) | |||
1095 | PCON(9) = 0x44444444; | 1098 | PCON(9) = 0x44444444; |
1096 | PCON(10) = (PCON(10) & ~0xffff) | 0x4444; | 1099 | PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
1097 | } | 1100 | } |
1101 | ata_swap = false; | ||
1098 | ata_powered = false; | 1102 | ata_powered = false; |
1099 | ata_total_sectors = 0; | 1103 | ata_total_sectors = 0; |
1100 | ata_power_up(); | 1104 | ata_power_up(); |
1101 | #ifdef ATA_HAVE_BBT | 1105 | #ifdef ATA_HAVE_BBT |
1102 | ata_bbt_reload(); | 1106 | ata_bbt_reload(); |
1103 | #endif | 1107 | #endif |
1108 | |||
1109 | /* HDD data endianness check: | ||
1110 | During the transition period Rockbox needs to detect the HDD data | ||
1111 | endianness automatically and support both. We're now using the correct | ||
1112 | endianness by default and only switching back to swapped bytes if we | ||
1113 | find a reversed MBR signature. | ||
1114 | To make this warning go away, update your emCORE version. The HDD will | ||
1115 | be reformatted with the correct endianness during the process. | ||
1116 | Once most users have switched over, this code may be removed again. | ||
1117 | -- Michael Sparmann (theseven), 2011-10-22 */ | ||
1118 | if (!ceata) | ||
1119 | { | ||
1120 | unsigned char* sector = fat_get_sector_buffer(); | ||
1121 | ata_rw_sectors(0, 1, sector, false); | ||
1122 | if (sector[510] == 0xaa && sector[511] == 0x55) | ||
1123 | { | ||
1124 | ata_swap = true; | ||
1125 | splashf(5000, "Wrong HDD endianness, please update your emCORE version!"); | ||
1126 | } | ||
1127 | fat_release_sector_buffer(); | ||
1128 | } | ||
1129 | |||
1104 | create_thread(ata_thread, ata_stack, | 1130 | create_thread(ata_thread, ata_stack, |
1105 | sizeof(ata_stack), 0, "ATA idle monitor" | 1131 | sizeof(ata_stack), 0, "ATA idle monitor" |
1106 | IF_PRIO(, PRIORITY_USER_INTERFACE) | 1132 | IF_PRIO(, PRIORITY_USER_INTERFACE) |