summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2008-04-22 04:34:25 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2008-04-22 04:34:25 +0000
commit7510335fc4fe25e1fe8ec80a33bd3f3f7442dd4c (patch)
tree4b542498d76a9550c9602b31eebae7fe8debda12
parent68afa9dc3438a03705544745654cd7f4d53d72c0 (diff)
downloadrockbox-7510335fc4fe25e1fe8ec80a33bd3f3f7442dd4c.tar.gz
rockbox-7510335fc4fe25e1fe8ec80a33bd3f3f7442dd4c.zip
This is a big chunk of code necessary to prepare for Gigabeat F flash loading and and implementation of rolo. There should be no noticible changes for the user. A new bootloader is not needed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17213 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/plugin.lds11
-rw-r--r--bootloader/gigabeat.c7
-rw-r--r--firmware/export/s3c2440.h12
-rw-r--r--firmware/target/arm/mmu-arm.c253
-rw-r--r--firmware/target/arm/mmu-arm.h14
-rw-r--r--firmware/target/arm/s3c2440/app.lds46
-rw-r--r--firmware/target/arm/s3c2440/boot.lds101
-rw-r--r--firmware/target/arm/s3c2440/crt0.S466
8 files changed, 562 insertions, 348 deletions
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds
index 8699ca1c25..4a0ad7326e 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -30,12 +30,9 @@ OUTPUT_FORMAT(elf32-sh)
30#define NOCACHE_BASE 0x00000000 30#define NOCACHE_BASE 0x00000000
31#endif 31#endif
32 32
33#if CONFIG_CPU==S3C2440 33#if CONFIG_CPU==DM320 || CONFIG_CPU==S3C2440
34#include "s3c2440.h" 34#include "cpu.h"
35#define DRAMSIZE (MEMORYSIZE * 0x100000) - 0x100 - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE 35#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE
36#elif CONFIG_CPU==DM320
37#include "dm320.h"
38#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE
39#elif CONFIG_CPU==IMX31L 36#elif CONFIG_CPU==IMX31L
40#include "imx31l.h" 37#include "imx31l.h"
41/* Reserve 1mb for LCD buffer/TTB as in app.lds */ 38/* Reserve 1mb for LCD buffer/TTB as in app.lds */
@@ -65,7 +62,7 @@ OUTPUT_FORMAT(elf32-sh)
65#define IRAMORIG 0x407000 62#define IRAMORIG 0x407000
66#define IRAMSIZE 0x9000 63#define IRAMSIZE 0x9000
67#elif CONFIG_CPU == S3C2440 64#elif CONFIG_CPU == S3C2440
68#define DRAMORIG 0x100 + STUBOFFSET 65#define DRAMORIG 0x0 + STUBOFFSET
69#define IRAMORIG DRAMORIG 66#define IRAMORIG DRAMORIG
70#define IRAMSIZE 4K 67#define IRAMSIZE 4K
71#define IRAM DRAM 68#define IRAM DRAM
diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c
index 8860b42c43..ac560afd64 100644
--- a/bootloader/gigabeat.c
+++ b/bootloader/gigabeat.c
@@ -54,7 +54,6 @@ void main(void)
54 int rc; 54 int rc;
55 int(*kernel_entry)(void); 55 int(*kernel_entry)(void);
56 56
57 memory_init();
58 power_init(); 57 power_init();
59 system_init(); 58 system_init();
60 lcd_init(); 59 lcd_init();
@@ -98,6 +97,8 @@ void main(void)
98 printf("Rockbox boot loader"); 97 printf("Rockbox boot loader");
99 printf("Version %s", version); 98 printf("Version %s", version);
100 99
100 sleep(50); /* ATA seems to error without this pause */
101
101 rc = ata_init(); 102 rc = ata_init();
102 if(rc) 103 if(rc)
103 { 104 {
@@ -115,8 +116,8 @@ void main(void)
115 116
116 printf("Loading firmware"); 117 printf("Loading firmware");
117 118
118 loadbuffer = (unsigned char*) 0x100; 119 loadbuffer = (unsigned char*) 0x31000000;
119 buffer_size = (unsigned char*)0x400000 - loadbuffer; 120 buffer_size = (unsigned char*)0x31400000 - loadbuffer;
120 121
121 rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); 122 rc = load_firmware(loadbuffer, BOOTFILE, buffer_size);
122 if(rc < 0) 123 if(rc < 0)
diff --git a/firmware/export/s3c2440.h b/firmware/export/s3c2440.h
index 0e802b5c0e..fae4f02203 100644
--- a/firmware/export/s3c2440.h
+++ b/firmware/export/s3c2440.h
@@ -19,6 +19,12 @@
19#ifndef __S3C2440_H__ 19#ifndef __S3C2440_H__
20#define __S3C2440_H__ 20#define __S3C2440_H__
21 21
22#define LCD_BUFFER_SIZE (320*240*2)
23#define TTB_SIZE (0x4000)
24/* must be 16Kb (0x4000) aligned */
25#define TTB_BASE ((unsigned int *)(0x30000000 + (32*1024*1024) - TTB_SIZE)) /* End of memory */
26#define FRAME ((short *) ((char *)TTB_BASE - LCD_BUFFER_SIZE)) /* Right before TTB */
27
22/* Memory Controllers */ 28/* Memory Controllers */
23 29
24#define BWSCON (*(volatile int *)0x48000000) /* Bus width & wait status control */ 30#define BWSCON (*(volatile int *)0x48000000) /* Bus width & wait status control */
@@ -225,12 +231,6 @@
225#define LCDINTMSK (*(volatile int *)0x4D00005C) /* LCD interrupt mask */ 231#define LCDINTMSK (*(volatile int *)0x4D00005C) /* LCD interrupt mask */
226#define TCONSEL (*(volatile int *)0x4D000060) /* TCON(LPC3600/LCC3600) control */ 232#define TCONSEL (*(volatile int *)0x4D000060) /* TCON(LPC3600/LCC3600) control */
227 233
228#define LCD_BUFFER_SIZE ((320*240*2))
229#define TTB_SIZE (0x4000)
230/*#define FRAME ( (short *) 0x31E00000 ) */ /* LCD Frame buffer - Firmware Address */
231/* must be 16Kb (0x4000) aligned */
232#define TTB_BASE ((unsigned int *)(0x30000000 + (32*1024*1024) - TTB_SIZE)) /* End of memory */
233#define FRAME ((short *) ((char *)TTB_BASE - LCD_BUFFER_SIZE)) /* Right before TTB */
234/* NAND Flash */ 234/* NAND Flash */
235 235
236#define NFCONF (*(volatile int *)0x4E000000) /* NAND flash configuration */ 236#define NFCONF (*(volatile int *)0x4E000000) /* NAND flash configuration */
diff --git a/firmware/target/arm/mmu-arm.c b/firmware/target/arm/mmu-arm.c
index ffca7a43ee..c4b63cf805 100644
--- a/firmware/target/arm/mmu-arm.c
+++ b/firmware/target/arm/mmu-arm.c
@@ -20,70 +20,111 @@
20#include "mmu-arm.h" 20#include "mmu-arm.h"
21#include "panic.h" 21#include "panic.h"
22 22
23#define SECTION_ADDRESS_MASK (-1 << 20) 23void __attribute__((naked)) ttb_init(void) {
24#define MB (1 << 20) 24 asm volatile
25 (
26 "mcr p15, 0, %[ttbB], c2, c0, 0 \n" /* Set the TTB base address */
27 "mcr p15, 0, %[ffff], c3, c0, 0 \n" /* Set all domains to manager status */
28 "bx lr \n"
29 :
30 : [ttbB] "r" (TTB_BASE),
31 [ffff] "r" (0xFFFFFFFF)
32 );
33}
25 34
26void ttb_init(void) { 35void __attribute__((naked)) map_section(unsigned int pa, unsigned int va, int mb, int flags) {
27 unsigned int* ttbPtr; 36#if 0 /* This code needs to be fixed and the C needs to be replaced to ensure that stack is not used */
37 asm volatile
38 (
39 /* pa &= (-1 << 20); // align to 1MB */
40 "mov r0, r0, lsr #20 \n"
41 "mov r0, r0, lsl #20 \n"
28 42
29 /* must be 16Kb (0x4000) aligned - clear out the TTB */ 43 /* pa |= (flags | 0x412);
30 for (ttbPtr=TTB_BASE; ttbPtr<(TTB_SIZE+TTB_BASE); ttbPtr++) 44 * bit breakdown:
31 { 45 * 10: superuser - r/w, user - no access
32 *ttbPtr = 0; 46 * 4: should be "1"
33 } 47 * 3,2: Cache flags (flags (r3))
48 * 1: Section signature
49 */
34 50
35 /* Set the TTB base address */ 51 "orr r0, r0, r3 \n"
36 asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r" (TTB_BASE)); 52 "orr r0, r0, #0x410 \n"
53 "orr r0, r0, #0x2 \n"
54 :
55 :
56 );
37 57
38 /* Set all domains to manager status */ 58 register int *ttb_base asm ("r3") = TTB_BASE; /* force in r3 */
39 asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (0xFFFFFFFF));
40}
41 59
42void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags) { 60 asm volatile
43 unsigned int* ttbPtr; 61 (
44 int i; 62 /* unsigned int* ttbPtr = TTB_BASE + (va >> 20);
45 int section_no; 63 * sections are 1MB size
64 */
46 65
47 section_no = va >> 20; /* sections are 1Mb size */ 66 "mov r1, r1, lsr #20 \n"
48 ttbPtr = TTB_BASE + section_no; 67 "add r1, %[ttbB], r1, lsl #0x2 \n"
49 pa &= SECTION_ADDRESS_MASK; /* align to 1Mb */
50 for(i=0; i<mb; i++, pa += MB) {
51 *(ttbPtr + i) =
52 pa |
53 1 << 10 | /* superuser - r/w, user - no access */
54 0 << 5 | /* domain 0th */
55 1 << 4 | /* should be "1" */
56 cache_flags |
57 1 << 1; /* Section signature */
58 }
59}
60 68
61void enable_mmu(void) { 69 /* Add MB to pa, flags are already present in pa, but addition
62 int regread; 70 * should not effect them
71 *
72 * #define MB (1 << 20)
73 * for( ; mb>0; mb--, pa += MB)
74 * {
75 * *(ttbPtr++) = pa;
76 * }
77 * #undef MB
78 */
63 79
64 asm volatile( 80 "cmp r2, #0 \n"
65 "MRC p15, 0, %r0, c1, c0, 0\n" /* Read reg1, control register */ 81 "bxle lr \n"
66 : /* outputs */ 82 "loop: \n"
67 "=r"(regread) 83 "str r0, [r1], #4 \n"
68 : /* inputs */ 84 "add r0, r0, #0x100000 \n"
69 : /* clobbers */ 85 "sub r2, r2, #0x01 \n"
70 "r0" 86 "bne loop \n"
87 "bx lr \n"
88 :
89 : [ttbB] "r" (ttb_base) /* This /HAS/ to be in r3 */
71 ); 90 );
91 (void) pa;
92 (void) va;
93 (void) mb;
94 (void) flags;
95#else
96 pa &= (-1 << 20);
97 pa |= (flags | 0x412);
98 unsigned int* ttbPtr = TTB_BASE + (va >> 20);
72 99
73 if ( !(regread & 0x04) || !(regread & 0x00001000) ) /* Was the ICache or DCache Enabled? */ 100#define MB (1 << 20)
74 clean_dcache(); /* If so we need to clean the DCache before invalidating below */ 101 for( ; mb>0; mb--, pa += MB)
75 102 {
76 asm volatile("mov r0, #0\n" 103 *(ttbPtr++) = pa;
77 "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */ 104 }
78 105#undef MB
79 "mcr p15, 0, r0, c7, c7,0\n" /* invalidate both icache and dcache */ 106#endif
107}
80 108
81 "mrc p15, 0, r0, c1, c0, 0\n" 109void __attribute__((naked)) enable_mmu(void) {
82 "orr r0, r0, #1<<0\n" /* enable mmu bit, icache and dcache */ 110 asm volatile(
83 "orr r0, r0, #1<<2\n" /* enable dcache */ 111 "mov r0, #0 \n"
84 "orr r0, r0, #1<<12\n" /* enable icache */ 112 "mcr p15, 0, r0, c8, c7, 0 \n" /* invalidate TLB */
85 "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); 113 "mcr p15, 0, r0, c7, c7,0 \n" /* invalidate both icache and dcache */
86 asm volatile("nop \n nop \n nop \n nop"); 114 "mrc p15, 0, r0, c1, c0, 0 \n"
115 "orr r0, r0, #1 \n" /* enable mmu bit, icache and dcache */
116 "orr r0, r0, #1<<2 \n" /* enable dcache */
117 "orr r0, r0, #1<<12 \n" /* enable icache */
118 "mcr p15, 0, r0, c1, c0, 0 \n"
119 "nop \n"
120 "nop \n"
121 "nop \n"
122 "nop \n"
123 "bx lr \n"
124 :
125 :
126 : "r0"
127 );
87} 128}
88 129
89#if CONFIG_CPU == IMX31L 130#if CONFIG_CPU == IMX31L
@@ -105,35 +146,36 @@ void invalidate_dcache_range(const void *base, unsigned int size) {
105 unsigned int addr = (((int) base) & ~31); /* Align start to cache line*/ 146 unsigned int addr = (((int) base) & ~31); /* Align start to cache line*/
106 unsigned int end = ((addr+size) & ~31)+64; /* Align end to cache line, pad */ 147 unsigned int end = ((addr+size) & ~31)+64; /* Align end to cache line, pad */
107 asm volatile( 148 asm volatile(
108"inv_start: \n" 149 "inv_start: \n"
109 "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 150 "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
110 "add %0, %0, #32 \n" 151 "add %0, %0, #32 \n"
111 "cmp %0, %1 \n" 152 "cmp %0, %1 \n"
112 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 153 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
113 "addne %0, %0, #32 \n" 154 "addne %0, %0, #32 \n"
114 "cmpne %0, %1 \n" 155 "cmpne %0, %1 \n"
115 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 156 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
116 "addne %0, %0, #32 \n" 157 "addne %0, %0, #32 \n"
117 "cmpne %0, %1 \n" 158 "cmpne %0, %1 \n"
118 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 159 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
119 "addne %0, %0, #32 \n" 160 "addne %0, %0, #32 \n"
120 "cmpne %0, %1 \n" 161 "cmpne %0, %1 \n"
121 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 162 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
122 "addne %0, %0, #32 \n" 163 "addne %0, %0, #32 \n"
123 "cmpne %0, %1 \n" 164 "cmpne %0, %1 \n"
124 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 165 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
125 "addne %0, %0, #32 \n" 166 "addne %0, %0, #32 \n"
126 "cmpne %0, %1 \n" 167 "cmpne %0, %1 \n"
127 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 168 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
128 "addne %0, %0, #32 \n" 169 "addne %0, %0, #32 \n"
129 "cmpne %0, %1 \n" 170 "cmpne %0, %1 \n"
130 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ 171 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
131 "addne %0, %0, #32 \n" 172 "addne %0, %0, #32 \n"
132 "cmpne %0, %1 \n" 173 "cmpne %0, %1 \n"
133 "bne inv_start \n" 174 "bne inv_start \n"
134 "mov %0, #0\n" 175 "mov %0, #0\n"
135 "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */ 176 "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
136 : : "r" (addr), "r" (end)); 177 : : "r" (addr), "r" (end)
178 );
137} 179}
138#endif 180#endif
139 181
@@ -239,41 +281,20 @@ void __attribute__((naked)) clean_dcache(void)
239/* Cleans entire DCache */ 281/* Cleans entire DCache */
240void clean_dcache(void) 282void clean_dcache(void)
241{ 283{
242 unsigned int index, addr; 284 unsigned int index, addr, low;
243 285
244 for(index = 0; index <= 63; index++) { 286 for(index = 0; index <= 63; index++)
245 addr = (0 << 5) | (index << 26); 287 {
246 asm volatile( 288 for(low = 0;low <= 7; low++)
247 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ 289 {
248 : : "r" (addr)); 290 addr = (index << 26) | (low << 5);
249 addr = (1 << 5) | (index << 26); 291 asm volatile
250 asm volatile( 292 (
251 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ 293 "mcr p15, 0, %[addr], c7, c10, 2 \n" /* Clean this entry by index */
252 : : "r" (addr)); 294 :
253 addr = (2 << 5) | (index << 26); 295 : [addr] "r" (addr)
254 asm volatile( 296 );
255 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ 297 }
256 : : "r" (addr));
257 addr = (3 << 5) | (index << 26);
258 asm volatile(
259 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
260 : : "r" (addr));
261 addr = (4 << 5) | (index << 26);
262 asm volatile(
263 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
264 : : "r" (addr));
265 addr = (5 << 5) | (index << 26);
266 asm volatile(
267 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
268 : : "r" (addr));
269 addr = (6 << 5) | (index << 26);
270 asm volatile(
271 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
272 : : "r" (addr));
273 addr = (7 << 5) | (index << 26);
274 asm volatile(
275 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
276 : : "r" (addr));
277 } 298 }
278} 299}
279#endif 300#endif
diff --git a/firmware/target/arm/mmu-arm.h b/firmware/target/arm/mmu-arm.h
index b744305dbd..4b8f3448d4 100644
--- a/firmware/target/arm/mmu-arm.h
+++ b/firmware/target/arm/mmu-arm.h
@@ -17,13 +17,16 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19 19
20#define CACHE_ALL (1 << 3 | 1 << 2 ) 20#define CACHE_ALL 0x0C
21#define CACHE_NONE 0 21#define CACHE_NONE 0
22#define BUFFERED (1 << 2) 22#define BUFFERED 0x04
23 23
24void ttb_init(void); 24void ttb_init(void);
25void enable_mmu(void); 25void enable_mmu(void);
26void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags); 26void map_section(unsigned int pa, unsigned int va, int mb, int flags);
27
28/* Cleans entire DCache */
29void clean_dcache(void);
27 30
28/* Invalidate DCache for this range */ 31/* Invalidate DCache for this range */
29/* Will do write back */ 32/* Will do write back */
@@ -37,7 +40,4 @@ void clean_dcache_range(const void *base, unsigned int size);
37/* Will *NOT* do write back */ 40/* Will *NOT* do write back */
38void dump_dcache_range(const void *base, unsigned int size); 41void dump_dcache_range(const void *base, unsigned int size);
39 42
40/* Cleans entire DCache */
41void clean_dcache(void);
42
43void memory_init(void); 43void memory_init(void);
diff --git a/firmware/target/arm/s3c2440/app.lds b/firmware/target/arm/s3c2440/app.lds
index 86f37d5a29..e6efe62656 100644
--- a/firmware/target/arm/s3c2440/app.lds
+++ b/firmware/target/arm/s3c2440/app.lds
@@ -16,12 +16,9 @@ INPUT(target/arm/s3c2440/crt0.o)
16#endif 16#endif
17 17
18#include "cpu.h" 18#include "cpu.h"
19#define DRAMSIZE (MEMORYSIZE * 0x100000) - 0x100 - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE 19#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE
20 20
21#define DRAMORIG 0x00000100 + STUBOFFSET 21#define DRAMORIG 0x00000000 + STUBOFFSET
22#define IRAMORIG DRAMORIG
23#define IRAM DRAM
24#define IRAMSIZE 0x1000
25 22
26/* End of the audio buffer, where the codec buffer starts */ 23/* End of the audio buffer, where the codec buffer starts */
27#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) 24#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
@@ -36,18 +33,26 @@ MEMORY
36 33
37SECTIONS 34SECTIONS
38{ 35{
39 .text : 36 .vectors DRAMORIG :
40 { 37 {
41 loadaddress = .; 38 _vectorstart = .;
42 _loadaddress = .; 39 *(.vectors*);
43 . = ALIGN(0x200);
44 *(.init.text) 40 *(.init.text)
41 . = ALIGN(0x4);
42 } > DRAM
43
44 .text :
45 {
46 _textstart = .;
47 *(.text)
45 *(.text*) 48 *(.text*)
46 *(.glue_7) 49 *(.glue_7)
47 *(.glue_7t) 50 *(.glue_7t)
48 . = ALIGN(0x4); 51 . = ALIGN(0x4);
49 } > DRAM 52 } > DRAM
50 53
54 _textcopy = LOADADDR(.text);
55
51 .rodata : 56 .rodata :
52 { 57 {
53 *(.rodata) /* problems without this, dunno why */ 58 *(.rodata) /* problems without this, dunno why */
@@ -55,35 +60,18 @@ SECTIONS
55 *(.rodata.str1.1) 60 *(.rodata.str1.1)
56 *(.rodata.str1.4) 61 *(.rodata.str1.4)
57 . = ALIGN(0x4); 62 . = ALIGN(0x4);
58
59 /* Pseudo-allocate the copies of the data sections */
60 _datacopy = .;
61 } > DRAM 63 } > DRAM
62 64
63 /* TRICK ALERT! For RAM execution, we put the .data section at the 65 .data :
64 same load address as the copy. Thus, we don't waste extra RAM
65 when we don't actually need the copy. */
66 .data : AT ( _datacopy )
67 { 66 {
68 _datastart = .;
69 *(.data*) 67 *(.data*)
70 . = ALIGN(0x4); 68 . = ALIGN(0x4);
71 _dataend = .;
72 } > DRAM 69 } > DRAM
73 70
74 /DISCARD/ : 71 /DISCARD/ :
75 { 72 {
76 *(.eh_frame) 73 *(.eh_frame)
77 } 74 }
78
79 .vectors 0x0 :
80 {
81 _vectorsstart = .;
82 *(.vectors);
83 _vectorsend = .;
84 } AT> DRAM
85
86 _vectorscopy = LOADADDR(.vectors);
87 75
88 .iram : 76 .iram :
89 { 77 {
@@ -97,7 +85,7 @@ SECTIONS
97 85
98 _iramcopy = LOADADDR(.iram); 86 _iramcopy = LOADADDR(.iram);
99 87
100 .ibss (NOLOAD) : 88 .ibss :
101 { 89 {
102 _iedata = .; 90 _iedata = .;
103 *(.ibss) 91 *(.ibss)
diff --git a/firmware/target/arm/s3c2440/boot.lds b/firmware/target/arm/s3c2440/boot.lds
index cc20fbe86f..4516c7ddb0 100644
--- a/firmware/target/arm/s3c2440/boot.lds
+++ b/firmware/target/arm/s3c2440/boot.lds
@@ -7,44 +7,93 @@ INPUT(target/arm/s3c2440/crt0.o)
7 7
8#define DRAMSIZE (MEMORYSIZE * 0x100000) 8#define DRAMSIZE (MEMORYSIZE * 0x100000)
9 9
10#define DRAMORIG 0x30000000 10#define DRAMORIG 0x00000000
11#define IRAMORIG 0x40000000 11#define IRAMORIG 0x40000000
12#define IRAMSIZE 4K 12#define IRAMSIZE 4K
13#define FLASHORIG 0x0000000 13#define FLASHORIG 0x00000000
14#define FLASHSIZE 1M 14#define FLASHSIZE 1M
15 15
16SECTIONS 16MEMORY
17{ 17{
18 . = DRAMORIG + 0x1000000; 18 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
19}
19 20
20 .text : { 21SECTIONS
22{
23 .vectors DRAMORIG :
24 {
25 _vectorstart = .;
26 *(.vectors*);
21 *(.init.text) 27 *(.init.text)
28 . = ALIGN(0x4);
29 } > DRAM
30
31 .text :
32 {
33 _textstart = .;
34 *(.text)
22 *(.text*) 35 *(.text*)
23 } 36 *(.glue_7)
37 *(.glue_7t)
38 . = ALIGN(0x4);
39 } > DRAM
24 40
25 .data : { 41 _textcopy = LOADADDR(.text);
42
43 .rodata :
44 {
45 *(.rodata) /* problems without this, dunno why */
46 *(.rodata*)
47 *(.rodata.str1.1)
48 *(.rodata.str1.4)
49 . = ALIGN(0x4);
50 } > DRAM
51
52 .data :
53 {
54 *(.data*)
55 . = ALIGN(0x4);
56 } > DRAM
57
58 /DISCARD/ :
59 {
60 *(.eh_frame)
61 }
62
63 .iram :
64 {
65 _iramstart = .;
26 *(.icode) 66 *(.icode)
27 *(.irodata) 67 *(.irodata)
28 *(.idata) 68 *(.idata)
29 *(.data*) 69 . = ALIGN(0x4);
70 _iramend = .;
71 } > DRAM
72
73 _iramcopy = LOADADDR(.iram);
74
75 .ibss :
76 {
77 _iedata = .;
78 *(.ibss)
30 . = ALIGN(0x4); 79 . = ALIGN(0x4);
31 _dataend = . ; 80 _iend = .;
32 } 81 } > DRAM
33 82
34 .stack : 83 .stack :
35 { 84 {
36 *(.stack) 85 *(.stack)
37 _stackbegin = .; 86 stackbegin = .;
38 stackbegin = .; 87 . += 0x2000;
39 . += 0x2000; 88 stackend = .;
40 _stackend = .; 89 } > DRAM
41 stackend = .; 90
42 } 91 .bss :
43 .bss : { 92 {
44 _edata = .; 93 _edata = .;
45 *(.bss*); 94 *(.bss*)
46 *(.ibss); 95 *(COMMON)
47 *(COMMON) 96 . = ALIGN(0x4);
48 _end = .; 97 _end = .;
49 } 98 } > DRAM
50} 99}
diff --git a/firmware/target/arm/s3c2440/crt0.S b/firmware/target/arm/s3c2440/crt0.S
index 4f220f6c7f..7f1ebf8dec 100644
--- a/firmware/target/arm/s3c2440/crt0.S
+++ b/firmware/target/arm/s3c2440/crt0.S
@@ -7,7 +7,11 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing 10 * Copyright (C) 2008 by Karl Kurbjun
11 *
12 * Arm bootloader and startup code based on startup.s from the iPodLinux loader
13 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
14 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
11 * 15 *
12 * All files in this archive are subject to the GNU General Public License. 16 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement. 17 * See the file COPYING in the source tree root for full license agreement.
@@ -19,73 +23,183 @@
19#include "config.h" 23#include "config.h"
20#include "cpu.h" 24#include "cpu.h"
21 25
22 .section .init.text,"ax",%progbits 26/* Exception Handlers */
27.section .vectors,"ax",%progbits
28.code 32
23 29
24 .global start 30.global vectors
25start: 31vectors:
32 b start
33 b undef_instr_handler
34 b software_int_handler
35 b prefetch_abort_handler
36 b data_abort_handler
37 b reserved_handler
38 b irq_handler
39 b fiq_handler
40
41/*
42 * Function: code_copy
43 * Variables:
44 * r0 = from
45 * r1 = to
46 * r2 = length
47 */
26 48
27/* Arm bootloader and startup code based on startup.s from the iPodLinux loader 49.section .init.text, "ax", %progbits
28 * 50.align 0x04
29 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) 51.global word_copy
30 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> 52.type word_copy, %function
31 * 53word_copy:
54 sub r2, r2, #0x04
55 cmp r2, #0
56 ldrge r3, [r0], #4
57 strge r3, [r1], #4
58 bgt word_copy
59 bx lr
60.ltorg
61.size word_copy, .-word_copy
62
63/*
64 * Entry: start
65 * Variables:
66 * none
32 */ 67 */
33 msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */
34
35#if !defined(BOOTLOADER)
36 /* Copy exception handler code to address 0 */
37 ldr r2, =_vectorsstart
38 ldr r3, =_vectorsend
39 ldr r4, =_vectorscopy
401:
41 cmp r3, r2
42 ldrhi r5, [r4], #4
43 strhi r5, [r2], #4
44 bhi 1b
45#endif
46 68
47#if !defined(BOOTLOADER) && !defined(STUB) 69.section .init.text,"ax",%progbits
48 /* Zero out IBSS */ 70.code 32
49 ldr r2, =_iedata 71.align 0x04 /* Align */
50 ldr r3, =_iend 72.global start
51 mov r4, #0 73start:
521: 74 msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */
53 cmp r3, r2
54 strhi r4, [r2], #4
55 bhi 1b
56 75
57 /* Copy the IRAM */ 76 /* Disable the watchdog */
58 ldr r2, =_iramcopy 77 ldr r2, =0x00000000
59 ldr r3, =_iramstart 78 mov r1, #0x53000000
60 ldr r4, =_iramend 79 str r2, [r1]
611:
62 cmp r4, r3
63 ldrhi r5, [r2], #4
64 strhi r5, [r3], #4
65 bhi 1b
66#endif /* !BOOTLOADER, !STUB */
67 80
68 /* Initialise bss section to zero */ 81 /* Mask all Interupts to be safe */
69 ldr r2, =_edata 82 ldr r2, =0xFFFFFFFF
70 ldr r3, =_end 83 mov r1, #0x4A000000
71 mov r4, #0 84 str r2, [r1]
721: 85
73 cmp r3, r2 86 /* Submask too */
74 strhi r4, [r2], #4 87 ldr r2, =0x00003FFF
75 bhi 1b 88 str r2, [r1, #0x1C]
76 89
77 /* Set up some stack and munge it with 0xdeadbeef */ 90 /* Check if loaded by the old bootloader or by the OF
78 ldr sp, =stackend 91 * Be careful with code size above this as well.
79 mov r3, sp 92 */
80 ldr r2, =stackbegin 93
81 ldr r4, =0xdeadbeef 94 /* Get the execute address (cannot be past 0x100 for this to work */
821: 95 ldr r0, =0xffffff00
83 cmp r3, r2 96 and r0, pc, r0
84 strhi r4, [r2], #4 97
85 bhi 1b 98 /* Calculate the length of the code needed to run/copy */
99 ldr r1, = _vectorstart
100 ldr r2, = _iramend
101 sub r2, r2, r1
102
103 add r3, r2, #0x30000000
104
105 /* Is there enough space to copy without overwriting? */
106 cmp r0, r3
107
108 /* There's enough space, skip copying */
109 bgt skipreset
110
111 /* Is this code running from 0x0? If so skip copy. */
112 cmplt r0, #0
113 beq skipreset
86 114
87#ifdef BOOTLOADER 115 /* There's not enough space to copy without overwriting, copy to safe spot
88 /* Proper initialization pulled from 0x5070 */ 116 * and reset
117 */
118 mov r1, #0x31000000 /* copy location */
119 bl word_copy
120
121 mov pc, #0x31000000
122
123 skipreset:
124
125 /* Initial Clock Setup */
126 mov r2, #0x7
127 mov r1, #0x4C000000
128 str r2, [r1, #0x14]
129
130 mov r2, #0x0
131 str r2, [r1, #0x18]
132
133 ldr r2, =0xFFFFFFFF
134 str r2, [r1]
135
136 ldr r2, =0x0003C042
137 str r2, [r1, #0x08]
138
139 nop
140 nop
141 nop
142 nop
143 nop
144 nop
145 nop
146 nop
147
148 ldr r2, =0x000C9042
149 str r2, [r1, #0x04]
150
151 nop
152 nop
153 nop
154 nop
155 nop
156 nop
157 nop
158 nop
159
160 /* If we want to disable extraneous clocks, uncomment, but it can
161 * freeze the device
162 */
163#if 0
164 ldr r2, =0x6030
165 mov r1, #0x4C000000
166 str r2, [r1, #0x0C]
167#endif
168
169 /* set Bus to Asynchronous mode (full speed) */
170 mov r0, #0
171 mrc p15, 0, r0, c1, c0, 0
172 ldr r1, =0xC0000000
173 orr r0, r0, r1
174 mcr p15, 0, r0, c1, c0, 0
175
176 /* Setup MISCCR */
177 ldr r2, =0x00613020
178 mov r1, #0x56000000
179 str r2, [r1, #0x80]
180
181 /* Setup some unknown outputs in GPB and GPH */
182 ldr r2, [r1, #0x10]
183 mov r3, #0x05
184 orr r2, r3, r2
185 str r2, [r1, #0x10]
186
187 ldr r2, [r1, #0x14]
188 mov r3, #0x03
189 orr r2, r3, r2
190 str r2, [r1, #0x14]
191
192 ldr r2, [r1, #0x70]
193 mov r3, #0x05
194 orr r2, r3, r2
195 str r2, [r1, #0x70]
196
197 ldr r2, [r1, #0x74]
198 mov r3, #0x03
199 orr r2, r3, r2
200 str r2, [r1, #0x74]
201
202 /* Memory setup (taken from 0x5070) */
89 203
90 /* BWSCON 204 /* BWSCON
91 * Reserved 0 205 * Reserved 0
@@ -120,7 +234,7 @@ start:
120 * Disable wait 0 234 * Disable wait 0
121 * Not using UB/LB 0 235 * Not using UB/LB 0
122 */ 236 */
123 ldr r2,=0x01055102 237 ldr r2, =0x01055102
124 mov r1, #0x48000000 238 mov r1, #0x48000000
125 str r2, [r1] 239 str r2, [r1]
126 240
@@ -133,8 +247,8 @@ start:
133 * Chip select setup time: 1 clock 01 247 * Chip select setup time: 1 clock 01
134 * Address setup time: 0 clock 00 248 * Address setup time: 0 clock 00
135 */ 249 */
136 ldr r2,=0x00000D60 250 ldr r2, =0x00000D60
137 str r2, [r1, #4] 251 str r2, [r1, #0x04]
138 252
139 253
140 /* BANKCON1 254 /* BANKCON1
@@ -146,8 +260,8 @@ start:
146 * Chip select setup time: 0 clocks 00 260 * Chip select setup time: 0 clocks 00
147 * Address setup time: 0 clocks 00 261 * Address setup time: 0 clocks 00
148 */ 262 */
149 ldr r2,=0x00000000 263 ldr r2, =0x00000000
150 str r2, [r1, #8] 264 str r2, [r1, #0x08]
151 265
152 /* BANKCON2 266 /* BANKCON2
153 * Pagemode: normal (1 data) 00 267 * Pagemode: normal (1 data) 00
@@ -158,17 +272,17 @@ start:
158 * Chip select setup time: 4 clocks 11 272 * Chip select setup time: 4 clocks 11
159 * Address setup time: 0 clocks 00 273 * Address setup time: 0 clocks 00
160 */ 274 */
161 ldr r2,=0x00001FA0 275 ldr r2, =0x00001FA0
162 str r2, [r1, #0xC] 276 str r2, [r1, #0xC]
163 277
164 /* BANKCON3 */ 278 /* BANKCON3 */
165 ldr r2,=0x00001D80 279 ldr r2, =0x00001D80
166 str r2, [r1, #0x10] 280 str r2, [r1, #0x10]
167 /* BANKCON4 */ 281 /* BANKCON4 */
168 str r2, [r1, #0x14] 282 str r2, [r1, #0x14]
169 283
170 /* BANKCON5 */ 284 /* BANKCON5 */
171 ldr r2,=0x00000000 285 ldr r2, =0x00000000
172 str r2, [r1, #0x18] 286 str r2, [r1, #0x18]
173 287
174 /* BANKCON6/7 288 /* BANKCON6/7
@@ -181,13 +295,13 @@ start:
181 * Tacs: 0 clock 00 295 * Tacs: 0 clock 00
182 * MT: Sync DRAM 11 296 * MT: Sync DRAM 11
183 */ 297 */
184 ldr r2,=0x00018005 298 ldr r2, =0x00018005
185 str r2, [r1, #0x1C] 299 str r2, [r1, #0x1C]
186 /* BANKCON7 */ 300 /* BANKCON7 */
187 str r2, [r1, #0x20] 301 str r2, [r1, #0x20]
188 302
189 /* REFRESH */ 303 /* REFRESH */
190 ldr r2,=0x00980501 304 ldr r2, =0x00980501
191 str r2, [r1, #0x24] 305 str r2, [r1, #0x24]
192 306
193 /* BANKSIZE 307 /* BANKSIZE
@@ -198,117 +312,158 @@ start:
198 * Reserved: 0 0 312 * Reserved: 0 0
199 * BURST_EN: enabled 1 313 * BURST_EN: enabled 1
200 */ 314 */
201 ldr r2,=0x00000090 315 ldr r2, =0x00000090
202 str r2, [r1, #0x28] 316 str r2, [r1, #0x28]
203 317
204 /* MRSRB6 */ 318 /* MRSRB6 */
205 ldr r2,=0x00000030 319 ldr r2, =0x00000030
206 str r2, [r1, #0x2C] 320 str r2, [r1, #0x2C]
207 /* MRSRB7 */ 321 /* MRSRB7 */
208 str r2, [r1, #0x30] 322 str r2, [r1, #0x30]
209 323
210#if 0 324#if 0
211 /* This next part I am not sure of the purpose */
212
213 /* GPACON */ 325 /* GPACON */
214 mov r2,#0x01FFFCFF 326 mov r1, #0x56000000
215 str r2,=0x56000000 327 ldr r2, =0x01FFFCFF /* 0x01FFFCFF */
328 str r2, [r1]
216 329
217 /* GPADAT */ 330 /* GPADAT */
218 mov r2,#0x01FFFEFF 331 ldr r2, =0x01FFFEFF
219 str r2,=0x56000004 332 str r2, [r1, #0x04]
220 333
221 /* MRSRB6 */ 334 /* MRSRB6 */
222 mov r2,#0x00000000 335 mov r1, #0x48000000
223 str r2,=0x4800002C 336 mov r2, #0x00000000
337 str r2, [r1, #0x2C]
224 338
225 /* GPADAT */ 339 /* GPADAT */
226 ldr r2,=0x01FFFFFF 340 mov r1, #0x56000000
227 mov r1, #0x56000000 341 ldr r2, =0x01FFFFFF
228 str r2, [r1, #4] 342 str r2, [r1, #0x04]
229 343
230 /* MRSRB6 */ 344 /* MRSRB6 */
231 mov r2,#0x00000030 345 mov r1, #0x48000000
232 str r2,=0x4800002C 346 mov r2, #0x00000030
347 str r2, [r1, #0x2C]
233 348
234 /* GPACON */ 349 /* GPACON */
235 mov r2,#0x01FFFFFF 350 mov r1, #0x56000000
236 str r2,=0x56000000 351 mov r2, #0x01FFFFFF
352 str r2, [r1]
237 353
238 /* End of the unknown */ 354 /* End of the unknown */
239#endif 355#endif
240 356
241 /* get the high part of our execute address */ 357 /* The builds have two potential load addresses, one being from flash,
242 ldr r2, =0xffffff00 358 * and the other from some "unknown" location right now the assumption
243 and r4, pc, r2 359 * is that the code is not at 0x3000000.
244 360 */
245 /* Copy bootloader to safe area - 0x31000000 */ 361 /* get the high part of our execute address (where am I) */
246 mov r5, #0x30000000 362 ldr r0, =0xfffff000
247 add r5, r5, #0x1000000 363 and r0, pc, r0
248 ldr r6, = _dataend 364
249 sub r0, r6, r5 /* length of loader */ 365 /* Copy code to 0x30000000 */
250 add r0, r4, r0 /* r0 points to start of loader */ 366 ldr r2, = _vectorstart
2511: 367 ldr r3, = _iramend
252 cmp r5, r6 368
253 ldrcc r2, [r4], #4 369 sub r2, r3, r2 /* length of loader */
254 strcc r2, [r5], #4 370
255 bcc 1b 371 ldr r1, =0x30000000 /* copy location */
256
257 ldr pc, =start_loc /* jump to the relocated start_loc: */
258 372
259start_loc: 373 bl word_copy
260 bl main 374
375 ldr r1, =donecopy
376 ldr r2, =0x30000000
377 add r1, r1, r2
378 mov pc, r1 /* The code is located where we want it-jump*/
379
380donecopy:
381
382 /* Setup the MMU, start by disabling */
261 383
262#else /* BOOTLOADER */ 384 mrc p15, 0, r0, c1, c0, 0
385 bic r0, r0, #0x41 /* disable mmu and dcache */
386 bic r0, r0, #0x1000 /* disable icache */
387 mcr p15, 0, r0, c1, c0, 0
388
389 bl ttb_init
390
391 ldr r0, =0x0
392 ldr r1, =0x0
393 ldr r2, =0x1000
394 mov r3, #0
395 bl map_section
396
397 ldr r0, =0x30000000
398 ldr r1, =0x0
399 mov r2, #32
400 mov r3, #12
401 bl map_section
402
403 ldr r0, =0x31FD6800 /* FRAME */
404 mov r1, r0
405 mov r2, #1
406 mov r3, #4
407 bl map_section
408
409 bl enable_mmu
410
411 /* Zero out IBSS */
412 ldr r2, =_iedata
413 ldr r3, =_iend
414 mov r4, #0
415ibsszero:
416 cmp r3, r2
417 strhi r4, [r2], #4
418 bhi ibsszero
419
420 /* Copy the IRAM */
421 ldr r0, =_iramcopy
422 ldr r1, =_iramstart
423 ldr r2, =_iramend
424 sub r2, r2, r1
425 bl word_copy
426
427 /* Initialise bss section to zero */
428 ldr r2, =_edata
429 ldr r3, =_end
430 mov r4, #0
431bsszero:
432 cmp r3, r2
433 strhi r4, [r2], #4
434 bhi bsszero
435
436 /* Set up some stack and munge it with 0xdeadbeef */
437 ldr sp, =stackend
438 mov r3, sp
439 ldr r2, =stackbegin
440 ldr r4, =0xdeadbeef
441stackmunge:
442 cmp r3, r2
443 strhi r4, [r2], #4
444 bhi stackmunge
263 445
264 /* Set up stack for IRQ mode */ 446 /* Set up stack for IRQ mode */
265 msr cpsr_c, #0xd2 447 msr cpsr_c, #0xd2
266 ldr sp, =irq_stack 448 ldr sp, =irq_stack
267 /* Set up stack for FIQ mode */ 449 /* Set up stack for FIQ mode */
268 msr cpsr_c, #0xd1 450 msr cpsr_c, #0xd1
269 ldr sp, =fiq_stack 451 ldr sp, =fiq_stack
270 452
271 /* Let abort and undefined modes use IRQ stack */ 453 /* Let abort and undefined modes use IRQ stack */
272 msr cpsr_c, #0xd7 454 msr cpsr_c, #0xd7
273 ldr sp, =irq_stack 455 ldr sp, =irq_stack
274 msr cpsr_c, #0xdb 456 msr cpsr_c, #0xdb
275 ldr sp, =irq_stack 457 ldr sp, =irq_stack
276 /* Switch to supervisor mode */ 458 /* Switch to supervisor mode */
277 msr cpsr_c, #0xd3 459 msr cpsr_c, #0xd3
278 ldr sp, =stackend 460 ldr sp, =stackend
279 bl main 461
280 /* main() should never return */ 462 /* Start the main function */
281 463 ldr pc, =main
282/* Exception handlers. Will be copied to address 0 after memory remapping */ 464
283 .section .vectors,"aw" 465 /* Should never get here, but let's restart in case */
284 ldr pc, [pc, #24] 466// b vectors
285 ldr pc, [pc, #24]
286 ldr pc, [pc, #24]
287 ldr pc, [pc, #24]
288 ldr pc, [pc, #24]
289 ldr pc, [pc, #24]
290 ldr pc, [pc, #24]
291 ldr pc, [pc, #24]
292
293 /* Exception vectors */
294 .global vectors
295vectors:
296 .word start
297 .word undef_instr_handler
298 .word software_int_handler
299 .word prefetch_abort_handler
300 .word data_abort_handler
301 .word reserved_handler
302 .word irq_handler
303 .word fiq_handler
304
305 .text
306
307#ifndef STUB
308 .global irq
309 .global fiq
310 .global UIE
311#endif
312 467
313/* All illegal exceptions call into UIE with exception address as first 468/* All illegal exceptions call into UIE with exception address as first
314 parameter. This is calculated differently depending on which exception 469 parameter. This is calculated differently depending on which exception
@@ -337,11 +492,15 @@ data_abort_handler:
337 mov r1, #2 492 mov r1, #2
338 b UIE 493 b UIE
339 494
340#ifdef STUB 495#if defined(BOOTLOADER)
341UIE: 496fiq_handler:
342 b UIE 497 b UIE
343#endif 498#endif
344 499
500UIE:
501 b UIE
502
503.section .text
345/* 256 words of IRQ stack */ 504/* 256 words of IRQ stack */
346 .space 256*4 505 .space 256*4
347irq_stack: 506irq_stack:
@@ -350,4 +509,3 @@ irq_stack:
350 .space 256*4 509 .space 256*4
351fiq_stack: 510fiq_stack:
352 511
353#endif /* BOOTLOADER */