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