summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lewis <sam.vr.lewis@gmail.com>2020-09-14 21:04:35 +1000
committerPatrick Georgi <pgeorgi@google.com>2020-09-21 08:10:56 +0000
commit362a1568670851cf25117d5660504dfb1d1b6331 (patch)
tree594596204207b4e909b685d52f9fbe164c091782
parentd5dda47db8fe1ed48e5aa02c02b3b6fe9b1b5402 (diff)
arch/arm: Add support for loading Linux kernels
Adds support for loading Linux kernels through FIT payloads. This has been implemented as an assembly function in order to simplify dealing with some of the intricacies of loading a kernel (such as needing to jump to the kernel in ARM mode and the kernel ABI). TEST: Booted a FIT image containing a 5.4 kernel and initramfs on the Beaglebone Black. Change-Id: I7dbf9467665ec17447cec73676763844b4be4764 Signed-off-by: Sam Lewis <sam.vr.lewis@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/45335 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
-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)