Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/elf_trampoline.c
Context not available. | |||||
#include <machine/pte-v4.h> | #include <machine/pte-v4.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/armreg.h> | #include <machine/armreg.h> | ||||
#include <machine/cpu.h> | |||||
extern char kernel_start[]; | extern char kernel_start[]; | ||||
extern char kernel_end[]; | extern char kernel_end[]; | ||||
Context not available. | |||||
void _start(void); | void _start(void); | ||||
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 unsigned int cpu_ident(void); | ||||
extern void armv6_idcache_wbinv_all(void); | extern void armv6_idcache_wbinv_all(void); | ||||
Context not available. | |||||
static int arm_dcache_l2_assoc; | static int arm_dcache_l2_assoc; | ||||
static int arm_dcache_l2_linesize; | 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_inc; | ||||
extern int arm9_dcache_sets_max; | extern int arm9_dcache_sets_max; | ||||
Context not available. | |||||
static void get_cachetype_cp15(); | static void get_cachetype_cp15(); | ||||
void | void | ||||
_startC(void) | _startC(unsigned r0, unsigned r1, unsigned r2, unsigned r3) | ||||
{ | { | ||||
int tmp1; | int tmp1; | ||||
unsigned int sp = ((unsigned int)&_end & ~3) + 4; | unsigned int sp = ((unsigned int)&_end & ~3) + 4; | ||||
unsigned int pc, kernphysaddr; | 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 | * Figure out the physical address the kernel was loaded at. This | ||||
* assumes the entry point (this code right here) is in the first page, | * assumes the entry point (this code right here) is in the first page, | ||||
Context not available. | |||||
/* Temporary set the sp and jump to the new location. */ | /* Temporary set the sp and jump to the new location. */ | ||||
__asm __volatile( | __asm __volatile( | ||||
"mov sp, %1\n" | "mov sp, %1\n" | ||||
"mov r0, %2\n" | |||||
"mov r1, %3\n" | |||||
"mov r2, %4\n" | |||||
"mov r3, %5\n" | |||||
"mov pc, %0\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 | #endif | ||||
Context not available. | |||||
vm_offset_t lastaddr = 0; | vm_offset_t lastaddr = 0; | ||||
Elf_Addr ssym = 0; | Elf_Addr ssym = 0; | ||||
Elf_Dyn *dp; | Elf_Dyn *dp; | ||||
struct arm_boot_params local_boot_params; | |||||
eh = (Elf32_Ehdr *)kstart; | eh = (Elf32_Ehdr *)kstart; | ||||
ssym = 0; | ssym = 0; | ||||
Context not available. | |||||
if (!d) | if (!d) | ||||
return ((void *)lastaddr); | 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; | j = eh->e_phnum; | ||||
for (i = 0; i < j; i++) { | for (i = 0; i < j; i++) { | ||||
volatile char c; | volatile char c; | ||||
Context not available. | |||||
"mcr p15, 0, %0, c1, c0, 0\n" /* CP15_SCTLR(%0)*/ | "mcr p15, 0, %0, c1, c0, 0\n" /* CP15_SCTLR(%0)*/ | ||||
: "=r" (ssym)); | : "=r" (ssym)); | ||||
/* Jump to the entry point. */ | /* 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" | __asm __volatile(".globl func_end\n" | ||||
"func_end:"); | "func_end:"); | ||||
Context not available. |