diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-10-19 19:35:24 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-10-19 19:35:24 +0000 |
commit | abd9f83e92fae22dcb9806deae665b7b303f430d (patch) | |
tree | 8d0d1d65c6aaa596e171cda2d78706739046d0bd | |
parent | 266f173b72967bae96119e5428fabe692edd8c30 (diff) |
Two new sections for IRAM usage: .irodata (selectable with the ICONST_ATTR attribute macro), allowing to put 'const' data into IRAM without causing a section type conflict, and .ibss (selectable with the IBSS_ATTR attribute macro) for uninitialised data. * Rockbox core: Adjusted the linker scripts and init code to not include the .ibss section in the binary, it is cleared instead. Saves ~500 bytes on archos and ~30KB on iriver. Codecs and plugins don't handle .ibss in a special way yet. * The init code properly handles empty sections now (except .stack, which should never be empty). * Unified the init code for SH1 and coldfire a bit.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7644 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/dsp.c | 10 | ||||
-rw-r--r-- | apps/playback.c | 4 | ||||
-rw-r--r-- | apps/plugins/plugin.lds | 2 | ||||
-rw-r--r-- | firmware/app.lds | 9 | ||||
-rw-r--r-- | firmware/boot.lds | 4 | ||||
-rw-r--r-- | firmware/crt0.S | 162 | ||||
-rw-r--r-- | firmware/drivers/lcd-h100-remote.c | 2 | ||||
-rw-r--r-- | firmware/drivers/lcd-h100.c | 5 | ||||
-rw-r--r-- | firmware/export/config.h | 4 | ||||
-rw-r--r-- | firmware/rom.lds | 9 | ||||
-rw-r--r-- | firmware/thread.c | 4 |
11 files changed, 141 insertions, 74 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index 8ec36c3f33..ff4c840008 100644 --- a/apps/dsp.c +++ b/apps/dsp.c @@ -130,9 +130,9 @@ struct dither_data long random; }; -static struct dsp_config dsp_conf[2] IDATA_ATTR; -static struct dither_data dither_data[2] IDATA_ATTR; -static struct resample_data resample_data[2][2] IDATA_ATTR; +static struct dsp_config dsp_conf[2] IBSS_ATTR; +static struct dither_data dither_data[2] IBSS_ATTR; +static struct resample_data resample_data[2][2] IBSS_ATTR; extern int current_codec; struct dsp_config *dsp; @@ -142,8 +142,8 @@ struct dsp_config *dsp; * of copying needed is minimized for that case. */ -static long sample_buf[SAMPLE_BUF_SIZE] IDATA_ATTR; -static long resample_buf[RESAMPLE_BUF_SIZE] IDATA_ATTR; +static long sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR; +static long resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR; /* Convert at most count samples to the internal format, if needed. Returns diff --git a/apps/playback.c b/apps/playback.c index d38e1f4527..5b78ad53ba 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -112,13 +112,13 @@ static const char audio_thread_name[] = "audio"; /* Codec thread. */ static struct event_queue codec_queue; -static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] IDATA_ATTR; +static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] IBSS_ATTR; static const char codec_thread_name[] = "codec"; /* Voice codec thread. */ static struct event_queue voice_codec_queue; /* Not enough IRAM for this. */ -static long voice_codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] IDATA_ATTR; +static long voice_codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] IBSS_ATTR; static const char voice_codec_thread_name[] = "voice codec"; static struct mutex mutex_bufferfill; diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds index bf400cf2e5..3e7261f024 100644 --- a/apps/plugins/plugin.lds +++ b/apps/plugins/plugin.lds @@ -80,7 +80,9 @@ SECTIONS { iramstart = .; *(.icode) + *(.irodata) *(.idata) + *(.ibss) iramend = .; } > PLUGIN_IRAM #endif diff --git a/firmware/app.lds b/firmware/app.lds index 86dafadbe1..5a0db8f8e3 100644 --- a/firmware/app.lds +++ b/firmware/app.lds @@ -188,9 +188,18 @@ SECTIONS { _iramstart = .; *(.icode) + *(.irodata) *(.idata) _iramend = .; } > IRAM + + .ibss (NOLOAD) : + { + _iedata = .; + *(.ibss) + . = ALIGN(0x4); + _iend = .; + } > IRAM #ifdef CPU_COLDFIRE .stack : diff --git a/firmware/boot.lds b/firmware/boot.lds index 4ce0eb974c..a693c2149b 100644 --- a/firmware/boot.lds +++ b/firmware/boot.lds @@ -51,9 +51,10 @@ SECTIONS *(.resetvectors); *(.vectors); . = ALIGN(0x200); - *(.data) *(.icode) + *(.irodata) *(.idata) + *(.data) . = ALIGN(0x4); _dataend = .; . = ALIGN(0x10); /* Maintain proper alignment for .text section */ @@ -91,6 +92,7 @@ SECTIONS .bss : { _edata = .; + *(.ibss) *(.bss) *(COMMON) _end = .; diff --git a/firmware/crt0.S b/firmware/crt0.S index 6a15324567..f41b57554b 100644 --- a/firmware/crt0.S +++ b/firmware/crt0.S @@ -246,7 +246,7 @@ irq_handler: move.l #0xffffffbf,%d0 and.l %d0,(0x108,%a0) /* Back to normal, the DRAM is now ready */ -#endif +#endif /* BOOTLOADER */ /* Invalicate cache */ move.l #0x01000000,%d0 @@ -263,38 +263,57 @@ irq_handler: movec.l %d0,%acr1 #ifndef BOOTLOADER + /* zero out .ibss */ + lea _iedata,%a2 + lea _iend,%a4 + bra.b .iedatastart +.iedataloop: + clr.l (%a2)+ +.iedatastart: + cmp.l %a2,%a4 + bhi.b .iedataloop + + /* copy the .iram section */ lea _iramcopy,%a2 lea _iramstart,%a3 lea _iramend,%a4 + bra.b .iramstart .iramloop: move.l (%a2)+,(%a3)+ +.iramstart: cmp.l %a3,%a4 bhi.b .iramloop -#endif +#endif /* !BOOTLOADER */ + /* zero out bss */ lea _edata,%a2 lea _end,%a4 + bra.b .edatastart .edataloop: clr.l (%a2)+ +.edatastart: cmp.l %a2,%a4 bhi.b .edataloop + /* copy the .data section */ lea _datacopy,%a2 lea _datastart,%a3 - lea _dataend,%a4 cmp.l %a2,%a3 - beq.b .nodatacopy + beq.b .nodatacopy /* Don't copy if src and dest are equal */ + lea _dataend,%a4 + bra.b .datastart .dataloop: move.l (%a2)+,(%a3)+ +.datastart: cmp.l %a3,%a4 bhi.b .dataloop .nodatacopy: /* Munge the main stack */ - move.l #0xdeadbeef,%d0 lea stackbegin,%a2 lea stackend,%a4 move.l %a4,%sp + move.l #0xdeadbeef,%d0 .mungeloop: move.l %d0,(%a2)+ cmp.l %a2,%a4 @@ -315,12 +334,12 @@ vectors: #else /* Platform: Archos Jukebox */ - mov.l vbr_k,r1 + mov.l .vbr_k,r1 #ifdef DEBUG /* If we have built our code to be loaded via the standalone GDB * stub, we will have out VBR at some other location than 0x9000000. * We must copy the trap vectors for the GDB stub to our vector table. */ - mov.l orig_vbr_k,r2 + mov.l .orig_vbr_k,r2 /* Move the invalid instruction vector (4) */ mov #4,r0 @@ -384,58 +403,77 @@ vectors: #endif /* DEBUG */ ldc r1,vbr - /* Now let's get on with the normal business */ - mov.l stackend_k,r15 + mov #0,r0 + ldc r0,gbr - /* zero out bss */ - mov.l edata_k,r0 - mov.l end_k,r1 + /* zero out .ibss */ + mov.l .iedata_k,r0 + mov.l .iend_k,r1 + bra .iedatastart mov #0,r2 -edata_l: /* backwards is faster and shorter */ +.iedataloop: /* backwards is faster and shorter */ mov.l r2,@-r1 +.iedatastart: cmp/hi r0,r1 - bt edata_l + bt .iedataloop /* copy the .iram section */ - mov.l iramcopy_k,r0 - mov.l iram_k,r1 - mov.l iramend_k,r2 -iramcopy_l: + mov.l .iramcopy_k,r0 + mov.l .iram_k,r1 + mov.l .iramend_k,r2 + /* Note: We cannot put a PC relative load into the delay slot of a 'bra' + instruction (the offset would be wrong), but there is nothing else to + do before the loop, so the delay slot would be 'nop'. The cmp / bf + sequence is the same length, but more efficient. */ + cmp/hi r1,r2 + bf .noiramcopy +.iramloop: mov.l @r0+,r3 mov.l r3,@r1 add #4,r1 cmp/hi r1,r2 - bt iramcopy_l + bt .iramloop +.noiramcopy: + + /* zero out bss */ + mov.l .edata_k,r0 + mov.l .end_k,r1 + bra .edatastart + mov #0,r2 +.edataloop: /* backwards is faster and shorter */ + mov.l r2,@-r1 +.edatastart: + cmp/hi r0,r1 + bt .edataloop /* copy the .data section, for rombased execution */ - mov.l datacopy_k,r0 - mov.l data_k,r1 - mov.l dataend_k,r2 - /* Don't copy if src and dest are equal */ + mov.l .datacopy_k,r0 + mov.l .data_k,r1 cmp/eq r0,r1 - bt nodatacopy -data_l: + bt .nodatacopy /* Don't copy if src and dest are equal */ + mov.l .dataend_k,r2 + cmp/hi r1,r2 + bf .nodatacopy +.dataloop: mov.l @r0+,r3 mov.l r3,@r1 add #4,r1 cmp/hi r1,r2 - bt data_l -nodatacopy: + bt .dataloop +.nodatacopy: /* Munge the main thread stack */ - mov.l stackbegin_k,r0 - mov.l stackend_k,r1 - mov.l deadbeef_k,r2 -munge_l: /* backwards is faster and shorter */ + mov.l .stackbegin_k,r0 + mov.l .stackend_k,r1 + mov r1,r15 + mov.l .deadbeef_k,r2 +.mungeloop: /* backwards is faster and shorter */ mov.l r2,@-r1 cmp/hi r0,r1 - bt munge_l - - mov #0,r0 - ldc r0,gbr + bt .mungeloop - ! call the mainline - mov.l main_k,r0 + /* call the mainline */ + mov.l .main_k,r0 jsr @r0 nop .hoo: @@ -443,36 +481,40 @@ munge_l: /* backwards is faster and shorter */ nop .align 2 -stackend_k: - .long _stackend -stackbegin_k: - .long _stackbegin -deadbeef_k: - .long 0xdeadbeef -edata_k: - .long _edata -end_k: - .long _end -iramcopy_k: +.vbr_k: + .long vectors +#ifdef DEBUG +.orig_vbr_k: + .long 0x09000000 +#endif +.iedata_k: + .long _iedata +.iend_k: + .long _iend +.iramcopy_k: .long _iramcopy -iram_k: +.iram_k: .long _iramstart -iramend_k: +.iramend_k: .long _iramend -datacopy_k: +.edata_k: + .long _edata +.end_k: + .long _end +.datacopy_k: .long _datacopy -data_k: +.data_k: .long _datastart -dataend_k: +.dataend_k: .long _dataend -main_k: +.stackbegin_k: + .long _stackbegin +.stackend_k: + .long _stackend +.deadbeef_k: + .long 0xdeadbeef +.main_k: .long _main -vbr_k: - .long vectors -#ifdef DEBUG -orig_vbr_k: - .long 0x9000000 -#endif .section .resetvectors vectors: diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c index bde2b16b26..afd0377914 100644 --- a/firmware/drivers/lcd-h100-remote.c +++ b/firmware/drivers/lcd-h100-remote.c @@ -67,7 +67,7 @@ /*** globals ***/ unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH] - IDATA_ATTR; + IBSS_ATTR; static int drawmode = DRMODE_SOLID; static int xmargin = 0; diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c index edc6e2e33b..001c3849dd 100644 --- a/firmware/drivers/lcd-h100.c +++ b/firmware/drivers/lcd-h100.c @@ -61,10 +61,9 @@ /*** globals ***/ -unsigned char lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH] IDATA_ATTR; +unsigned char lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH] IBSS_ATTR; -/* should be 'const', but this causes a section type conflict */ -static unsigned char dibits[16] IDATA_ATTR = { +static const unsigned char dibits[16] ICONST_ATTR = { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF }; diff --git a/firmware/export/config.h b/firmware/export/config.h index 966f47cb5a..66f53eb0ed 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -139,11 +139,15 @@ (CONFIG_CPU == MCF5249) || /* Coldfire: core, plugins, codecs */ \ (CONFIG_CPU == TCC730)) /* CalmRISC16: core, (plugins, codecs) */ #define ICODE_ATTR __attribute__ ((section(".icode"))) +#define ICONST_ATTR __attribute__ ((section(".irodata"))) #define IDATA_ATTR __attribute__ ((section(".idata"))) +#define IBSS_ATTR __attribute__ ((section(".ibss"))) #define USE_IRAM #else #define ICODE_ATTR +#define ICONST_ATTR #define IDATA_ATTR +#define IBSS_ATTR #endif #endif diff --git a/firmware/rom.lds b/firmware/rom.lds index 8781873f45..7e178ae2b2 100644 --- a/firmware/rom.lds +++ b/firmware/rom.lds @@ -90,10 +90,19 @@ SECTIONS { _iramstart = .; *(.icode) + *(.irodata) *(.idata) _iramend = .; } > IRAM + .ibss (NOLOAD) : + { + _iedata = .; + *(.ibss) + . = ALIGN(0x4); + _iend = .; + } > IRAM + .stack : { *(.stack) diff --git a/firmware/thread.c b/firmware/thread.c index 5bbea31d53..7ee4072895 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -57,7 +57,7 @@ struct regs int num_threads; static volatile int num_sleepers; static int current_thread; -static struct regs thread_contexts[MAXTHREADS] __attribute__ ((section(".idata"))); +static struct regs thread_contexts[MAXTHREADS] IBSS_ATTR; const char *thread_name[MAXTHREADS]; void *thread_stack[MAXTHREADS]; int thread_stack_size[MAXTHREADS]; @@ -66,7 +66,7 @@ static const char main_thread_name[] = "main"; extern int stackbegin[]; extern int stackend[]; -void switch_thread(void) __attribute__ ((section(".icode"))); +void switch_thread(void) ICODE_ATTR; static inline void store_context(void* addr) __attribute__ ((always_inline)); static inline void load_context(const void* addr) __attribute__ ((always_inline)); |