summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/Makefile.inc1
-rw-r--r--src/arch/arm/boot.c22
-rw-r--r--src/arch/arm/boot_linux.S21
3 files changed, 42 insertions, 2 deletions
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index 241bfe5051..3d359148aa 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -119,6 +119,7 @@ ramstage-y += memset.S
ramstage-y += memcpy.S
ramstage-y += memmove.S
ramstage-y += clock.c
+ramstage-y += boot_linux.S
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
rmodules_arm-y += memset.S
diff --git a/src/arch/arm/boot.c b/src/arch/arm/boot.c
index 8c876de0b0..b18473b924 100644
--- a/src/arch/arm/boot.c
+++ b/src/arch/arm/boot.c
@@ -1,14 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <cbfs.h>
#include <arch/cache.h>
#include <program_loading.h>
+void boot_linux(void *kernel_ptr, void *fdt_ptr);
+
void arch_prog_run(struct prog *prog)
{
void (*doit)(void *);
cache_sync_instructions();
- doit = prog_entry(prog);
- doit(prog_entry_arg(prog));
+ switch (prog_cbfs_type(prog)) {
+ case CBFS_TYPE_FIT:
+ /*
+ * We only load Linux payloads from the ramstage, so provide a hint to
+ * the linker that the below functions do not need to be included in
+ * earlier stages.
+ */
+ if (!ENV_RAMSTAGE)
+ break;
+
+ dcache_mmu_disable();
+ boot_linux(prog_entry(prog), prog_entry_arg(prog));
+ break;
+ default:
+ doit = prog_entry(prog);
+ doit(prog_entry_arg(prog));
+ }
}
diff --git a/src/arch/arm/boot_linux.S b/src/arch/arm/boot_linux.S
new file mode 100644
index 0000000000..e3985eae56
--- /dev/null
+++ b/src/arch/arm/boot_linux.S
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/asm.h>
+
+/* Required to jump to kernel in ARM state */
+.arm
+/* void boot_linux(void *kernel_ptr, void *fdt_ptr); */
+ENTRY(boot_linux)
+ /* Save kernel ptr */
+ mov r3, r0
+ /* Set R2 = fdt */
+ mov r2, r1
+ /* Set R0 = 0x00000000 as expected by Linux ABI */
+ mov r0, #0
+ /* Set R1 = 0xffffffff as expected by Linux ABI */
+ mov r1, #-1
+ /* Linux ABI expects SVC mode (0x13) with IRQ(7) and FIQ(6) disabled. */
+ msr cpsr_cxf, #0xd3
+ /* Jump to kernel */
+ mov pc, r3
+ENDPROC(boot_linux)