summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/imx233/app.lds10
-rw-r--r--firmware/target/arm/imx233/boot.lds10
-rw-r--r--firmware/target/arm/imx233/crt0.S33
3 files changed, 48 insertions, 5 deletions
diff --git a/firmware/target/arm/imx233/app.lds b/firmware/target/arm/imx233/app.lds
index a961222749..0eeecc1ab8 100644
--- a/firmware/target/arm/imx233/app.lds
+++ b/firmware/target/arm/imx233/app.lds
@@ -34,6 +34,11 @@ SECTIONS
{
loadaddress = UNCACHED_DRAM_ADDR;
_loadaddress = UNCACHED_DRAM_ADDR;
+
+ .dramcopystart (NOLOAD) :
+ {
+ _dramcopystart = .;
+ } > DRAM
.text :
{
@@ -76,6 +81,11 @@ SECTIONS
_initcopy = LOADADDR(.init);
+ .dramcopyend (NOLOAD) :
+ {
+ _dramcopyend = .;
+ } > DRAM
+
.stack (NOLOAD) :
{
*(.stack)
diff --git a/firmware/target/arm/imx233/boot.lds b/firmware/target/arm/imx233/boot.lds
index 206e0bb99f..d909b9fbd1 100644
--- a/firmware/target/arm/imx233/boot.lds
+++ b/firmware/target/arm/imx233/boot.lds
@@ -26,6 +26,11 @@ SECTIONS
_loadaddress = UNCACHED_DRAM_ADDR;
loadaddressend = UNCACHED_DRAM_ADDR + RAM_HOLE;
_loadaddressend = UNCACHED_DRAM_ADDR + RAM_HOLE;
+
+ .dramcopystart (NOLOAD) :
+ {
+ _dramcopystart = .;
+ } > DRAM
.text :
{
@@ -48,6 +53,11 @@ SECTIONS
_iramcopy = LOADADDR(.itext);
+ .dramcopyend (NOLOAD) :
+ {
+ _dramcopyend = .;
+ } > DRAM
+
.ibss (NOLOAD) :
{
_iedata = .;
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
index 393411b83a..abbff5816a 100644
--- a/firmware/target/arm/imx233/crt0.S
+++ b/firmware/target/arm/imx233/crt0.S
@@ -33,15 +33,22 @@
ldr pc, =irq_handler
ldr pc, =fiq_handler
-/* When starting, we are running at 0x4xxxxxxx (uncached) but the code
- * assumes DRAM is somewhere else (cached) so we first need to
- * setup the MMU and then jump to the right location. */
+/* When starting, we will be running at 0x40000000 most probably
+ * but the code is expected to be loaded at 0x4xxxxxxx (uncached) and to be
+ * running at virtual address 0xyyyyyyyy (cached). So we first
+ * need to move everything to the right locationn then we setup the mmu and
+ * jump to the final virtual address. */
.text
.global start
+ /** The code below must be able to run at any address **/
start:
+ /* Copy running address */
+ sub r7, pc, #8
/* Save r0 */
mov r6, r0
- msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+
+ /* enter supervisor mode, disable IRQ/FIQ */
+ msr cpsr_c, #0xd3
/* Disable MMU, disable caching and buffering;
* use low exception range address (the core uses high range by default) */
mrc p15, 0, r0, c1, c0, 0
@@ -55,10 +62,25 @@ start:
/* Enable MMU */
bl memory_init
+
+ /* Copy the DRAM
+ * Assume the dram binary blob is located at the loading address (r5) */
+ mov r2, r7
+ ldr r3, =_dramcopystart
+ ldr r4, =_dramcopyend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+
+ mov r2, #0
+ mcr p15, 0, r2, c7, c5, 0 @ Invalidate ICache
+
/* Jump to real location */
ldr pc, =remap
remap:
-
+ /** The code below is be running at the right virtual address **/
/* Zero out IBSS */
ldr r2, =_iedata
ldr r3, =_iend
@@ -132,6 +154,7 @@ remap:
/* Jump to main */
mov r0, r6
+ mov r1, r7
bl main
1:
b 1b