diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index 10b1370..cae54b2 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 */ @@ -45,10 +46,12 @@ OUTPUT_FORMAT(elf32-littlemips) #include "imx31l.h" /* 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 +#elif CONFIG_CPU==AS3525 +#ifdef AMS_LOWMEM +#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 #endif #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300) @@ -97,15 +100,15 @@ OUTPUT_FORMAT(elf32-littlemips) #define IRAM DRAM #define IRAMSIZE 0 #elif CONFIG_CPU==AS3525 -#if MEMORYSIZE <= 2 +#define DRAMORIG 0x30000000 + STUBOFFSET +#ifdef AMS_LOWMEM #define IRAMSIZE 0 /* simulates no IRAM since codec is already entirely in IRAM */ -#define CODEC_ORIGIN (0x50000 - CODEC_SIZE) -#define PLUGIN_ORIGIN (DRAMORIG + DRAMSIZE) +#define CODEC_ORIGIN (IRAM_ORIG + IRAM_SIZE - CODEC_SIZE) +#define PLUGIN_ORIGIN (DRAM_ORIG + DRAMSIZE) #else -#define IRAMORIG 0x10000 -#define IRAMSIZE 0x40000 +#define IRAMORIG (IRAM_ORIG + 0x10000) +#define IRAMSIZE (IRAM_ORIG + IRAM_SIZE - IRAMORIG) #endif -#define DRAMORIG 0x30000000 #elif CONFIG_CPU == JZ4732 #define DRAMORIG 0x80004000 + STUBOFFSET diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c index 08b8365..c297560 100644 --- a/bootloader/sansa_as3525.c +++ b/bootloader/sansa_as3525.c @@ -35,10 +35,11 @@ #include "panic.h" #include "power.h" +#include "mmu-arm.h" void morpion(void); int show_logo(void); -void main(void) __attribute__((noreturn)); +void main(void) __attribute__((noreturn, naked)); void main(void) { unsigned char* loadbuffer; @@ -109,21 +110,20 @@ void main(void) printf("Loading firmware"); loadbuffer = (unsigned char*)0x30000000; /* DRAM */ - buffer_size = (int)(loadbuffer + (MEM * 0x100000)); + buffer_size = (int)(DRAM_SIZE - TTB_SIZE); ret = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(ret < 0) error(EBOOTFILE, ret); - disable_irq(); /* disable irq until we have copied the new vectors */ + disable_irq(); - if (ret == EOK) - { - kernel_entry = (void*) loadbuffer; - printf("Executing"); - kernel_entry(); - printf("ERR: Failed to boot"); - } + kernel_entry = (void*)0; + printf("Executing"); + enable_mmu(); /* TTB has been setup by system_init() */ + kernel_entry(); + + printf("ERR: Failed to boot"); /* never returns */ while(1) ; diff --git a/firmware/SOURCES b/firmware/SOURCES index fbf8acd..a014717 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -362,6 +362,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..1f7ffdf 100644 --- a/firmware/export/as3525.h +++ b/firmware/export/as3525.h @@ -22,10 +22,30 @@ #define UART_CHANNELS 1 + +#if MEMORYSIZE <= 2 +/* we put the codec buffer in IRAM */ +#define AMS_LOWMEM +#endif +/* these addresses are valid after mapping through the MMU */ +#define DRAM_ORIG 0x0 +#define IRAM_ORIG (DRAM_ORIG + DRAM_SIZE) +/* +#define IRAM_ORIG 0x10000000 +*/ + +#define DRAM_SIZE (MEMORYSIZE * 0x100000) +#define IRAM_SIZE 0x50000 + + /* AS352X only supports 512 Byte HW ECC */ #define ECCSIZE 512 #define ECCBYTES 3 +/* AS352X MMU Page Table Entries */ +#define TTB_SIZE 0x4000 /* Mimics OF */ +#define TTB_BASE_ADDR (0x30000000 + DRAM_SIZE - TTB_SIZE) + /* AS352X device base addresses */ diff --git a/firmware/target/arm/as3525/app.lds b/firmware/target/arm/as3525/app.lds index cbc391c..9cd8e0c 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) @@ -6,11 +7,6 @@ OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/crt0.o) -#if MEMORYSIZE <= 2 -/* we put the codec buffer in IRAM */ -#define LOWMEM -#endif - #define PLUGINSIZE PLUGIN_BUFFER_SIZE #define CODECSIZE CODEC_SIZE @@ -20,13 +16,11 @@ STARTUP(target/arm/crt0.o) #define STUBOFFSET 0 #endif -#include "cpu.h" - -#ifdef LOWMEM -#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE +#ifdef AMS_LOWMEM +#define DRAMSIZE (DRAM_SIZE - STUBOFFSET - PLUGINSIZE - TTB_SIZE) #define CODECORIG (IRAMORIG + 0x50000 - CODEC_SIZE) #else -#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE +#define DRAMSIZE DRAM_SIZE - STUBOFFSET - PLUGINSIZE - CODECSIZE - TTB_SIZE #define CODECORIG (ENDAUDIOADDR) #endif @@ -34,15 +28,15 @@ STARTUP(target/arm/crt0.o) #define IRAMORIG 0x81000000 #define DRAMORIG 0x0 + STUBOFFSET #else -#define IRAMORIG 0x0 -#define DRAMORIG 0x30000000 + STUBOFFSET +#define IRAMORIG IRAM_ORIG +#define DRAMORIG (DRAM_ORIG + STUBOFFSET) #endif /* End of the audio buffer, where the codec buffer starts */ #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) /* Where the codec buffer ends, and the plugin buffer starts */ -#ifdef LOWMEM +#ifdef AMS_LOWMEM #define ENDADDR (ENDAUDIOADDR) #else #define ENDADDR (ENDAUDIOADDR + CODECSIZE) @@ -50,7 +44,7 @@ STARTUP(target/arm/crt0.o) MEMORY { -#ifdef LOWMEM +#ifdef AMS_LOWMEM IRAM : ORIGIN = IRAMORIG, LENGTH = (0x50000 - CODEC_SIZE) CODEC_IRAM : ORIGIN = CODECORIG, LENGTH = CODEC_SIZE #else @@ -64,20 +58,14 @@ SECTIONS #if defined(SANSA_CLIPV2) loadaddress = 0x0; #else - loadaddress = 0x30000000; + loadaddress = DRAM_ORIG; #endif .vectors 0x0: { _vectors_start = .; *(.init.text) -#if defined(SANSA_CLIPV2) } > DRAM -#else - } > IRAM AT > DRAM - - _vectorscopy = LOADADDR(.vectors); -#endif .text : { @@ -92,10 +80,7 @@ SECTIONS .rodata : { - *(.rodata) /* problems without this, dunno why */ *(.rodata*) - *(.rodata.str1.1) - *(.rodata.str1.4) . = ALIGN(0x4); } > DRAM @@ -165,7 +150,7 @@ SECTIONS { codecbuf = .; _codecbuf = .; -#ifdef LOWMEM +#ifdef AMS_LOWMEM } > CODEC_IRAM #else } > DRAM diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 7e5bc12..3199ed3 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" @@ -708,6 +709,13 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, dma_retain(); +#ifndef BOOTLOADER + if(write) /* write back cached data to memory before we use it */ + clean_dcache_range(buf, count * BLOCK_SIZE); + else /* write back buffer ends to memory before we modify memory */ + dump_dcache_range(buf, count * BLOCK_SIZE); +#endif + while(count) { /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH @@ -783,6 +791,11 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, } } +#ifndef BOOTLOADER + if(!write) /* invalidate cached data because memory content changed */ + dump_dcache_range(buf, count * BLOCK_SIZE); +#endif + dma_release(); #ifndef BOOTLOADER diff --git a/firmware/target/arm/as3525/boot.lds b/firmware/target/arm/as3525/boot.lds index 95199f2..6a0a5c3 100644 --- a/firmware/target/arm/as3525/boot.lds +++ b/firmware/target/arm/as3525/boot.lds @@ -1,11 +1,16 @@ #include "config.h" +#include "cpu.h" ENTRY(start) OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/crt0.o) +#ifdef SANSA_CLIPV2 #define RAMORIG 0 +#else +#define RAMORIG 0x81000000 +#endif #ifdef SANSA_CLIPV2 /* DRAM is mapped at 0 */ #define RAMSIZE (MEM*0x100000 - RAMORIG) diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c index dd15bb4..8272948 100644 --- a/firmware/target/arm/as3525/dma-pl081.c +++ b/firmware/target/arm/as3525/dma-pl081.c @@ -20,7 +20,7 @@ ****************************************************************************/ #include -#include "as3525.h" +#include "cpu.h" #include "pl081.h" #include "dma-target.h" #include "panic.h" @@ -75,6 +75,21 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri, { dma_callback[channel] = callback; +#ifndef BOOTLOADER + /* use physical addresses for DMA */ + if((unsigned long)dst < (DRAM_SIZE)) /* SDRAM */ + dst += 0x30000000; + else if((unsigned long)dst >= IRAM_ORIG && + (unsigned long)dst < (IRAM_ORIG + IRAM_SIZE)) /* IRAM */ + dst += (0x81000000 - IRAM_ORIG); + + if((unsigned long)src < DRAM_SIZE) /* SDRAM */ + src += 0x30000000; + else if((unsigned long)src >= IRAM_ORIG && + (unsigned long)src < (IRAM_ORIG + IRAM_SIZE)) /* IRAM */ + src += (0x81000000 - IRAM_ORIG); +#endif + int control = 0; DMAC_CH_SRC_ADDR(channel) = (int)src; diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index 5074941..6024633 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -28,6 +28,7 @@ #include "panic.h" #include "as3514.h" #include "audiohw.h" +#include "mmu-arm.h" #define MAX_TRANSFER (4*((1<<11)-1)) /* maximum data we can transfer via DMA * i.e. 32 bits at once (size of I2SO_DATA) @@ -69,6 +70,7 @@ static void play_start_pcm(void) CGU_PERI |= CGU_I2SOUT_APB_CLOCK_ENABLE; CGU_AUDIO |= (1<<11); + clean_dcache_range((void*)addr, size); /* force write back */ dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT, DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1, dma_callback); diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 99f469d..d677c49 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) @@ -244,21 +245,15 @@ 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 */ - 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 */ - "mcr p15, 0, r0, c1, c0 \n" - : : : "r0" ); - #ifdef BOOTLOADER sdram_init(); + + ttb_init(); + map_section(0, 0, 0x1000, CACHE_NONE); + map_section(0x81000000, IRAM_ORIG, 1, CACHE_ALL); /* IRAM */ + map_section(0x30000000, DRAM_ORIG, MEMORYSIZE, /*CACHE_ALL*/0); /* sdram */ #endif /* BOOTLOADER */ + #else unsigned int reset_loops = 640; diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index 2172be3..cb5fe00 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S @@ -59,18 +59,6 @@ newstart: #if CONFIG_CPU==AS3525 && !defined(BOOTLOADER) -#ifndef SANSA_CLIPV2 - /* relocate vectors */ - mov r1, #0 @ destination - ldr r2, =_vectorscopy @ source - ldr r3, =_vectorsend @ end - -1: ldr r0, [r2], #4 - str r0, [r1], #4 - cmp r1, r3 - bne 1b -#endif /* SANSA_CLIPV2 */ - /* Zero out IBSS */ ldr r2, =_iedata ldr r3, =_iend diff --git a/tools/configure b/tools/configure index e62fe07..2cc9d76 100755 --- a/tools/configure +++ b/tools/configure @@ -259,7 +259,7 @@ arm7tdmicc () { arm9tdmicc () { prefixtools arm-elf- GCCOPTS="$CCOPTS -mcpu=arm9tdmi" - if test "$modelname" != "gigabeatf"; then + if test "$modelname" != "gigabeatf" -a "$t_manufacturer" != "as3525"; then GCCOPTS="$GCCOPTS -mlong-calls" fi GCCOPTIMIZE="-fomit-frame-pointer" @@ -1716,7 +1716,6 @@ fi modelname="clip" target="-DSANSA_CLIP" memory=2 - arm9tdmicc bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$bmp2rb_mono" tool="$rootdir/tools/scramble -add=clip" @@ -1729,6 +1728,7 @@ fi t_cpu="arm" t_manufacturer="as3525" t_model="sansa-clip" + arm9tdmicc ;; 551|Clipv2|clipv2) @@ -1757,7 +1757,6 @@ fi modelname="e200v2" target="-DSANSA_E200V2" memory=8 - arm9tdmicc bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 4" tool="$rootdir/tools/scramble -add=e2v2" @@ -1770,6 +1769,7 @@ fi t_cpu="arm" t_manufacturer="as3525" t_model="sansa-e200v2" + arm9tdmicc ;; 57|m200v4) @@ -1777,7 +1777,6 @@ fi modelname="m200v4" target="-DSANSA_M200V4" memory=2 - arm9tdmicc bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$bmp2rb_mono" tool="$rootdir/tools/scramble -add=m2v4" @@ -1790,6 +1789,7 @@ fi t_cpu="arm" t_manufacturer="as3525" t_model="sansa-m200v4" + arm9tdmicc ;; @@ -1798,7 +1798,6 @@ fi modelname="fuze" target="-DSANSA_FUZE" memory=8 - arm9tdmicc bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 4" tool="$rootdir/tools/scramble -add=fuze" @@ -1811,6 +1810,7 @@ fi t_cpu="arm" t_manufacturer="as3525" t_model="sansa-fuze" + arm9tdmicc ;; @@ -1819,7 +1819,6 @@ fi modelname="c200v2" target="-DSANSA_C200V2" memory=2 # as per OF diagnosis mode - arm9tdmicc bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 4" tool="$rootdir/tools/scramble -add=c2v2" @@ -1835,6 +1834,7 @@ fi t_cpu="arm" t_manufacturer="as3525" t_model="sansa-c200v2" + arm9tdmicc ;; 60|tpj1022)