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
This commit is contained in:
Jens Arnold 2005-10-19 19:35:24 +00:00
parent 266f173b72
commit abd9f83e92
11 changed files with 164 additions and 97 deletions

View file

@ -130,9 +130,9 @@ struct dither_data
long random; long random;
}; };
static struct dsp_config dsp_conf[2] IDATA_ATTR; static struct dsp_config dsp_conf[2] IBSS_ATTR;
static struct dither_data dither_data[2] IDATA_ATTR; static struct dither_data dither_data[2] IBSS_ATTR;
static struct resample_data resample_data[2][2] IDATA_ATTR; static struct resample_data resample_data[2][2] IBSS_ATTR;
extern int current_codec; extern int current_codec;
struct dsp_config *dsp; struct dsp_config *dsp;
@ -142,8 +142,8 @@ struct dsp_config *dsp;
* of copying needed is minimized for that case. * of copying needed is minimized for that case.
*/ */
static long sample_buf[SAMPLE_BUF_SIZE] IDATA_ATTR; static long sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR;
static long resample_buf[RESAMPLE_BUF_SIZE] IDATA_ATTR; static long resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR;
/* Convert at most count samples to the internal format, if needed. Returns /* Convert at most count samples to the internal format, if needed. Returns

View file

@ -112,13 +112,13 @@ static const char audio_thread_name[] = "audio";
/* Codec thread. */ /* Codec thread. */
static struct event_queue codec_queue; 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"; static const char codec_thread_name[] = "codec";
/* Voice codec thread. */ /* Voice codec thread. */
static struct event_queue voice_codec_queue; static struct event_queue voice_codec_queue;
/* Not enough IRAM for this. */ /* 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 const char voice_codec_thread_name[] = "voice codec";
static struct mutex mutex_bufferfill; static struct mutex mutex_bufferfill;

View file

@ -80,7 +80,9 @@ SECTIONS
{ {
iramstart = .; iramstart = .;
*(.icode) *(.icode)
*(.irodata)
*(.idata) *(.idata)
*(.ibss)
iramend = .; iramend = .;
} > PLUGIN_IRAM } > PLUGIN_IRAM
#endif #endif

View file

@ -188,9 +188,18 @@ SECTIONS
{ {
_iramstart = .; _iramstart = .;
*(.icode) *(.icode)
*(.irodata)
*(.idata) *(.idata)
_iramend = .; _iramend = .;
} > IRAM } > IRAM
.ibss (NOLOAD) :
{
_iedata = .;
*(.ibss)
. = ALIGN(0x4);
_iend = .;
} > IRAM
#ifdef CPU_COLDFIRE #ifdef CPU_COLDFIRE
.stack : .stack :

View file

@ -51,9 +51,10 @@ SECTIONS
*(.resetvectors); *(.resetvectors);
*(.vectors); *(.vectors);
. = ALIGN(0x200); . = ALIGN(0x200);
*(.data)
*(.icode) *(.icode)
*(.irodata)
*(.idata) *(.idata)
*(.data)
. = ALIGN(0x4); . = ALIGN(0x4);
_dataend = .; _dataend = .;
. = ALIGN(0x10); /* Maintain proper alignment for .text section */ . = ALIGN(0x10); /* Maintain proper alignment for .text section */
@ -91,6 +92,7 @@ SECTIONS
.bss : .bss :
{ {
_edata = .; _edata = .;
*(.ibss)
*(.bss) *(.bss)
*(COMMON) *(COMMON)
_end = .; _end = .;

View file

@ -246,7 +246,7 @@ irq_handler:
move.l #0xffffffbf,%d0 move.l #0xffffffbf,%d0
and.l %d0,(0x108,%a0) /* Back to normal, the DRAM is now ready */ and.l %d0,(0x108,%a0) /* Back to normal, the DRAM is now ready */
#endif #endif /* BOOTLOADER */
/* Invalicate cache */ /* Invalicate cache */
move.l #0x01000000,%d0 move.l #0x01000000,%d0
@ -263,38 +263,57 @@ irq_handler:
movec.l %d0,%acr1 movec.l %d0,%acr1
#ifndef BOOTLOADER #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 _iramcopy,%a2
lea _iramstart,%a3 lea _iramstart,%a3
lea _iramend,%a4 lea _iramend,%a4
bra.b .iramstart
.iramloop: .iramloop:
move.l (%a2)+,(%a3)+ move.l (%a2)+,(%a3)+
.iramstart:
cmp.l %a3,%a4 cmp.l %a3,%a4
bhi.b .iramloop bhi.b .iramloop
#endif #endif /* !BOOTLOADER */
/* zero out bss */
lea _edata,%a2 lea _edata,%a2
lea _end,%a4 lea _end,%a4
bra.b .edatastart
.edataloop: .edataloop:
clr.l (%a2)+ clr.l (%a2)+
.edatastart:
cmp.l %a2,%a4 cmp.l %a2,%a4
bhi.b .edataloop bhi.b .edataloop
/* copy the .data section */
lea _datacopy,%a2 lea _datacopy,%a2
lea _datastart,%a3 lea _datastart,%a3
lea _dataend,%a4
cmp.l %a2,%a3 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: .dataloop:
move.l (%a2)+,(%a3)+ move.l (%a2)+,(%a3)+
.datastart:
cmp.l %a3,%a4 cmp.l %a3,%a4
bhi.b .dataloop bhi.b .dataloop
.nodatacopy: .nodatacopy:
/* Munge the main stack */ /* Munge the main stack */
move.l #0xdeadbeef,%d0
lea stackbegin,%a2 lea stackbegin,%a2
lea stackend,%a4 lea stackend,%a4
move.l %a4,%sp move.l %a4,%sp
move.l #0xdeadbeef,%d0
.mungeloop: .mungeloop:
move.l %d0,(%a2)+ move.l %d0,(%a2)+
cmp.l %a2,%a4 cmp.l %a2,%a4
@ -315,12 +334,12 @@ vectors:
#else #else
/* Platform: Archos Jukebox */ /* Platform: Archos Jukebox */
mov.l vbr_k,r1 mov.l .vbr_k,r1
#ifdef DEBUG #ifdef DEBUG
/* If we have built our code to be loaded via the standalone GDB /* 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. * 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. */ * 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) */ /* Move the invalid instruction vector (4) */
mov #4,r0 mov #4,r0
@ -384,58 +403,77 @@ vectors:
#endif /* DEBUG */ #endif /* DEBUG */
ldc r1,vbr ldc r1,vbr
/* Now let's get on with the normal business */
mov.l stackend_k,r15
/* zero out bss */
mov.l edata_k,r0
mov.l end_k,r1
mov #0,r2
edata_l: /* backwards is faster and shorter */
mov.l r2,@-r1
cmp/hi r0,r1
bt edata_l
/* copy the .iram section */
mov.l iramcopy_k,r0
mov.l iram_k,r1
mov.l iramend_k,r2
iramcopy_l:
mov.l @r0+,r3
mov.l r3,@r1
add #4,r1
cmp/hi r1,r2
bt iramcopy_l
/* 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 */
cmp/eq r0,r1
bt nodatacopy
data_l:
mov.l @r0+,r3
mov.l r3,@r1
add #4,r1
cmp/hi r1,r2
bt data_l
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 r2,@-r1
cmp/hi r0,r1
bt munge_l
mov #0,r0 mov #0,r0
ldc r0,gbr ldc r0,gbr
! call the mainline /* zero out .ibss */
mov.l main_k,r0 mov.l .iedata_k,r0
mov.l .iend_k,r1
bra .iedatastart
mov #0,r2
.iedataloop: /* backwards is faster and shorter */
mov.l r2,@-r1
.iedatastart:
cmp/hi r0,r1
bt .iedataloop
/* copy the .iram section */
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 .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
cmp/eq r0,r1
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 .dataloop
.nodatacopy:
/* Munge the main thread stack */
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 .mungeloop
/* call the mainline */
mov.l .main_k,r0
jsr @r0 jsr @r0
nop nop
.hoo: .hoo:
@ -443,36 +481,40 @@ munge_l: /* backwards is faster and shorter */
nop nop
.align 2 .align 2
stackend_k: .vbr_k:
.long _stackend
stackbegin_k:
.long _stackbegin
deadbeef_k:
.long 0xdeadbeef
edata_k:
.long _edata
end_k:
.long _end
iramcopy_k:
.long _iramcopy
iram_k:
.long _iramstart
iramend_k:
.long _iramend
datacopy_k:
.long _datacopy
data_k:
.long _datastart
dataend_k:
.long _dataend
main_k:
.long _main
vbr_k:
.long vectors .long vectors
#ifdef DEBUG #ifdef DEBUG
orig_vbr_k: .orig_vbr_k:
.long 0x9000000 .long 0x09000000
#endif #endif
.iedata_k:
.long _iedata
.iend_k:
.long _iend
.iramcopy_k:
.long _iramcopy
.iram_k:
.long _iramstart
.iramend_k:
.long _iramend
.edata_k:
.long _edata
.end_k:
.long _end
.datacopy_k:
.long _datacopy
.data_k:
.long _datastart
.dataend_k:
.long _dataend
.stackbegin_k:
.long _stackbegin
.stackend_k:
.long _stackend
.deadbeef_k:
.long 0xdeadbeef
.main_k:
.long _main
.section .resetvectors .section .resetvectors
vectors: vectors:

View file

@ -67,7 +67,7 @@
/*** globals ***/ /*** globals ***/
unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH] unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]
IDATA_ATTR; IBSS_ATTR;
static int drawmode = DRMODE_SOLID; static int drawmode = DRMODE_SOLID;
static int xmargin = 0; static int xmargin = 0;

View file

@ -61,10 +61,9 @@
/*** globals ***/ /*** 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 const unsigned char dibits[16] ICONST_ATTR = {
static unsigned char dibits[16] IDATA_ATTR = {
0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
}; };

View file

@ -139,11 +139,15 @@
(CONFIG_CPU == MCF5249) || /* Coldfire: core, plugins, codecs */ \ (CONFIG_CPU == MCF5249) || /* Coldfire: core, plugins, codecs */ \
(CONFIG_CPU == TCC730)) /* CalmRISC16: core, (plugins, codecs) */ (CONFIG_CPU == TCC730)) /* CalmRISC16: core, (plugins, codecs) */
#define ICODE_ATTR __attribute__ ((section(".icode"))) #define ICODE_ATTR __attribute__ ((section(".icode")))
#define ICONST_ATTR __attribute__ ((section(".irodata")))
#define IDATA_ATTR __attribute__ ((section(".idata"))) #define IDATA_ATTR __attribute__ ((section(".idata")))
#define IBSS_ATTR __attribute__ ((section(".ibss")))
#define USE_IRAM #define USE_IRAM
#else #else
#define ICODE_ATTR #define ICODE_ATTR
#define ICONST_ATTR
#define IDATA_ATTR #define IDATA_ATTR
#define IBSS_ATTR
#endif #endif
#endif #endif

View file

@ -90,10 +90,19 @@ SECTIONS
{ {
_iramstart = .; _iramstart = .;
*(.icode) *(.icode)
*(.irodata)
*(.idata) *(.idata)
_iramend = .; _iramend = .;
} > IRAM } > IRAM
.ibss (NOLOAD) :
{
_iedata = .;
*(.ibss)
. = ALIGN(0x4);
_iend = .;
} > IRAM
.stack : .stack :
{ {
*(.stack) *(.stack)

View file

@ -57,7 +57,7 @@ struct regs
int num_threads; int num_threads;
static volatile int num_sleepers; static volatile int num_sleepers;
static int current_thread; 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]; const char *thread_name[MAXTHREADS];
void *thread_stack[MAXTHREADS]; void *thread_stack[MAXTHREADS];
int thread_stack_size[MAXTHREADS]; int thread_stack_size[MAXTHREADS];
@ -66,7 +66,7 @@ static const char main_thread_name[] = "main";
extern int stackbegin[]; extern int stackbegin[];
extern int stackend[]; 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 store_context(void* addr) __attribute__ ((always_inline));
static inline void load_context(const void* addr) __attribute__ ((always_inline)); static inline void load_context(const void* addr) __attribute__ ((always_inline));