diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index d9ed9ac..124ed9f 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES @@ -164,3 +164,4 @@ superdom.c #endif /* m:robe 500 */ md5sum.c +test_disk.c diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 9c65f31..e1804f9 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds @@ -1,4 +1,5 @@ #include "config.h" +#include "cpu.h" /* These output formats should be in the config-files */ @@ -46,9 +47,9 @@ OUTPUT_FORMAT(elf32-littlemips) /* Reserve 1mb for LCD buffer/TTB as in app.lds */ #define DRAMSIZE (MEMORYSIZE * 0x100000 - 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE #elif CONFIG_CPU==AS3525 && MEMORYSIZE <= 2 -#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET +#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - TTB_SIZE #else -#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE +#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE - TTB_SIZE #endif #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300) @@ -99,13 +100,13 @@ OUTPUT_FORMAT(elf32-littlemips) #elif CONFIG_CPU==AS3525 #if MEMORYSIZE <= 2 #define IRAMSIZE 0 /* simulates no IRAM since codec is already entirely in IRAM */ -#define CODEC_ORIGIN (0x50000 - CODEC_SIZE) +#define CODEC_ORIGIN (0x10000000 + 0x50000 - CODEC_SIZE) #define PLUGIN_ORIGIN (DRAMORIG + DRAMSIZE) #else -#define IRAMORIG 0x0 +#define IRAMORIG 0x10000000 #define IRAMSIZE 0x50000 #endif -#define DRAMORIG 0x30000000 +#define DRAMORIG 0x0 #elif CONFIG_CPU == JZ4732 #define DRAMORIG 0x80004000 + STUBOFFSET diff --git a/apps/plugins/test_disk.c b/apps/plugins/test_disk.c index 2fa841b..722f7d3 100644 --- a/apps/plugins/test_disk.c +++ b/apps/plugins/test_disk.c @@ -32,7 +32,7 @@ PLUGIN_HEADER #if (CONFIG_STORAGE & STORAGE_MMC) #define TEST_SIZE (20*1024*1024) #else -#define TEST_SIZE (300*1024*1024) +#define TEST_SIZE (1*1024*1024) #endif #define TEST_TIME 10 /* in seconds */ diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c index 02f040a..d8cd84e 100644 --- a/bootloader/sansa_as3525.c +++ b/bootloader/sansa_as3525.c @@ -33,6 +33,7 @@ #include "storage.h" #include "disk.h" #include "panic.h" +#include "mmu-arm.h" int show_logo(void); void main(void) @@ -81,7 +82,7 @@ void main(void) printf("Loading firmware"); loadbuffer = (unsigned char*)0x30000000; /* DRAM */ - buffer_size = (int)(loadbuffer + (MEM * 0x100000)); + buffer_size = (int)(loadbuffer + (MEM * 0x100000) - TTB_SIZE); ret = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(ret < 0) @@ -91,7 +92,18 @@ void main(void) if (ret == EOK) { - kernel_entry = (void*) loadbuffer; + enable_mmu(); +#if 1 + asm volatile( + "mov r0, #0 \n" + "mrc p15, 0, r0, c1, c0 \n" /* control register */ + "bic r0, r0, #0x1000 \n" /* disable icache */ + "bic r0, r0, #4 \n" /* disable dcache */ + "mcr p15, 0, r0, c1, c0 \n" + : : : "r0" ); +#endif + + kernel_entry = /*(void*) loadbuffer*/ 0; printf("Executing"); kernel_entry(); printf("ERR: Failed to boot"); diff --git a/firmware/SOURCES b/firmware/SOURCES index 91482bf..8f53987 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -360,6 +360,7 @@ target/arm/as3525/power-as3525.c target/arm/as3525/usb-as3525.c target/arm/as3525/dma-pl081.c target/arm/as3525/ascodec-as3525.c +target/arm/mmu-arm.S #ifndef BOOTLOADER drivers/generic_i2c.c target/arm/adc-as3514.c diff --git a/firmware/export/as3525.h b/firmware/export/as3525.h index 388df2a..3b84427 100644 --- a/firmware/export/as3525.h +++ b/firmware/export/as3525.h @@ -26,6 +26,10 @@ #define ECCSIZE 512 #define ECCBYTES 3 +/* AS352X MMU Page Table Entries */ +#define TTB_SIZE 0x4000 /* Mimics OF */ +#define TTB_BASE_ADDR (0x30000000 + MEM*0x100000 - TTB_SIZE) + /* AS352X device base addresses */ diff --git a/firmware/target/arm/as3525/app.lds b/firmware/target/arm/as3525/app.lds index 09844a1..fc2cace 100644 --- a/firmware/target/arm/as3525/app.lds +++ b/firmware/target/arm/as3525/app.lds @@ -1,4 +1,5 @@ #include "config.h" +#include "cpu.h" ENTRY(start) @@ -20,20 +21,19 @@ STARTUP(target/arm/crt0.o) #define STUBOFFSET 0 #endif -#include "cpu.h" - #define IRAMSIZE 0x50000 #ifdef LOWMEM -#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE +#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - TTB_SIZE #define CODECORIG (IRAMORIG + IRAMSIZE - CODEC_SIZE) #else -#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE +#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE \ + - TTB_SIZE #define CODECORIG (ENDAUDIOADDR) #endif -#define IRAMORIG 0x0 -#define DRAMORIG 0x30000000 + STUBOFFSET +#define IRAMORIG 0x10000000 +#define DRAMORIG 0 + STUBOFFSET /* End of the audio buffer, where the codec buffer starts */ #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) @@ -58,7 +58,13 @@ MEMORY SECTIONS { - loadaddress = 0x30000000; + loadaddress = 0x0; + + .vectors 0x0: + { + _vectors_start = .; + *(.init.text) + } > DRAM .text : { @@ -91,14 +97,6 @@ SECTIONS *(.eh_frame) } - .vectors IRAMORIG: - { - _vectors_start = .; - *(.init.text) - } > IRAM AT > DRAM - - _vectorscopy = LOADADDR(.vectors); - .iram : { _iramstart = .; diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 042af3b..5a87ae9 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c @@ -41,6 +41,7 @@ #include "stdbool.h" #include "ata_idle_notify.h" #include "sd.h" +#include "mmu-arm.h" #ifdef HAVE_HOTSWAP #include "disk.h" @@ -81,6 +82,8 @@ #define INTERNAL_AS3525 0 /* embedded SD card */ #define SD_SLOT_AS3525 1 /* SD slot if present */ +static volatile int bad_status = 0; + static const int pl180_base[NUM_VOLUMES] = { NAND_FLASH_BASE #ifdef HAVE_MULTIVOLUME @@ -176,7 +179,10 @@ void INT_NAND(void) const int status = MCI_STATUS(INTERNAL_AS3525); if(status & MCI_ERROR) + { + bad_status = status; retry = true; + } wakeup_signal(&transfer_completion_signal); MCI_CLEAR(INTERNAL_AS3525) = status; @@ -646,7 +652,7 @@ static int sd_select_bank(signed char bank) } static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, - int count, void* buf, bool write) + int count, void* buf, const bool write) { #ifndef HAVE_MULTIVOLUME const int drive = 0; @@ -704,6 +710,15 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, dma_retain(); +#ifndef BOOTLOADER +#if 0 + if(write) /* write back cache to memory the region we'll write */ + clean_dcache_range(buf, count * BLOCK_SIZE); + else /* invalidate cache of memory region where we'll read */ + dump_dcache_range(buf, count * BLOCK_SIZE); +#endif +#endif /* ! BOOTLOADER */ + while(count) { /* Interrupt handler might set this to true during transfer */ @@ -739,7 +754,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, (1<<3) /* DMA */ | (9<<4) /* 2^9 = 512 */ ; - wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); if(!retry) { @@ -747,6 +761,10 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, start += transfer; count -= transfer; } +#ifdef BOOTLOADER + else + printf("status %x", bad_status); +#endif last_disk_activity = current_tick; diff --git a/firmware/target/arm/as3525/boot.lds b/firmware/target/arm/as3525/boot.lds index 7a13d67..91884e5 100644 --- a/firmware/target/arm/as3525/boot.lds +++ b/firmware/target/arm/as3525/boot.lds @@ -1,18 +1,21 @@ #include "config.h" +#include "cpu.h" ENTRY(start) OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/crt0.o) -#define DRAMSIZE (MEMORYSIZE * 0x100000) +/* +#define DRAMSIZE (MEMORYSIZE * 0x100000) - TTB_SIZE #define DRAMORIG 0x30000000 -#define IRAMORIG 0 +*/ +#define IRAMORIG 0x81000000 #define IRAMSIZE 0x50000 MEMORY { - DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + /*DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE*/ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE } diff --git a/firmware/target/arm/as3525/debug-as3525.c b/firmware/target/arm/as3525/debug-as3525.c index a8a973b..a4c0a44 100644 --- a/firmware/target/arm/as3525/debug-as3525.c +++ b/firmware/target/arm/as3525/debug-as3525.c @@ -46,19 +46,146 @@ short button_dbop_data(void); #endif -static unsigned read_cp15 (void) +static unsigned read_cp15 (int reg) { unsigned value; - asm volatile ( - "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n":"=r" - (value)::"memory" - ); - return (value); + switch (reg) { + + case 0: /* Register 0 Op2 =0 ID Code */ + asm volatile ( + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 1: /* Register 1 Control */ + asm volatile ( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 2: /* Register 2 Translation Table Base */ + asm volatile ( + "mrc p15, 0, %0, c2, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 3: /* Register 3 Domain Access Control */ + asm volatile ( + "mrc p15, 0, %0, c3, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 4: /*Reg 5 Fault Status of prefetch*/ + asm volatile ( + "mrc p15, 0, %0, c5, c0, 1 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 5: /* Register 5 Fault Status */ + asm volatile ( + "mrc p15, 0, %0, c5, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 6: /* Register 6 Fault address */ + asm volatile ( + "mrc p15, 0, %0, c6, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 7: /* Register 0 Op2 =1 Cache type */ + asm volatile ( + "mrc p15, 0, %0, c0, c0, 1 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 8: /*Reg 9 Cache lockdown Op2 1=Icache*/ + asm volatile ( + "mrc p15, 0, %0, c9, c0, 1 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 9: /*Reg 9 Cache lockdown Op2 0 = Dcache*/ + asm volatile ( + "mrc p15, 0, %0, c9, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 10: /*Reg 10 TLB lockdown Op2 0 = Dcache*/ + asm volatile ( + "mrc p15, 0, %0, c10, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 11: /*Reg 10 TLB lockdown Op2 1=Icache*/ + asm volatile ( + "mrc p15, 0, %0, c10, c0, 1 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 13: /* Register 13 FCSE PID */ + asm volatile ( + "mrc p15, 0, %0, c13, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + + case 15: /* Register 15 Test configuration */ + asm volatile ( + "mrc p15, 0, %0, c15, c0, 0 @ read control reg\n":"=r" + (value)::"memory" + ); + return (value); + return (0xdeadbeef); + } + return (0xdeadbeef); } bool __dbg_hw_info(void) { + char buf[50]; + int line; + + lcd_clear_display(); + lcd_setfont(FONT_SYSFIXED); + + while(1) + { + line = 0; + _DEBUG_PRINTF("[CP15 Registers:]"); + _DEBUG_PRINTF("c00 : 0x%8x ID", read_cp15(0)); + _DEBUG_PRINTF("c01 : 0x%8x CacheType", read_cp15(7)); + _DEBUG_PRINTF("c1 : 0x%8x Control", read_cp15(1)); + _DEBUG_PRINTF("c2 : 0x%8x TTB", read_cp15(2)); + _DEBUG_PRINTF("c3 : 0x%8x DomainCTL", read_cp15(3)); + _DEBUG_PRINTF("c50 : 0x%2x Data FSR", read_cp15(5)); + _DEBUG_PRINTF("c51 : 0x%2x Prefetch FSR", read_cp15(4)); + _DEBUG_PRINTF("c6 : 0x%8x FltAddress", read_cp15(6)); + _DEBUG_PRINTF("c90 : 0x%8x DcacheLock", read_cp15(9)); + _DEBUG_PRINTF("c91 : 0x%8x IcacheLock", read_cp15(8)); + _DEBUG_PRINTF("c100: 0x%8x TLBLockD", read_cp15(10)); + _DEBUG_PRINTF("c101: 0x%8x TLBLockI", read_cp15(11)); + _DEBUG_PRINTF("c13 : 0x%8x FCFE PID", read_cp15(13)); + _DEBUG_PRINTF("c15 : 0x%8x Test", read_cp15(15)); + + lcd_update(); + if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) + break; + } + lcd_setfont(FONT_UI); return false; } @@ -84,8 +211,6 @@ bool __dbg_ports(void) _DEBUG_PRINTF("DBOP_DIN: %4x", button_dbop_data()); #endif line++; - _DEBUG_PRINTF("[CP15]"); - _DEBUG_PRINTF("CP15: 0x%8x", read_cp15()); lcd_update(); if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) break; diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c index 8a97986..e73ae02 100644 --- a/firmware/target/arm/as3525/dma-pl081.c +++ b/firmware/target/arm/as3525/dma-pl081.c @@ -63,6 +63,21 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri, { dma_callback[channel] = callback; +#ifndef BOOTLOADER /* && !defined(MMU_IN_BOOTLOADER) /!\ */ + /* use physical addresses for DMA */ + if((unsigned long)dst < (MEM * 0x100000)) /* SDRAM */ + dst += 0x30000000; + else if((unsigned long)dst >= 0x10000000 && + (unsigned long)dst < 0x10050000) /* IRAM */ + dst += 0x80000000; + + if((unsigned long)src < (MEM * 0x100000)) /* SDRAM */ + src += 0x30000000; + else if((unsigned long)src >= 0x10000000 && + (unsigned long)src < 0x10050000) /* IRAM */ + src += 0x80000000; +#endif + int control = 0; DMAC_CH_SRC_ADDR(channel) = (int)src; diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index a5f34d9..488c195 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -28,6 +28,7 @@ #include "clock-target.h" #include "fmradio_i2c.h" #include "button-target.h" +#include "mmu-arm.h" #define default_interrupt(name) \ extern __attribute__((weak,alias("UIRQ"))) void name (void) @@ -243,20 +244,33 @@ void system_init(void) CGU_PERI |= ((CLK_DIV(AS3525_PLLA_FREQ, AS3525_PCLK_FREQ) - 1) << 2) | 1; /* clk_in = PLLA */ - - /* FIXME: dcache will not be active, since the mmu is not running - * See arm922t datasheet */ +#ifdef BOOTLOADER asm volatile( "mov r0, #0 \n" - "mcr p15, 0, r0, c7, c7 \n" /* invalidate icache & dcache */ "mrc p15, 0, r0, c1, c0 \n" /* control register */ - "orr r0, r0, #0x1000 \n" /* enable icache */ - "orr r0, r0, #4 \n" /* enable dcache */ + "bic r0, r0, #0x1000 \n" /* disable icache */ + "bic r0, r0, #4 \n" /* disable dcache */ + "bic r0, r0, #1 \n" /* disable mmu */ "mcr p15, 0, r0, c1, c0 \n" : : : "r0" ); -#ifdef BOOTLOADER sdram_init(); + +//#define MMU_IN_BOOTLOADER +#ifdef MMU_IN_BOOTLOADER + int i; + for(i=0; i< 0x44; i++) /* vectors */ + ((unsigned long*)0x30000000)[i] = ((unsigned long*)0x81000000)[i]; +#endif + + ttb_init(); + map_section(0, 0, 0x1000, CACHE_NONE); + map_section(0x81000000, 0x10000000, 1, /*CACHE_ALL*/ CACHE_NONE); /* IRAM */ + map_section(0x30000000, 0x0, MEM, /*CACHE_ALL*/ CACHE_NONE); /* sdram */ +#ifdef MMU_IN_BOOTLOADER + enable_mmu(); +#endif + #endif /* BOOTLOADER */ #if 0 /* the GPIO clock is already enabled by the dualboot function */ diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index 35d0aec..d2ec15a 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S @@ -59,6 +59,7 @@ newstart: #if CONFIG_CPU==AS3525 && !defined(BOOTLOADER) +#if 0 /* relocate vectors */ mov r1, #0 @ destination ldr r2, =_vectorscopy @ source @@ -68,6 +69,7 @@ newstart: str r0, [r1], #4 cmp r1, r3 bne 1b +#endif /* Zero out IBSS */ ldr r2, =_iedata diff --git a/firmware/target/arm/mmu-arm.S b/firmware/target/arm/mmu-arm.S index 2223be2..c1aa697 100644 --- a/firmware/target/arm/mmu-arm.S +++ b/firmware/target/arm/mmu-arm.S @@ -476,12 +476,65 @@ invalidate_dcache: .type invalidate_idcache, %function .global cpucache_invalidate @ Alias invalidate_idcache: -cpucache_invalidate: +cpucache_invalidate: mov r1, lr @ save lr to r1, call uses r0 only bl invalidate_dcache @ Clean and invalidate entire DCache mcr p15, 0, r0, c7, c5, 0 @ Invalidate ICache (r0=0 from call) mov pc, r1 @ .size invalidate_idcache, .-invalidate_idcache +/* + *void mmu_bus_fast(void) + * + */ + .section .text, "ax", %progbits + .align 2 + .global mmu_bus_fast + .type mmu_bus_fast, %function + +mmu_bus_fast: + mrc 15, 0, r0, c1, c0, 0 @Read control reg + bic r0, r0, #0xc0000000 @Set Fast Bus + mcr 15, 0, r0, c1, c0, 0 @Make it so + bx lr + + .size mmu_bus_fast, .-mmu_bus_fast + +/* + *void mmu_bus_sync(void) + * + */ + .section .text, "ax", %progbits + .align 2 + .global mmu_bus_sync + .type mmu_bus_sync, %function + +mmu_bus_sync: + mrc 15, 0, r0, c1, c0, 0 @Read control reg + bic r0, r0, #0xc0000000 @Clear Bus bits + orr r0, r0, #0x40000000 @Set Sync Bus + mcr 15, 0, r0, c1, c0, 0 @Make it so + bx lr + + .size mmu_bus_sync, .-mmu_bus_sync + +/* + *void mmu_bus_async(void) + * + */ + .section .text, "ax", %progbits + .align 2 + .global mmu_bus_async + .type mmu_bus_async, %function + +mmu_bus_async: + mrc 15, 0, r0, c1, c0, 0 @Read control reg + bic r0, r0, #0xc0000000 @Set Fast Bus + mcr 15, 0, r0, c1, c0, 0 @Make it so + bx lr + + .size mmu_bus_async, .-mmu_bus_async + + #endif /* !IMX31L */ diff --git a/firmware/target/arm/mmu-arm.h b/firmware/target/arm/mmu-arm.h index f3e8a8d..a892449 100644 --- a/firmware/target/arm/mmu-arm.h +++ b/firmware/target/arm/mmu-arm.h @@ -53,6 +53,12 @@ void dump_dcache_range(const void *base, unsigned int size); /* will do writeback */ void invalidate_idcache(void); +/* Set bus speed relationships */ +void mmu_bus_fast(void); +void mmu_bus_sync(void); +void mmu_bus_async(void); + + #define HAVE_CPUCACHE_INVALIDATE #define HAVE_CPUCACHE_FLUSH