1*4a5d661aSToomas Soome/*- 2*4a5d661aSToomas Soome * Copyright (c) 2008 Semihalf, Rafal Czubak 3*4a5d661aSToomas Soome * All rights reserved. 4*4a5d661aSToomas Soome * 5*4a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 6*4a5d661aSToomas Soome * modification, are permitted provided that the following conditions 7*4a5d661aSToomas Soome * are met: 8*4a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 9*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 10*4a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 11*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 12*4a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 13*4a5d661aSToomas Soome * 14*4a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*4a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*4a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*4a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*4a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*4a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*4a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*4a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*4a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*4a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*4a5d661aSToomas Soome * SUCH DAMAGE. 25*4a5d661aSToomas Soome * 26*4a5d661aSToomas Soome * $FreeBSD$ 27*4a5d661aSToomas Soome */ 28*4a5d661aSToomas Soome 29*4a5d661aSToomas Soome#include <machine/asm.h> 30*4a5d661aSToomas Soome#include <machine/armreg.h> 31*4a5d661aSToomas Soome 32*4a5d661aSToomas Soome .text 33*4a5d661aSToomas Soome .extern _C_LABEL(self_reloc), _C_LABEL(main) 34*4a5d661aSToomas Soome .weak _DYNAMIC 35*4a5d661aSToomas Soome 36*4a5d661aSToomas Soome/* 37*4a5d661aSToomas Soome * Entry point to the loader that U-Boot passes control to. 38*4a5d661aSToomas Soome */ 39*4a5d661aSToomas Soome .globl _start 40*4a5d661aSToomas Soome_start: 41*4a5d661aSToomas Soome 42*4a5d661aSToomas Soome#ifdef _ARM_ARCH_6 43*4a5d661aSToomas Soome mrc p15, 0, ip, c1, c0, 0 44*4a5d661aSToomas Soome orr ip, ip, #(CPU_CONTROL_UNAL_ENABLE) 45*4a5d661aSToomas Soome orr ip, ip, #(CPU_CONTROL_AFLT_ENABLE) 46*4a5d661aSToomas Soome mcr p15, 0, ip, c1, c0, 0 47*4a5d661aSToomas Soome#endif 48*4a5d661aSToomas Soome /* 49*4a5d661aSToomas Soome * Do self-relocation when the weak external symbol _DYNAMIC is non-NULL. 50*4a5d661aSToomas Soome * When linked as a dynamic relocatable file, the linker automatically 51*4a5d661aSToomas Soome * defines _DYNAMIC with a value that is the offset of the dynamic 52*4a5d661aSToomas Soome * relocation info section. 53*4a5d661aSToomas Soome * Note that we're still on u-boot's stack here, but the self_reloc 54*4a5d661aSToomas Soome * code uses only a couple dozen bytes of stack space. 55*4a5d661aSToomas Soome */ 56*4a5d661aSToomas Soome adr ip, .here_off /* .here_off is a symbol whose value */ 57*4a5d661aSToomas Soome ldr r0, [ip] /* is its own offset in the text seg. */ 58*4a5d661aSToomas Soome sub r0, ip, r0 /* Get its pc-relative address and */ 59*4a5d661aSToomas Soome ldr r1, .dynamic_off /* subtract its value and we get */ 60*4a5d661aSToomas Soome teq r1, #0 /* r0 = physaddr we were loaded at. */ 61*4a5d661aSToomas Soome addne r1, r1, r0 /* r1 = dynamic section physaddr. */ 62*4a5d661aSToomas Soome blne _C_LABEL(self_reloc) /* Do reloc if _DYNAMIC is non-NULL. */ 63*4a5d661aSToomas Soome 64*4a5d661aSToomas Soome /* Hint where to look for the API signature */ 65*4a5d661aSToomas Soome ldr ip, =uboot_address 66*4a5d661aSToomas Soome str sp, [ip] 67*4a5d661aSToomas Soome 68*4a5d661aSToomas Soome /* Save U-Boot's r8 and r9 */ 69*4a5d661aSToomas Soome ldr ip, =saved_regs 70*4a5d661aSToomas Soome str r8, [ip, #0] 71*4a5d661aSToomas Soome str r9, [ip, #4] 72*4a5d661aSToomas Soome 73*4a5d661aSToomas Soome /* 74*4a5d661aSToomas Soome * Start loader. This is basically a tail-recursion call; if main() 75*4a5d661aSToomas Soome * returns, it returns to u-boot (which reports the value returned r0). 76*4a5d661aSToomas Soome */ 77*4a5d661aSToomas Soome b main 78*4a5d661aSToomas Soome 79*4a5d661aSToomas Soome /* 80*4a5d661aSToomas Soome * Data for self-relocation, in the text segment for pc-rel access. 81*4a5d661aSToomas Soome */ 82*4a5d661aSToomas Soome.here_off: 83*4a5d661aSToomas Soome .word . 84*4a5d661aSToomas Soome.dynamic_off: 85*4a5d661aSToomas Soome .word _DYNAMIC 86*4a5d661aSToomas Soome 87*4a5d661aSToomas Soome/* 88*4a5d661aSToomas Soome * syscall() 89*4a5d661aSToomas Soome */ 90*4a5d661aSToomas SoomeENTRY(syscall) 91*4a5d661aSToomas Soome /* Save caller's lr, r8 and r9 */ 92*4a5d661aSToomas Soome ldr ip, =saved_regs 93*4a5d661aSToomas Soome str r8, [ip, #8] 94*4a5d661aSToomas Soome str r9, [ip, #12] 95*4a5d661aSToomas Soome str lr, [ip, #16] 96*4a5d661aSToomas Soome /* Restore U-Boot's r8 and r9 */ 97*4a5d661aSToomas Soome ldr r8, [ip, #0] 98*4a5d661aSToomas Soome ldr r9, [ip, #4] 99*4a5d661aSToomas Soome /* Call into U-Boot */ 100*4a5d661aSToomas Soome ldr lr, =return_from_syscall 101*4a5d661aSToomas Soome ldr ip, =syscall_ptr 102*4a5d661aSToomas Soome ldr pc, [ip] 103*4a5d661aSToomas Soomereturn_from_syscall: 104*4a5d661aSToomas Soome /* Restore loader's r8, r9 and lr */ 105*4a5d661aSToomas Soome ldr ip, =saved_regs 106*4a5d661aSToomas Soome ldr lr, [ip, #16] 107*4a5d661aSToomas Soome ldr r9, [ip, #12] 108*4a5d661aSToomas Soome ldr r8, [ip, #8] 109*4a5d661aSToomas Soome /* Return to caller */ 110*4a5d661aSToomas Soome mov pc, lr 111*4a5d661aSToomas Soome 112*4a5d661aSToomas Soome/* 113*4a5d661aSToomas Soome * Data section 114*4a5d661aSToomas Soome */ 115*4a5d661aSToomas Soome .data 116*4a5d661aSToomas Soome .align 4 117*4a5d661aSToomas Soome .globl syscall_ptr 118*4a5d661aSToomas Soomesyscall_ptr: 119*4a5d661aSToomas Soome .long 0 120*4a5d661aSToomas Soome 121*4a5d661aSToomas Soome .globl uboot_address 122*4a5d661aSToomas Soomeuboot_address: 123*4a5d661aSToomas Soome .long 0 124*4a5d661aSToomas Soome 125*4a5d661aSToomas Soomesaved_regs: 126*4a5d661aSToomas Soome .long 0 /* U-Boot's r8 */ 127*4a5d661aSToomas Soome .long 0 /* U-Boot's r9 */ 128*4a5d661aSToomas Soome .long 0 /* Loader's r8 */ 129*4a5d661aSToomas Soome .long 0 /* Loader's r9 */ 130*4a5d661aSToomas Soome .long 0 /* Loader's lr */ 131