diff --strip-trailing-cr -u -r rockbox/trunk/apps/debug_menu.c rockbox-working/apps/debug_menu.c --- rockbox/trunk/apps/debug_menu.c 2009-01-31 14:26:22.000000000 +0200 +++ rockbox-working/apps/debug_menu.c 2009-02-01 12:16:56.000000000 +0200 @@ -1446,53 +1446,86 @@ } #endif +extern int sd_write_sectors (int drive, unsigned long start, int count, const void* outbuf); +extern int sd_read_sectors (int drive, unsigned long start, int count, void* buf); + +#define WR_BUF_SIZE 32768*4 +long write_buffer[WR_BUF_SIZE/4+50]; /* 128kB, 32bit aligned */ +long read_buffer[WR_BUF_SIZE/4]; /* 128kB */ +unsigned int num_sect, num_ok, num_bad, time_wr, cid, misalign; + #ifdef HAVE_ADJUSTABLE_CPU_FREQ static bool dbg_cpufreq(void) { char buf[128]; - int line; - int button; + int line, cnt, boost=0; #ifdef HAVE_LCD_BITMAP lcd_setfont(FONT_SYSFIXED); #endif lcd_clear_display(); + /* init write buffer */ + for(line=0; line<(int)WR_BUF_SIZE; line++) + ((char*)write_buffer)[line] = (char)line; + + num_sect = 1; + num_ok = 0; + num_bad = 0; + while(1) { + time_wr = 0; + for(cnt=0; cnt<10; cnt++) + { + time_wr -= USEC_TIMER; + /* move the write_buffer on every write to assure real overwriting */ + sd_write_sectors(cid, 0x50000+cnt*num_sect, num_sect, (char*)&write_buffer[cnt]+misalign); + time_wr += USEC_TIMER; + memset(read_buffer, 0, num_sect*512); /* invalidate read_buffer */ + sd_read_sectors (cid, 0x50000+cnt*num_sect, num_sect, read_buffer); + + if(memcmp((char*)&write_buffer[cnt]+misalign, read_buffer, num_sect*512) != 0) + { +/* optionally write the buggy data to disk: + { int fd = open("/sectors.bin", O_WRONLY|O_CREAT|O_TRUNC); + write(fd, read_buffer, num_sect*512); + close(fd); + } */ + num_bad++; + } + else + num_ok++; + } + line = 0; - snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ); - lcd_puts(0, line++, buf); + time_wr = (1000 * num_sect*512*10) / time_wr; // [kByte/sec] - snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter()); - lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "Frequen: %ld", FREQ); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "CardType: %s", cid?"ext":"int"); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "NumSects: %d", num_sect); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "NumGoods: %d", num_ok); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "NumBads: %d", num_bad); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "AvgSpeed: %d [kB/s]", time_wr); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "Misalign: %s", misalign?"y":"n");lcd_puts(0, line++, buf); lcd_update(); - button = get_action(CONTEXT_STD,HZ/10); - switch(button) + switch(get_action(CONTEXT_STD,HZ/10)) { - case ACTION_STD_PREV: - cpu_boost(true); - break; - - case ACTION_STD_NEXT: - cpu_boost(false); - break; - - case ACTION_STD_OK: - while (get_cpu_boost_counter() > 0) - cpu_boost(false); - set_cpu_frequency(CPUFREQ_DEFAULT); - break; - - case ACTION_STD_CANCEL: - lcd_setfont(FONT_UI); - return false; + case ACTION_STD_PREV: num_sect--; break; + case ACTION_STD_NEXT: num_sect++; break; + case ACTION_STD_MENU: misalign^=1; break; + case ACTION_STD_OK: cpu_boost((boost^=1) ? true:false); break; + case ACTION_STD_CONTEXT:cid^=1; break; + case ACTION_STD_CANCEL: return false; } + if(num_sect == 0) num_sect = 1; } - lcd_setfont(FONT_UI); + + cpu_boost(false); + return false; } #endif /* HAVE_ADJUSTABLE_CPU_FREQ */ @@ -2651,10 +2684,10 @@ { "Dump ROM contents", dbg_save_roms }, #endif #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \ - || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 + || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L { "View I/O ports", dbg_ports }, #endif -#if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR) + #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR) { "View PCF registers", dbg_pcf }, #endif #if defined(HAVE_TSC2100) && !defined(SIMULATOR) diff --strip-trailing-cr -u -r rockbox/trunk/firmware/target/arm/ata-sd-pp.c rockbox-working/firmware/target/arm/ata-sd-pp.c --- rockbox/trunk/firmware/target/arm/ata-sd-pp.c 2009-02-01 11:12:48.000000000 +0200 +++ rockbox-working/firmware/target/arm/ata-sd-pp.c 2009-02-01 11:42:13.000000000 +0200 @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: ata-sd-pp.c 19893 2009-02-01 09:08:12Z Toni $ + * $Id$ * * Copyright (C) 2006 Daniel Ankers * @@ -481,15 +481,46 @@ /* Writes have to be kept slow for now */ static inline void copy_write_sectors(const unsigned char** buf) { - int cnt = FIFO_LEN; + int cnt = FIFO_LEN - 1; unsigned t; + long time; - do + time = USEC_TIMER + 3; + if (((intptr_t)*buf & 3) == 0) + { + asm volatile ( + "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" + "mov r4, r3, lsr #16 \r\n" + "mov r6, r5, lsr #16 \r\n" + "mov r8, r7, lsr #16 \r\n" + "mov r10, r9, lsr #16 \r\n" + "stmia %[data], { r3-r10 } \r\n" + "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" + "mov r4, r3, lsr #16 \r\n" + "mov r6, r5, lsr #16 \r\n" + "mov r8, r7, lsr #16 \r\n" + "mov %[t], r9, lsr #16 \r\n" + "stmia %[data], { r3-r9 } \r\n" + : [buf]"+&r"(*buf), [t]"=&r"(t) + : [data]"r"(&MMC_DATA_FIFO) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + } + else { + do + { + t = *(*buf)++; + t |= *(*buf)++ << 8; + MMC_DATA_FIFO = t; + } while (--cnt > 0); /* tail loop is faster */ t = *(*buf)++; t |= *(*buf)++ << 8; - MMC_DATA_FIFO = t; - } while (--cnt > 0); /* tail loop is faster */ + } + /* Don't write the last word before at least 3 usec have elapsed since FIFO_EMPTY */ + /* This prevents the 'two bytes inserted' bug. */ + while (!TIME_AFTER(USEC_TIMER, time)); + MMC_DATA_FIFO = t; } static int sd_select_bank(unsigned char bank) @@ -988,15 +1019,13 @@ { /* SDHC */ ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, - 0x1c00 | CMDAT_BUSY | CMDAT_WR_RD | - CMDAT_DATA_EN | CMDAT_RES_TYPE1); + CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1); } else #endif { ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, - 0x1c00 | CMDAT_BUSY | CMDAT_WR_RD | - CMDAT_DATA_EN | CMDAT_RES_TYPE1); + CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1); } if (ret < 0) goto sd_write_error; @@ -1011,18 +1040,15 @@ MMC_SD_STATE = SD_PRG; } - udelay(2); /* needed here (loop is too fast :-) */ + copy_write_sectors(&buf); /* Copy one chunk of 16 words */ + /* TODO: Switch bank if necessary */ /* Wait for the FIFO to empty */ - if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000)) + if (!sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000)) { - copy_write_sectors(&buf); /* Copy one chunk of 16 words */ - /* TODO: Switch bank if necessary */ - continue; + ret = -EC_FIFO_WR_EMPTY; + goto sd_write_error; } - - ret = -EC_FIFO_WR_EMPTY; - goto sd_write_error; } last_disk_activity = current_tick;