summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-10-19 19:35:24 +0000
committerJens Arnold <amiconn@rockbox.org>2005-10-19 19:35:24 +0000
commitabd9f83e92fae22dcb9806deae665b7b303f430d (patch)
tree8d0d1d65c6aaa596e171cda2d78706739046d0bd /firmware
parent266f173b72967bae96119e5428fabe692edd8c30 (diff)
downloadrockbox-abd9f83e92fae22dcb9806deae665b7b303f430d.tar.gz
rockbox-abd9f83e92fae22dcb9806deae665b7b303f430d.tar.bz2
rockbox-abd9f83e92fae22dcb9806deae665b7b303f430d.zip
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
Diffstat (limited to 'firmware')
-rw-r--r--firmware/app.lds9
-rw-r--r--firmware/boot.lds4
-rw-r--r--firmware/crt0.S162
-rw-r--r--firmware/drivers/lcd-h100-remote.c2
-rw-r--r--firmware/drivers/lcd-h100.c5
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/rom.lds9
-rw-r--r--firmware/thread.c4
8 files changed, 132 insertions, 67 deletions
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));