Changeset View
Standalone View
sys/boot/arm64/uboot/start.S
/*- | |||||
* Copyright (c) 2016 Thomas Skibo <skibo@freebsd.org> | |||||
* Copyright (c) 2008 Semihalf, Rafal Czubak | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* $FreeBSD$ | |||||
*/ | |||||
#include <machine/asm.h> | |||||
#include <machine/armreg.h> | |||||
.text | |||||
.extern _C_LABEL(self_reloc), _C_LABEL(main) | |||||
.weak _DYNAMIC | |||||
/* | |||||
* Entry point to the loader that U-Boot passes control to. | |||||
*/ | |||||
.globl _start | |||||
_start: | |||||
/* Do self-relocation if this external symbol reference has not been | |||||
* filled in the literal pool. | |||||
*/ | |||||
ldr x0, =_C_LABEL(self_reloc) | |||||
cbnz x0, 2f | |||||
adr x0, ImageBase /* x0 = addr where we were loaded. */ | |||||
adr x1, _DYNAMIC /* x1 = dynamic section addr. */ | |||||
bl _C_LABEL(self_reloc) | |||||
2: | |||||
/* Hint where to look for the API signature */ | |||||
skibo: Sorry, destroyed this comment. Will fix. | |||||
adr x15, uboot_address | |||||
mov x0, sp | |||||
str x0, [x15] | |||||
/* Save U-Boot's x18 */ | |||||
adr x15, saved_regs | |||||
str x18, [x15, #0] | |||||
/* | |||||
* Start loader. This is basically a tail-recursion call; if main() | |||||
* returns, it returns to u-boot (which reports the value returned x0). | |||||
*/ | |||||
b main | |||||
/* | |||||
* syscall() | |||||
*/ | |||||
ENTRY(syscall) | |||||
/* Save caller's lr, x18 */ | |||||
adr x15, saved_regs | |||||
str x18, [x15, #8] | |||||
str lr, [x15, #16] | |||||
/* Restore U-Boot's x18 */ | |||||
ldr x18, saved_regs | |||||
/* Call into U-Boot */ | |||||
adr lr, return_from_syscall | |||||
ldr x15, syscall_ptr | |||||
br x15 | |||||
return_from_syscall: | |||||
/* Restore loader's x18 and lr */ | |||||
Not Done Inline ActionsI can't get the position independent ubldr.pie to work because the linker leaves zeros in these locations. In the arm version, these locations are filled with offsets. Without the value of __DYNAMIC I don't know how to find the relocation data to pass to self_reloc(). skibo: I can't get the position independent ubldr.pie to work because the linker leaves zeros in these… | |||||
Not Done Inline ActionsOkay, I think I know what's going on. In aarch64, relocation data is stored in Elf64_Rela entries whereas arm uses Elf32_Rel entries (no addend field). In arm, the offsets go into the locations to be adjusted whereas in aarch64, the offsets go into the addend field in the entries in the relocation table and zeros go into locations that need to be adjusted. Any ideas how I could find the location of the dynamic section from within here so I can call self_reloc()? skibo: Okay, I think I know what's going on. In aarch64, relocation data is stored in Elf64_Rela… | |||||
Not Done Inline ActionsHave you looked at the efi code? It's a lot simpler than this, and has been tested on various hardware. andrew: Have you looked at the efi code? It's a lot simpler than this, and has been tested on various… | |||||
Not Done Inline ActionsThanks! I got it to work. So we should just build a relocatable ubldr only. skibo: Thanks! I got it to work. So we should just build a relocatable ubldr only. | |||||
ldr lr, saved_regs + 16 | |||||
ldr x18, saved_regs + 8 | |||||
/* Return to caller */ | |||||
ret | |||||
/* | |||||
* Data section | |||||
*/ | |||||
.data | |||||
.align 3 | |||||
.globl syscall_ptr | |||||
syscall_ptr: | |||||
.quad 0 | |||||
.globl uboot_address | |||||
uboot_address: | |||||
.quad 0 | |||||
saved_regs: | |||||
.quad 0 /* U-Boot's x18 */ | |||||
.quad 0 /* Loader's x18 */ | |||||
.quad 0 /* Loader's lr */ |
Sorry, destroyed this comment. Will fix.