summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2018-04-02 22:16:19 +0000
committergonzo <gonzo@FreeBSD.org>2018-04-02 22:16:19 +0000
commit522277038a84aca4ccfd4ff19563022420f4b376 (patch)
treef81fe13044e80a6d093bf6a26a7ad434d04fd3a7 /sys/arm
parente6a33cf67e3d25ec186eaf10582b887c9a11b833 (diff)
downloadFreeBSD-src-522277038a84aca4ccfd4ff19563022420f4b376.zip
FreeBSD-src-522277038a84aca4ccfd4ff19563022420f4b376.tar.gz
MFC r304488, r304623
r304488 by manu: Keep boot parameters in ARM trampoline code Currently boot parameters (r0 - r3) are forgotten in ARM trampoline code. This patch save them at startup and restore them before jumping into kernel _start() routine. This is usefull when booting with Linux ABI and/or custom bootloader. Submitted by: Grégory Soutadé <soutade@gmail.com> Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D7395 r304623 by manu: Fix building for ARM kernel that have FLASHADDR, PHYSADDR and LOADERRAMADDR defined. Pointy Hat: myself Reported by: bz
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/elf_trampoline.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index 379bc32..62d0db5 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/armreg.h>
#include <machine/vmparam.h> /* For KERNVIRTADDR */
+#include <machine/cpu.h>
extern char kernel_start[];
extern char kernel_end[];
@@ -48,7 +49,7 @@ extern void *_end;
void _start(void);
void __start(void);
-void __startC(void);
+void __startC(unsigned r0, unsigned r1, unsigned r2, unsigned r3);
extern unsigned int cpu_ident(void);
extern void armv6_idcache_wbinv_all(void);
@@ -125,6 +126,10 @@ static int arm_dcache_l2_nsets;
static int arm_dcache_l2_assoc;
static int arm_dcache_l2_linesize;
+/*
+ * Boot parameters
+ */
+static struct arm_boot_params s_boot_params;
extern int arm9_dcache_sets_inc;
extern int arm9_dcache_sets_max;
@@ -173,12 +178,17 @@ bzero(void *addr, int count)
static void arm9_setup(void);
void
-_startC(void)
+_startC(unsigned r0, unsigned r1, unsigned r2, unsigned r3)
{
int tmp1;
unsigned int sp = ((unsigned int)&_end & ~3) + 4;
unsigned int pc, kernphysaddr;
+ s_boot_params.abp_r0 = r0;
+ s_boot_params.abp_r1 = r1;
+ s_boot_params.abp_r2 = r2;
+ s_boot_params.abp_r3 = r3;
+
/*
* Figure out the physical address the kernel was loaded at. This
* assumes the entry point (this code right here) is in the first page,
@@ -212,8 +222,15 @@ _startC(void)
/* Temporary set the sp and jump to the new location. */
__asm __volatile(
"mov sp, %1\n"
+ "mov r0, %2\n"
+ "mov r1, %3\n"
+ "mov r2, %4\n"
+ "mov r3, %5\n"
"mov pc, %0\n"
- : : "r" (target_addr), "r" (tmp_sp));
+ : : "r" (target_addr), "r" (tmp_sp),
+ "r" (s_boot_params.abp_r0), "r" (s_boot_params.abp_r1),
+ "r" (s_boot_params.abp_r2), "r" (s_boot_params.abp_r3)
+ : "r0", "r1", "r2", "r3");
}
#endif
@@ -488,6 +505,7 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
vm_offset_t lastaddr = 0;
Elf_Addr ssym = 0;
Elf_Dyn *dp;
+ struct arm_boot_params local_boot_params;
eh = (Elf32_Ehdr *)kstart;
ssym = 0;
@@ -556,6 +574,12 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
if (!d)
return ((void *)lastaddr);
+ /*
+ * Now the stack is fixed, copy boot params
+ * before it's overrided
+ */
+ memcpy(&local_boot_params, &s_boot_params, sizeof(local_boot_params));
+
j = eh->e_phnum;
for (i = 0; i < j; i++) {
volatile char c;
@@ -605,7 +629,10 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
"mcr p15, 0, %0, c1, c0, 0\n" /* CP15_SCTLR(%0)*/
: "=r" (ssym));
/* Jump to the entry point. */
- ((void(*)(void))(entry_point - KERNVIRTADDR + curaddr))();
+ ((void(*)(unsigned, unsigned, unsigned, unsigned))
+ (entry_point - KERNVIRTADDR + curaddr))
+ (local_boot_params.abp_r0, local_boot_params.abp_r1,
+ local_boot_params.abp_r2, local_boot_params.abp_r3);
__asm __volatile(".globl func_end\n"
"func_end:");
OpenPOWER on IntegriCloud