]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/boot/arm/uboot/start.S
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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          * Do self-relocation when the weak external symbol _DYNAMIC is non-NULL.
50          * When linked as a dynamic relocatable file, the linker automatically
51          * defines _DYNAMIC with a value that is the offset of the dynamic
52          * relocation info section.
53          * Note that we're still on u-boot's stack here, but the self_reloc 
54          * code uses only a couple dozen bytes of stack space.
55          */
56         adr     ip, .here_off           /* .here_off is a symbol whose value */
57         ldr     r0, [ip]                /* is its own offset in the text seg. */
58         sub     r0, ip, r0              /* Get its pc-relative address and */
59         ldr     r1, .dynamic_off        /* subtract its value and we get */
60         teq     r1, #0                  /* r0 = physaddr we were loaded at. */
61         addne   r1, r1, r0              /* r1 = dynamic section physaddr. */
62         blne    _C_LABEL(self_reloc)    /* Do reloc if _DYNAMIC is non-NULL. */
63
64         /* Hint where to look for the API signature */
65         ldr     ip, =uboot_address
66         str     sp, [ip]
67
68         /* Save U-Boot's r8 and r9 */
69         ldr     ip, =saved_regs
70         str     r8, [ip, #0]
71         str     r9, [ip, #4]
72
73         /* 
74          * Start loader.  This is basically a tail-recursion call; if main()
75          * returns, it returns to u-boot (which reports the value returned r0).
76          */
77         b       main
78
79         /* 
80          * Data for self-relocation, in the text segment for pc-rel access.
81          */
82 .here_off:
83         .word   .
84 .dynamic_off:
85         .word   _DYNAMIC
86
87 /*
88  * syscall()
89  */
90 ENTRY(syscall)
91         /* Save caller's lr, r8 and r9 */
92         ldr     ip, =saved_regs
93         str     r8, [ip, #8]
94         str     r9, [ip, #12]
95         str     lr, [ip, #16]
96         /* Restore U-Boot's r8 and r9 */
97         ldr     r8, [ip, #0]
98         ldr     r9, [ip, #4]
99         /* Call into U-Boot */
100         ldr     lr, =return_from_syscall
101         ldr     ip, =syscall_ptr
102         ldr     pc, [ip]
103 return_from_syscall:
104         /* Restore loader's r8, r9 and lr */
105         ldr     ip, =saved_regs
106         ldr     lr, [ip, #16]
107         ldr     r9, [ip, #12]
108         ldr     r8, [ip, #8]
109         /* Return to caller */
110         mov     pc, lr
111
112 /*
113  * Data section
114  */
115         .data
116         .align  4
117         .globl  syscall_ptr
118 syscall_ptr:
119         .long   0
120
121         .globl  uboot_address
122 uboot_address:
123         .long   0
124
125 saved_regs:
126         .long   0       /* U-Boot's r8 */
127         .long   0       /* U-Boot's r9 */
128         .long   0       /* Loader's r8 */
129         .long   0       /* Loader's r9 */
130         .long   0       /* Loader's lr */