diff options
author | Karl Kurbjun <kkurbjun@gmail.com> | 2011-02-06 20:10:45 +0000 |
---|---|---|
committer | Karl Kurbjun <kkurbjun@gmail.com> | 2011-02-06 20:10:45 +0000 |
commit | 924121005083bf6f07f877dfc6eb6c0e2908316d (patch) | |
tree | dfe3b9140965dca6c0b2adfc71a46dcad693bc98 | |
parent | 02dbde70970b002f1a77583a496c1d669e6c0537 (diff) | |
download | rockbox-924121005083bf6f07f877dfc6eb6c0e2908316d.tar.gz rockbox-924121005083bf6f07f877dfc6eb6c0e2908316d.zip |
DM320: Re-write of crt0.S and update to app linker script.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29224 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/target/arm/tms320dm320/app.lds | 164 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/crt0.S | 409 |
2 files changed, 392 insertions, 181 deletions
diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds index 3a9c01708a..ab871bb9c5 100644 --- a/firmware/target/arm/tms320dm320/app.lds +++ b/firmware/target/arm/tms320dm320/app.lds | |||
@@ -1,6 +1,6 @@ | |||
1 | #include "config.h" | 1 | #include "config.h" |
2 | 2 | ||
3 | ENTRY(start) | 3 | ENTRY(_start) |
4 | 4 | ||
5 | OUTPUT_FORMAT(elf32-littlearm) | 5 | OUTPUT_FORMAT(elf32-littlearm) |
6 | OUTPUT_ARCH(arm) | 6 | OUTPUT_ARCH(arm) |
@@ -16,7 +16,7 @@ STARTUP(target/arm/tms320dm320/crt0.o) | |||
16 | 16 | ||
17 | #define LCD_FUDGE LCD_NATIVE_WIDTH%32 | 17 | #define LCD_FUDGE LCD_NATIVE_WIDTH%32 |
18 | 18 | ||
19 | #define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2) | 19 | #define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2) |
20 | 20 | ||
21 | /* must be 16Kb (0x4000) aligned */ | 21 | /* must be 16Kb (0x4000) aligned */ |
22 | #define TTB_SIZE 0x4000 | 22 | #define TTB_SIZE 0x4000 |
@@ -30,112 +30,144 @@ STARTUP(target/arm/tms320dm320/crt0.o) | |||
30 | #define DRAMSIZE (MEMORYSIZE * 0x100000) | 30 | #define DRAMSIZE (MEMORYSIZE * 0x100000) |
31 | 31 | ||
32 | #define DRAMORIG 0x00900000 | 32 | #define DRAMORIG 0x00900000 |
33 | #define IRAMORIG 0x00000000 | 33 | |
34 | #define IRAMSIZE 0x4000 | 34 | #define FLASHORIG 0x00100000 |
35 | #define FLASHSIZE 0x00800000 | ||
36 | |||
37 | #define ITCMORIG 0x00000000 | ||
38 | #define ITCMSIZE 0x4000 | ||
39 | |||
40 | #define DTCMORIG 0x00020000 | ||
41 | #define DTCMSIZE 0x4000 | ||
42 | |||
43 | PRO_STACK_SIZE = 0x2000; | ||
44 | IRQ_STACK_SIZE = 0x600; | ||
45 | FIQ_STACK_SIZE = 0x400; | ||
35 | 46 | ||
36 | /* End of the audio buffer, where the codec buffer starts */ | 47 | /* End of the audio buffer, where the codec buffer starts */ |
37 | #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA) | 48 | #define ENDAUDIOADDR \ |
49 | (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA) | ||
38 | 50 | ||
39 | MEMORY | 51 | MEMORY |
40 | { | 52 | { |
41 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE | 53 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE |
42 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE | 54 | ITCM : ORIGIN = ITCMORIG, LENGTH = ITCMSIZE |
55 | DTCM : ORIGIN = DTCMORIG, LENGTH = DTCMSIZE | ||
43 | } | 56 | } |
44 | 57 | ||
45 | SECTIONS | 58 | SECTIONS |
46 | { | 59 | { |
47 | .text : | 60 | /* Set up variables needed for memory initialization */ |
61 | _sdram_start = DRAMORIG; | ||
62 | _sdram_sizem = ((_endsdram - _sdram_start) / 0x100000); | ||
63 | |||
64 | _flash_start = FLASHORIG; | ||
65 | _flash_sizem = (FLASHSIZE / 0x100000); | ||
66 | |||
67 | /* crt0.S initialization */ | ||
68 | .init : | ||
48 | { | 69 | { |
70 | . = ALIGN(0x4); | ||
49 | loadaddress = .; | 71 | loadaddress = .; |
50 | _loadaddress = .; | 72 | *(.init) |
51 | *(.init.text) | 73 | } > DRAM |
52 | *(.text*) | 74 | |
53 | *(.glue_7) | 75 | .vectors ITCMORIG : |
54 | *(.glue_7t) | 76 | { |
55 | . = ALIGN(0x4); | 77 | . = ALIGN(0x4); |
78 | _vectorsstart = .; | ||
79 | *(.vectors); | ||
80 | _vectorsend = .; | ||
81 | } > ITCM AT> DRAM | ||
82 | |||
83 | _vectorscopy = LOADADDR(.vectors); | ||
84 | |||
85 | .text : | ||
86 | { | ||
87 | . = ALIGN(0x4); | ||
88 | *(.text*) | ||
89 | } > DRAM | ||
90 | |||
91 | /* Thumb interworking sections - for some reason LD dies even if these | ||
92 | * sections are empty. | ||
93 | */ | ||
94 | .glue : | ||
95 | { | ||
96 | . = ALIGN(0x4); | ||
97 | *(.glue_7) /* ARM calling Thumb */ | ||
98 | *(.glue_7t) /* Thumb calling ARM */ | ||
56 | } > DRAM | 99 | } > DRAM |
57 | 100 | ||
58 | .rodata : | 101 | .rodata : |
59 | { | 102 | { |
60 | *(.rodata) /* problems without this, dunno why */ | ||
61 | *(.rodata*) | ||
62 | . = ALIGN(0x4); | 103 | . = ALIGN(0x4); |
104 | *(.rodata*) | ||
63 | } > DRAM | 105 | } > DRAM |
64 | 106 | ||
65 | .data : | 107 | .data : |
66 | { | 108 | { |
67 | *(.data*) | ||
68 | . = ALIGN(0x4); | 109 | . = ALIGN(0x4); |
110 | *(.data*) | ||
69 | } > DRAM | 111 | } > DRAM |
70 | 112 | ||
71 | /DISCARD/ : | 113 | .bss (NOLOAD) : |
72 | { | ||
73 | *(.eh_frame) | ||
74 | } | ||
75 | |||
76 | .vectors IRAMORIG : | ||
77 | { | 114 | { |
78 | _vectorsstart = .; | 115 | . = ALIGN(0x4); |
79 | *(.vectors); | 116 | _bss_start = .; |
80 | _vectorsend = .; | 117 | *(.bss*) |
81 | } > IRAM AT> DRAM | 118 | *(COMMON) |
82 | 119 | _bss_end = .; | |
83 | _vectorscopy = LOADADDR(.vectors); | 120 | } > DRAM |
84 | 121 | ||
85 | .iram : | 122 | .iram : |
86 | { | 123 | { |
124 | . = ALIGN(0x4); | ||
87 | _iramstart = .; | 125 | _iramstart = .; |
88 | *(.icode) | 126 | *(.icode) |
89 | *(.irodata*) | 127 | *(.irodata) |
90 | *(.idata) | 128 | *(.idata) |
91 | . = ALIGN(0x4); | ||
92 | _iramend = .; | 129 | _iramend = .; |
93 | } > IRAM AT> DRAM | 130 | } > ITCM AT> DRAM |
94 | 131 | ||
95 | _iramcopy = LOADADDR(.iram); | 132 | _iramcopy = LOADADDR(.iram); |
96 | 133 | ||
97 | .ibss (NOLOAD) : | 134 | .ibss DTCMORIG + _iramend (NOLOAD) : |
98 | { | 135 | { |
99 | _iedata = .; | ||
100 | *(.ibss) | ||
101 | . = ALIGN(0x4); | 136 | . = ALIGN(0x4); |
102 | _iend = .; | 137 | _ibss_start = .; |
103 | } > IRAM | 138 | *(.ibss) |
139 | _ibss_end = .; | ||
140 | } > DTCM | ||
104 | 141 | ||
105 | .stack (NOLOAD) : | 142 | /* Program stack space */ |
143 | .pro_stack (NOLOAD): | ||
106 | { | 144 | { |
107 | *(.stack) | 145 | . = ALIGN(0x4); |
108 | stackbegin = .; | 146 | *(.stack) |
109 | . += 0x2000; | 147 | stackbegin = .; /* Variable for thread.c */ |
110 | stackend = .; | 148 | _pro_stack_end = .; |
111 | } > IRAM | 149 | . += PRO_STACK_SIZE; |
150 | _pro_stack_start = .; | ||
151 | stackend = .; /* Variable for tread.c */ | ||
152 | } > DTCM | ||
112 | 153 | ||
113 | .irqstack (NOLOAD) : | 154 | /* IRQ stack space */ |
155 | .irq_stack (NOLOAD): | ||
114 | { | 156 | { |
115 | *(.stack) | 157 | . = ALIGN(0x4); |
116 | . += 0x400; | 158 | _irq_stack_end = .; |
117 | irq_stack = .; | 159 | . += IRQ_STACK_SIZE; |
118 | } > IRAM | 160 | _irq_stack_start = .; |
119 | 161 | } > DTCM | |
120 | .fiqstack (NOLOAD) : | 162 | |
121 | { | 163 | /* FIQ stack space */ |
122 | *(.stack) | 164 | .fiq_stack (NOLOAD): |
123 | . += 0x400; | ||
124 | fiq_stack = .; | ||
125 | } > IRAM | ||
126 | |||
127 | /* This overwrites the iram (in ram), so make sure that the iram is copied | ||
128 | * out in crt0.s before the bss section and the rest are used. | ||
129 | */ | ||
130 | .bss (NOLOAD) : | ||
131 | { | 165 | { |
132 | . = ADDR(.data) + SIZEOF(.data); | ||
133 | _edata = .; | ||
134 | *(.bss*) | ||
135 | *(COMMON) | ||
136 | . = ALIGN(0x4); | 166 | . = ALIGN(0x4); |
137 | _end = .; | 167 | _fiq_stack_end = .; |
138 | } > DRAM | 168 | . += FIQ_STACK_SIZE; |
169 | _fiq_stack_start = .; | ||
170 | } > DTCM | ||
139 | 171 | ||
140 | .audiobuf (NOLOAD) : | 172 | .audiobuf (NOLOAD) : |
141 | { | 173 | { |
@@ -160,6 +192,8 @@ SECTIONS | |||
160 | . += PLUGIN_BUFFER_SIZE; | 192 | . += PLUGIN_BUFFER_SIZE; |
161 | } > DRAM | 193 | } > DRAM |
162 | 194 | ||
195 | _endsdram = .; | ||
196 | |||
163 | .ttbtable (NOLOAD) : | 197 | .ttbtable (NOLOAD) : |
164 | { | 198 | { |
165 | . = ALIGN (0x4000); | 199 | . = ALIGN (0x4000); |
diff --git a/firmware/target/arm/tms320dm320/crt0.S b/firmware/target/arm/tms320dm320/crt0.S index 440897d67f..69bc8b1622 100644 --- a/firmware/target/arm/tms320dm320/crt0.S +++ b/firmware/target/arm/tms320dm320/crt0.S | |||
@@ -7,12 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | 10 | * Copyright (C) 2010 by Karl Kurbjun |
11 | * | ||
12 | * Arm bootloader and startup code based on startup.s from the iPodLinux loader | ||
13 | * | ||
14 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) | ||
15 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> | ||
16 | * | 11 | * |
17 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
18 | * modify it under the terms of the GNU General Public License | 13 | * modify it under the terms of the GNU General Public License |
@@ -26,25 +21,83 @@ | |||
26 | #include "config.h" | 21 | #include "config.h" |
27 | #include "cpu.h" | 22 | #include "cpu.h" |
28 | 23 | ||
29 | .section .init.text,"ax",%progbits | 24 | #define CACHE_NONE 0 |
25 | #define CACHE_ALL 0x0C | ||
26 | #define BUFFERED 0x04 | ||
30 | 27 | ||
31 | .global start | 28 | #define LONG_VECTORS 1 |
32 | start: | ||
33 | msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ | ||
34 | 29 | ||
35 | #ifndef CREATIVE_ZVx | 30 | /****************************************************************************** |
36 | /* Copy exception handler code to address 0 */ | 31 | * vectors: * |
37 | ldr r2, =_vectorsstart | 32 | * This is the ARM vector table * |
38 | ldr r3, =_vectorsend | 33 | * Long call exception handlers are used for simplicity between flash * |
39 | ldr r4, =_vectorscopy | 34 | * bootloader and SDRAM main-application. These need to be copied to address * |
40 | 1: | 35 | * 0x0 at start. * |
41 | cmp r3, r2 | 36 | ******************************************************************************/ |
42 | ldrhi r5, [r4], #4 | 37 | .section .vectors,"ax" |
43 | strhi r5, [r2], #4 | 38 | .code 32 |
44 | bhi 1b | 39 | |
40 | .global _vectors | ||
41 | @entry: | ||
42 | _vectors: | ||
43 | |||
44 | #if defined(SHORT_VECTORS) /* Use relative branch vectors (64 MB limit) */ | ||
45 | b _start /* Reset Vector */ | ||
46 | b _undefined_instruction /* Undefined instruction */ | ||
47 | b _software_interrupt /* Software Vector */ | ||
48 | b _prefetch_abort /* Prefetch Abort */ | ||
49 | b _data_abort /* Data Abort */ | ||
50 | b _dead_loop /* Reserved/Unused */ | ||
51 | b irq_handler /* IRQ vector */ | ||
52 | b fiq_handler /* FIQ vector */ | ||
53 | #else | ||
54 | #if defined(LONG_VECTORS) | ||
55 | /* Load the PC with the word values stored below */ | ||
56 | ldr pc, [pc, #0x18] /* Reset */ | ||
57 | ldr pc, [pc, #0x18] /* Undefined instruction */ | ||
58 | ldr pc, [pc, #0x18] /* Software interrupt */ | ||
59 | ldr pc, [pc, #0x18] /* Prefetch Abort */ | ||
60 | ldr pc, [pc, #0x18] /* Data Abort */ | ||
61 | ldr pc, [pc, #0x18] /* Reserved/Unused */ | ||
62 | ldr pc, [pc, #0x18] /* IRQ */ | ||
63 | ldr pc, [pc, #0x18] /* FIQ */ | ||
64 | |||
65 | /* Addresses of the handlers */ | ||
66 | .word _start | ||
67 | .word _undefined_instruction | ||
68 | .word _software_interrupt | ||
69 | .word _prefetch_abort | ||
70 | .word _data_abort | ||
71 | .word _dead_loop | ||
72 | .word irq_handler | ||
73 | .word fiq_handler | ||
74 | #else | ||
75 | #error Vector type undefined | ||
76 | #endif | ||
45 | #endif | 77 | #endif |
46 | 78 | ||
47 | /* Disable data and instruction cache, high vectors (at 0xffff0000 instead of 0x00000000) */ | 79 | /****************************************************************************** |
80 | * _start: * | ||
81 | * This is the main entry point to the program * | ||
82 | ******************************************************************************/ | ||
83 | .section .init, "ax" | ||
84 | .code 32 | ||
85 | .align 0x04 | ||
86 | .global _start | ||
87 | _start: | ||
88 | /* Go into supervisor state with IRQ's disabled. | ||
89 | * This register is described in section "A2.5 Program status registers" | ||
90 | * of the "ARM Architecture Reference Manual". | ||
91 | */ | ||
92 | msr cpsr, #0xd3 | ||
93 | |||
94 | /* Disable all the fancy stuff */ | ||
95 | mov r0, #0 | ||
96 | mcr p15, 0, r0, c1, c0, 0 | ||
97 | |||
98 | /* Disable data and instruction cache, high vectors (at 0xffff0000 instead | ||
99 | * of 0x00000000) | ||
100 | */ | ||
48 | mrc p15, 0, r0, c1, c0, 0 | 101 | mrc p15, 0, r0, c1, c0, 0 |
49 | /* clear bits 13, 9:8 (--VI --RS) */ | 102 | /* clear bits 13, 9:8 (--VI --RS) */ |
50 | bic r0, r0, #0x00003300 | 103 | bic r0, r0, #0x00003300 |
@@ -54,112 +107,236 @@ start: | |||
54 | orr r0, r0, #0x00000002 | 107 | orr r0, r0, #0x00000002 |
55 | mcr p15, 0, r0, c1, c0, 0 | 108 | mcr p15, 0, r0, c1, c0, 0 |
56 | 109 | ||
57 | #if !defined(STUB) | 110 | /* Add a few cycles of delay before continuing due to system requirements */ |
58 | /* Zero out IBSS */ | 111 | mov r0, #0x20 |
59 | ldr r2, =_iedata | 112 | bl _delay_cycles |
60 | ldr r3, =_iend | 113 | |
61 | mov r4, #0 | 114 | #if defined(BOOTLOADER) |
62 | 1: | 115 | bl _init_board |
63 | cmp r3, r2 | 116 | #endif |
64 | strhi r4, [r2], #4 | 117 | |
65 | bhi 1b | 118 | /* Copy exception handler code to address 0 */ |
66 | 119 | ldr r0, =_vectorscopy | |
67 | #ifndef CREATIVE_ZVx | 120 | ldr r1, =_vectorsstart |
68 | /* Copy the IRAM */ | 121 | ldr r2, =_vectorsend |
69 | ldr r2, =_iramcopy | 122 | bl _copy_section |
70 | ldr r3, =_iramstart | 123 | |
71 | ldr r4, =_iramend | 124 | /* Add some delay time to make sure JTAG can be accessed cleanly */ |
72 | 1: | 125 | mov r0, #0x100000 |
73 | cmp r4, r3 | 126 | bl _delay_cycles |
74 | ldrhi r5, [r2], #4 | 127 | |
75 | strhi r5, [r3], #4 | 128 | #if defined(BOOTLOADER) |
76 | bhi 1b | 129 | /* Copy the DRAM */ |
130 | ldr r0, =_dramcopy | ||
131 | ldr r1, =_dramstart | ||
132 | ldr r2, =_dramend | ||
133 | bl _copy_section | ||
77 | #endif | 134 | #endif |
78 | #endif /* !STUB */ | 135 | |
79 | 136 | /* Zero out the IBSS */ | |
80 | 137 | mov r0, #0 | |
81 | /* Initialise bss section to zero */ | 138 | ldr r1, =_ibss_start |
82 | ldr r2, =_edata | 139 | ldr r2, =_ibss_end |
83 | ldr r3, =_end | 140 | bl _init_section |
84 | mov r4, #0 | 141 | |
85 | bsszero: | 142 | /* Copy the IRAM */ |
86 | cmp r3, r2 | 143 | ldr r0, =_iramcopy |
87 | strhi r4, [r2], #4 | 144 | ldr r1, =_iramstart |
88 | bhi bsszero | 145 | ldr r2, =_iramend |
89 | 146 | bl _copy_section | |
90 | /* Set up some stack and munge it with 0xdeadbeef */ | 147 | |
91 | ldr sp, =stackend | 148 | /* Zero out the BSS */ |
92 | mov r3, sp | 149 | mov r0, #0 |
93 | ldr r2, =stackbegin | 150 | ldr r1, =_bss_start |
94 | ldr r4, =0xdeadbeef | 151 | ldr r2, =_bss_end |
95 | stackmunge: | 152 | bl _init_section |
96 | cmp r3, r2 | 153 | |
97 | strhi r4, [r2], #4 | 154 | /* Initialize fiq stack */ |
98 | bhi stackmunge | 155 | ldr r0, =0xDEADBEEF |
99 | 156 | ldr r1, =_fiq_stack_end /* Stack counts backwards, so end is first*/ | |
100 | /* Set up stack for IRQ mode */ | 157 | ldr r2, =_fiq_stack_start |
101 | msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */ | 158 | bl _init_section |
102 | ldr sp, =irq_stack | 159 | |
103 | /* Set up stack for FIQ mode */ | 160 | msr cpsr_c, #0xd1 /* Go into fiq state */ |
104 | msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */ | 161 | ldr sp, =_fiq_stack_start /* set the fiq stack pointer */ |
105 | ldr sp, =fiq_stack | 162 | |
106 | 163 | /* Initialize irq stack */ | |
107 | /* Let abort and undefined modes use IRQ stack */ | 164 | ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */ |
108 | msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */ | 165 | ldr r1, =_irq_stack_end /* Stack counts backwards, so end is first*/ |
109 | ldr sp, =irq_stack | 166 | ldr r2, =_irq_stack_start |
110 | msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ | 167 | bl _init_section |
111 | ldr sp, =irq_stack | 168 | |
112 | 169 | msr cpsr_c, #0xd2 /* Go into irq state */ | |
113 | /* Switch to supervisor mode (no IRQ) */ | 170 | ldr sp, =_irq_stack_start /* set the irq stack pointer */ |
114 | msr cpsr_c, #0xd3 | 171 | |
115 | ldr sp, =stackend | 172 | /* This should not be needed, but set the stack location for abort and |
116 | 173 | * undefined to at least a known stack location (IRQ) | |
117 | start_loc: | 174 | */ |
118 | bl main | 175 | msr cpsr_c, #0xd7 /* Go into abort state */ |
119 | /* main() should never return */ | 176 | ldr sp, =_irq_stack_start /* set the stack pointer */ |
120 | 177 | ||
121 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | 178 | msr cpsr_c, #0xdb /* Go into undefined state */ |
122 | .section .vectors,"aw" | 179 | ldr sp, =_irq_stack_start /* set the stack pointer */ |
123 | b start | 180 | |
124 | b undef_instr_handler | 181 | /* Initialize program stack */ |
125 | b software_int_handler | 182 | msr cpsr_c, #0xd3 /* Go into supervisor state */ |
126 | b prefetch_abort_handler | 183 | ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */ |
127 | b data_abort_handler | 184 | ldr r1, =_pro_stack_end /* Stack counts backwards, so end is first*/ |
128 | b reserved_handler | 185 | ldr r2, =_pro_stack_start |
129 | b irq_handler | 186 | bl _init_section |
130 | b fiq_handler | 187 | |
131 | 188 | ldr sp, =_pro_stack_start /* set the supervisor stack pointer */ | |
132 | .text | 189 | |
133 | 190 | /* MMU initialization */ | |
134 | /* All illegal exceptions call into UIE with exception address as first | 191 | bl ttb_init |
135 | parameter. This is calculated differently depending on which exception | 192 | |
136 | we're in. Second parameter is exception number, used for a string lookup | 193 | /* Make sure everything is mapped on itself */ |
137 | in UIE. | 194 | ldr r0, =0x0 |
195 | ldr r1, =0x0 | ||
196 | ldr r2, =0x1000 | ||
197 | mov r3, #CACHE_NONE | ||
198 | bl map_section | ||
199 | |||
200 | /* Enable caching for FLASH */ | ||
201 | ldr r0, =_flash_start | ||
202 | ldr r1, =_flash_start | ||
203 | ldr r2, =_flash_sizem | ||
204 | mov r3, #CACHE_ALL | ||
205 | bl map_section | ||
206 | |||
207 | /* Enable caching for RAM */ | ||
208 | ldr r0, =_sdram_start | ||
209 | ldr r1, =_sdram_start | ||
210 | ldr r2, =_sdram_sizem | ||
211 | mov r3, #CACHE_ALL | ||
212 | bl map_section | ||
213 | |||
214 | bl enable_mmu | ||
215 | |||
216 | /* Initial setup is complete, go into main */ | ||
217 | ldr pc, =main | ||
218 | |||
219 | /* If main returns go into an infinite loop */ | ||
220 | b _dead_loop | ||
221 | |||
222 | /* Constants go here (from _start - .ltorg): */ | ||
223 | .ltorg | ||
224 | |||
225 | /****************************************************************************** | ||
226 | * _init_section: * | ||
227 | * This function initializes a section with the 32-bit value specified. * | ||
228 | ******************************************************************************/ | ||
229 | .section .init, "ax" | ||
230 | .code 32 | ||
231 | .align 0x04 | ||
232 | .global _init_section | ||
233 | .type _init_section, %function | ||
234 | /* r0 = init value | ||
235 | * r1 = start location | ||
236 | * r2 = end location | ||
237 | */ | ||
238 | |||
239 | /* This function will not run if end is less than or equal to start */ | ||
240 | _init_section: | ||
241 | cmp r2, r1 | ||
242 | strhi r0, [r1], #4 /* store and increment start location */ | ||
243 | bhi _init_section | ||
244 | bx lr | ||
245 | .ltorg | ||
246 | .size _init_section, .-_init_section | ||
247 | |||
248 | /****************************************************************************** | ||
249 | * _copy_section: * | ||
250 | * This function copies a section to a new location * | ||
251 | ******************************************************************************/ | ||
252 | .section .init, "ax" | ||
253 | .code 32 | ||
254 | .align 0x04 | ||
255 | .global _copy_section | ||
256 | .type _copy_section, %function | ||
257 | /* r0 = source address | ||
258 | * r1 = destination start address | ||
259 | * r2 = destination end address | ||
260 | * | ||
261 | * r3 is a scratch register | ||
138 | */ | 262 | */ |
139 | undef_instr_handler: | 263 | |
264 | _copy_section: | ||
265 | cmp r2, r1 | ||
266 | ldrhi r3, [r0], #4 | ||
267 | strhi r3, [r1], #4 | ||
268 | bhi _copy_section | ||
269 | bx lr | ||
270 | .ltorg | ||
271 | .size _copy_section, .-_copy_section | ||
272 | |||
273 | /****************************************************************************** | ||
274 | * _delay_cycles: * | ||
275 | * This function delays for the specified number of cycles * | ||
276 | ******************************************************************************/ | ||
277 | .section .init, "ax" | ||
278 | .code 32 | ||
279 | .align 0x04 | ||
280 | .global _delay_cycles | ||
281 | .type _delay_cycles, %function | ||
282 | /* r0 = number of cycles to delay */ | ||
283 | |||
284 | /* If r0 is zero it will be the maximum length delay */ | ||
285 | _delay_cycles: | ||
286 | subs r0, r0, #1 | ||
287 | bne _delay_cycles | ||
288 | bx lr | ||
289 | .ltorg | ||
290 | .size _delay_cycles, .-_delay_cycles | ||
291 | |||
292 | /****************************************************************************** | ||
293 | * Unused exception vectors. These call the UIE function. * | ||
294 | * Arguements are: * | ||
295 | * r0: PC of exception * | ||
296 | * r1: Exception number. * | ||
297 | * Exception numbers are as defined: * | ||
298 | * 0: Undefined Instruction * | ||
299 | * 1: Prefetch Abort * | ||
300 | * 2: Data Abort * | ||
301 | * The exceptions return operations are documented in section A2.6 of the * | ||
302 | * ARM Architecture Reference Manual. * | ||
303 | ******************************************************************************/ | ||
304 | |||
305 | /* A2.6.3: Undefined Instruction Exception - LR=PC of next instruction */ | ||
306 | _undefined_instruction: | ||
140 | sub r0, lr, #4 | 307 | sub r0, lr, #4 |
141 | mov r1, #0 | 308 | mov r1, #0 |
142 | b UIE | 309 | bl UIE |
143 | 310 | ||
144 | /* We run supervisor mode most of the time, and should never see a software | 311 | /* A2.6.4: Software Interrupt exception - These should not happen in Rockbox, |
145 | exception being thrown. Perhaps make it illegal and call UIE? | 312 | * but for now leave this as a placeholder and continue with the program. |
313 | * LR=PC of next instruction. | ||
146 | */ | 314 | */ |
147 | software_int_handler: | 315 | _software_interrupt: |
148 | reserved_handler: | 316 | mov pc, lr |
149 | movs pc, lr | ||
150 | 317 | ||
151 | prefetch_abort_handler: | 318 | /* A2.6.5 Prefetch Abort - This is also the BKPT instruction since this is a |
319 | * v5 target. Pass it on to UIE since it is not currently used. | ||
320 | */ | ||
321 | _prefetch_abort: | ||
152 | sub r0, lr, #4 | 322 | sub r0, lr, #4 |
153 | mov r1, #1 | 323 | mov r1, #1 |
154 | b UIE | 324 | bl UIE |
155 | 325 | ||
156 | data_abort_handler: | 326 | /* A2.6.6 Data Abort - There was a memory abort, can return after fixing cause |
327 | * with the LR address. | ||
328 | */ | ||
329 | _data_abort: | ||
157 | sub r0, lr, #8 | 330 | sub r0, lr, #8 |
158 | mov r1, #2 | 331 | mov r1, #2 |
159 | b UIE | 332 | bl UIE |
160 | 333 | ||
161 | #ifdef STUB | 334 | /****************************************************************************** |
162 | UIE: | 335 | * _dead_loop: Something really unexpected happened (like a reserved * |
163 | b UIE | 336 | * exception). Just hang. * |
164 | #endif | 337 | ******************************************************************************/ |
338 | _dead_loop: | ||
339 | b _dead_loop | ||
340 | |||
341 | .ltorg | ||
165 | 342 | ||