diff options
author | gonzo <gonzo@FreeBSD.org> | 2018-04-02 22:16:19 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2018-04-02 22:16:19 +0000 |
commit | 522277038a84aca4ccfd4ff19563022420f4b376 (patch) | |
tree | f81fe13044e80a6d093bf6a26a7ad434d04fd3a7 /sys/arm | |
parent | e6a33cf67e3d25ec186eaf10582b887c9a11b833 (diff) | |
download | FreeBSD-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.c | 35 |
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:"); |