First version
[3rdparty/ote_partner/tlk.git] / lib / monitor / arm64 / monitor_start.S
1 /*
2  * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <config.h>
24 #include <asm.h>
25 #include <arch/arm.h>
26 #include <arm64/asm.h>
27
28 /* vector entry points */
29 .macro  vec_entry, label
30         .align  7
31         b       \label
32 .endm
33 .macro  vec_entry_null
34         .align  7
35         b       .
36 .endm
37
38 .section ".text.boot"
39 .align 11
40
41 /*
42  * Vector offset 0x000 - 0x180 (from Current EL, using SP_EL0)
43  */
44 FUNCTION(_start)
45 FUNCTION(_vector_el3)
46
47         /* entry point */
48         vec_entry       _reset
49
50         /* EL3 exception to EL3 (SP_EL0) unexpected */
51         vec_entry_null          /* IRQ exc SP_EL0 */
52         vec_entry_null          /* FIQ exc SP_EL0 */
53         vec_entry_null          /* SERR exc SP_EL0 */
54
55 /*
56  * Vector offset 0x200 - 0x380 (from Current EL, using SP_ELx)
57  */
58 .align 9
59         /* EL3 exception to EL3 (SP_ELx) unexpected */
60         vec_entry_null          /* sync exc SP_ELx */
61         vec_entry_null          /* IRQ exc SP_ELx */
62         vec_entry_null          /* FIQ exc SP_ELx */
63         vec_entry_null          /* SERR exc SP_ELx */
64
65 /*
66  * Vector offset 0x400 - 0x580 (from Lower EL, using AArch64)
67  */
68 .align 9
69         /* EL1 exception to EL3 (AArch64) */
70         vec_entry       handle_exc_aarch64
71         vec_entry_null                  /* IRQ exc aarch64  - unexpected in EL3 */
72         vec_entry_null                  /* FIQ exc aarch64  - unexpected in EL3 */
73         vec_entry_null                  /* SERR exc aarch64 - unexpected in EL3 */
74
75 /*
76  * Vector offset 0x600 - 0x580 (from Lower EL, using AArch32)
77  */
78 .align 9
79         /* EL1 exception to EL3 (AArch32) */
80         vec_entry       handle_exc_aarch32
81         vec_entry_null          /* IRQ exc aarch32 */
82         vec_entry_null          /* FIQ exc aarch32 */
83         vec_entry_null          /* SERR exc aarch32 */
84
85 /* void mon_clear_bss(void) */
86 FUNCTION(mon_clear_bss)
87         ldr     x0, =__bss_start
88         ldr     x1, =__bss_end
89         subs    x1, x1, x0              /* size in bytes */
90         b.eq    2f
91 1:
92         strb    wzr, [x0], #1
93         sub     x1, x1, #1
94         cbnz    x1, 1b
95 2:
96         ret
97
98 /*
99  * Set up initial registers and transition to EL1 to start the
100  * secureos (no args are passed to this routine and it does not
101  * return).
102  */
103 FUNCTION(mon_start_tlk_el1)
104         /* entry into EL1 is at _end of monitor binary */
105         ldr     x6, __mon_phys_offset
106         adr     x4, _end
107         sub     x5, x4, x6      // phys addr of _end
108
109         /* adjust carveout (reduced by what monitor's used) */
110         adr     x3, __mon_phys_size
111         ldr     w0, [x3]
112         adr     x4, _start
113         sub     x7, x4, x6      // phys addr of _start
114         sub     x3, x5, x7      // amount used by monitor
115         sub     w0, w0, w3      // reduced size
116
117         /* size and bootarg passed as 32bit args */
118         adr     x3, __mon_bootarg_addr
119         ldr     w1, [x3]
120
121         mon_scr_secure_32 x3
122
123         ldr     x3, =MON_INIT_EL1_SPSR_AARCH32
124         msr     spsr_el3, x3
125         msr     elr_el3, x5
126         eret
127
128 /*
129  * Entry from the bootloader.
130  *
131  * Assuming for now the BL will jump to our _start rather than exception
132  * to us (though the latter is doable, given our entry point is where
133  * VBAR_EL3 would be setup, so could SMC to us).
134  *
135  * Setup state so we can return from the EL3 "exception" by pushing
136  * the needed state onto the stack (popped during go_nonsecure).
137  */
138 _reset:
139         /* derive/save the phys_base addr */
140         adr     x9, (. + 0x4)
141         sub     x10, x9, #(. - _start)
142         adr     x3, __mon_phys_base
143         str     x10, [x3]               // physbase
144
145         /* save mon_phys_offset (v -> p conversions) */
146         adr     x4, __mon_phys_offset
147         ldr     x5, =MONBASE
148         sub     x11, x5, x10
149         str     x11, [x4]               // physoff
150
151         /* save per-cpu return addr (from LR) */
152         cpuidx  x4
153         adr     x5, __mon_cpu_return_addr
154         str     lr, [x5, x4, lsl #3]
155
156         /*
157          * All secondaries, init their CPU state and then return,
158          * while only the primary continues on to init the OS. For
159          * now, this means only CPU0 can run within the secureos.
160          */
161         cbnz    x4, boot_secondary
162
163         /* save carveout size and bootarg ptr */
164         adr     x3, __mon_phys_size
165         str     x0, [x3]
166         mov     x2, x0                  // make copy
167         adr     x3, __mon_bootarg_addr
168         str     x1, [x3]
169
170         bl      mon_init_cpu
171
172         /* setup MMU pagetables, (args: base, off, size) */
173         mov     x0, x10
174         mov     x1, x11
175         bl      mon_setup_pagetable
176
177         /* enable MMU */
178         bl      mon_enable_mmu
179
180         /* reload vbar with virtual address */
181         adr     x0, _vector_el3
182         msr     vbar_el3, x0
183         isb
184
185         bl      mon_clear_bss
186
187         cpuidx  x0
188         bl      platform_psci_init
189         b       mon_start_tlk_el1
190
191 .ltorg
192 .align 3
193 /*
194  * Keep location of where the image was loaded, and how much
195  * contiguous memory has been made available.
196  */
197 .global __mon_phys_base
198 __mon_phys_base:
199         .quad 0
200
201 .global __mon_phys_size
202 __mon_phys_size:
203         .quad 0
204
205 __mon_bootarg_addr:
206         .quad 0
207
208 .data
209 .align 4
210 /* stack must be 16 byte aligned */
211 monitor_stack:
212         .skip 4096
213 .global monitor_stack_top
214 monitor_stack_top: