source: mainline/kernel/arch/arm64/src/asm.S

Last change on this file was ebb3538, checked in by Martin Decky <martin@…>, 4 years ago

Improve early kernel debugging prints

Since the early kernel debugging prints are useful only in a few
debugging scenarios, define a configuration option that disables them by
default (if enabled, it produces duplicate output which might be
confusing).

Implement early kernel debugging prints for the HiKey960.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2015 Petr Pavlu
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <abi/asmtool.h>
30#include <arch/exception.h>
31#include <arch/istate_struct.h>
32
33.text
34
35FUNCTION_BEGIN(memcpy_from_uspace)
36FUNCTION_BEGIN(memcpy_to_uspace)
37 /* Simple (un-optimized) memcpy(). */
38 cbz x2, 2f
39 mov x3, x0
401:
41 ldrb w4, [x1], #1
42 strb w4, [x3], #1
43 subs x2, x2, #1
44 b.ne 1b
45
462:
47 ret
48FUNCTION_END(memcpy_from_uspace)
49FUNCTION_END(memcpy_to_uspace)
50
51FUNCTION_BEGIN(memcpy_from_uspace_failover_address)
52FUNCTION_BEGIN(memcpy_to_uspace_failover_address)
53 mov x0, #0
54 ret
55FUNCTION_END(memcpy_from_uspace_failover_address)
56FUNCTION_END(memcpy_to_uspace_failover_address)
57
58/** Flush instruction caches
59 *
60 * @param x0 Starting address of the flushing.
61 * @param x1 Number of bytes to flush.
62 *
63 */
64FUNCTION_BEGIN(smc_coherence)
65 /* Initialize loop */
66 mov x9, x0
67 mov x10, xzr
68
69 __dc_loop:
70 /* Data or Unified Cache Line Clean */
71 dc cvau, x9
72 add x9, x9, #4
73 add x10, x10, #4
74 cmp x10, x1
75 blo __dc_loop
76
77 dsb ish
78
79 /* Initialize loop */
80 mov x9, x0
81 mov x10, xzr
82
83 __ic_loop:
84 /* Instruction Cache Line Invalidate */
85 ic ivau, x9
86 add x9, x9, #4
87 add x10, x10, #4
88 cmp x10, x1
89 blo __ic_loop
90
91 dsb ish
92 isb
93 ret
94FUNCTION_END(smc_coherence)
95
96/* Static checks for the istate_t save/load. */
97#if ISTATE_OFFSET_X0 + 8 != ISTATE_OFFSET_X1
98#error x0 and x1 are not successive in istate_t
99#endif
100#if ISTATE_OFFSET_X2 + 8 != ISTATE_OFFSET_X3
101#error x2 and x3 are not successive in istate_t
102#endif
103#if ISTATE_OFFSET_X4 + 8 != ISTATE_OFFSET_X5
104#error x4 and x5 are not successive in istate_t
105#endif
106#if ISTATE_OFFSET_X6 + 8 != ISTATE_OFFSET_X7
107#error x6 and x7 are not successive in istate_t
108#endif
109#if ISTATE_OFFSET_X8 + 8 != ISTATE_OFFSET_X9
110#error x8 and x9 are not successive in istate_t
111#endif
112#if ISTATE_OFFSET_X10 + 8 != ISTATE_OFFSET_X11
113#error x10 and x11 are not successive in istate_t
114#endif
115#if ISTATE_OFFSET_X12 + 8 != ISTATE_OFFSET_X13
116#error x12 and x13 are not successive in istate_t
117#endif
118#if ISTATE_OFFSET_X14 + 8 != ISTATE_OFFSET_X15
119#error x14 and x15 are not successive in istate_t
120#endif
121#if ISTATE_OFFSET_X16 + 8 != ISTATE_OFFSET_X17
122#error x16 and x17 are not successive in istate_t
123#endif
124#if ISTATE_OFFSET_X18 + 8 != ISTATE_OFFSET_X19
125#error x18 and x19 are not successive in istate_t
126#endif
127#if ISTATE_OFFSET_X20 + 8 != ISTATE_OFFSET_X21
128#error x20 and x21 are not successive in istate_t
129#endif
130#if ISTATE_OFFSET_X22 + 8 != ISTATE_OFFSET_X23
131#error x22 and x23 are not successive in istate_t
132#endif
133#if ISTATE_OFFSET_X24 + 8 != ISTATE_OFFSET_X25
134#error x24 and x25 are not successive in istate_t
135#endif
136#if ISTATE_OFFSET_X26 + 8 != ISTATE_OFFSET_X27
137#error x26 and x27 are not successive in istate_t
138#endif
139#if ISTATE_OFFSET_X28 + 8 != ISTATE_OFFSET_X29
140#error x28 and x29 are not successive in istate_t
141#endif
142#if ISTATE_OFFSET_SPSR + 8 != ISTATE_OFFSET_SP
143#error spsr and sp are not successive in istate_t
144#endif
145#if ISTATE_OFFSET_PC + 8 != ISTATE_OFFSET_TPIDR
146#error pc and tpidr are not successive in istate_t
147#endif
148
149/* Exception vector. */
150.macro handler i
151handler_\i:
152 /*
153 * Initial code for each handler, at maximum 128 bytes (32
154 * instructions).
155 */
156
157 /* Save current state. */
158 sub sp, sp, #ISTATE_SIZE /* 0x00 */
159 stp x0, x1, [sp, #ISTATE_OFFSET_X0] /* 0x04 */
160 stp x2, x3, [sp, #ISTATE_OFFSET_X2] /* 0x08 */
161 stp x4, x5, [sp, #ISTATE_OFFSET_X4] /* 0x0c */
162 stp x6, x7, [sp, #ISTATE_OFFSET_X6] /* 0x10 */
163 stp x8, x9, [sp, #ISTATE_OFFSET_X8] /* 0x14 */
164 stp x10, x11, [sp, #ISTATE_OFFSET_X10] /* 0x18 */
165 stp x12, x13, [sp, #ISTATE_OFFSET_X12] /* 0x1c */
166 stp x14, x15, [sp, #ISTATE_OFFSET_X14] /* 0x20 */
167 stp x16, x17, [sp, #ISTATE_OFFSET_X16] /* 0x24 */
168 stp x18, x19, [sp, #ISTATE_OFFSET_X18] /* 0x28 */
169 stp x20, x21, [sp, #ISTATE_OFFSET_X20] /* 0x2c */
170 stp x22, x23, [sp, #ISTATE_OFFSET_X22] /* 0x30 */
171 stp x24, x25, [sp, #ISTATE_OFFSET_X24] /* 0x34 */
172 stp x26, x27, [sp, #ISTATE_OFFSET_X26] /* 0x38 */
173 stp x28, x29, [sp, #ISTATE_OFFSET_X28] /* 0x3c */
174 str x30, [sp, #ISTATE_OFFSET_X30] /* 0x40 */
175
176 mrs x0, spsr_el1 /* 0x44 */
177 mrs x1, sp_el0 /* 0x48 */
178 stp x0, x1, [sp, #ISTATE_OFFSET_SPSR] /* 0x4c */
179
180 mrs x0, elr_el1 /* 0x50 */
181 mrs x1, tpidr_el0 /* 0x54 */
182 stp x0, x1, [sp, #ISTATE_OFFSET_PC] /* 0x58 */
183
184 mov x0, #\i /* 0x5c */
185 mov x1, sp /* 0x60 */
186 bl exc_dispatch /* 0x64 */
187
188 /* Restore previous state. */
189 ldp x0, x1, [sp, #ISTATE_OFFSET_SPSR] /* 0x68 */
190 msr spsr_el1, x0 /* 0x6c */
191 msr sp_el0, x1 /* 0x70 */
192
193 ldp x0, x1, [sp, #ISTATE_OFFSET_PC] /* 0x74 */
194 msr elr_el1, x0 /* 0x78 */
195 b exc_restore_end /* 0x7c */
196.endm
197
198exc_restore_end:
199 /* Restore remaining registers and return from the exception handler. */
200 msr tpidr_el0, x1
201 ldp x0, x1, [sp, #ISTATE_OFFSET_X0]
202 ldp x2, x3, [sp, #ISTATE_OFFSET_X2]
203 ldp x4, x5, [sp, #ISTATE_OFFSET_X4]
204 ldp x6, x7, [sp, #ISTATE_OFFSET_X6]
205 ldp x8, x9, [sp, #ISTATE_OFFSET_X8]
206 ldp x10, x11, [sp, #ISTATE_OFFSET_X10]
207 ldp x12, x13, [sp, #ISTATE_OFFSET_X12]
208 ldp x14, x15, [sp, #ISTATE_OFFSET_X14]
209 ldp x16, x17, [sp, #ISTATE_OFFSET_X16]
210 ldp x18, x19, [sp, #ISTATE_OFFSET_X18]
211 ldp x20, x21, [sp, #ISTATE_OFFSET_X20]
212 ldp x22, x23, [sp, #ISTATE_OFFSET_X22]
213 ldp x24, x25, [sp, #ISTATE_OFFSET_X24]
214 ldp x26, x27, [sp, #ISTATE_OFFSET_X26]
215 ldp x28, x29, [sp, #ISTATE_OFFSET_X28]
216 ldr x30, [sp, #ISTATE_OFFSET_X30]
217 add sp, sp, #ISTATE_SIZE
218 eret
219
220.align 11
221SYMBOL(exc_vector)
222.org exc_vector + 0x000
223 handler EXC_CURRENT_EL_SP_SEL0_SYNCH
224.org exc_vector + 0x080
225 handler EXC_CURRENT_EL_SP_SEL0_IRQ
226.org exc_vector + 0x100
227 handler EXC_CURRENT_EL_SP_SEL0_FIQ
228.org exc_vector + 0x180
229 handler EXC_CURRENT_EL_SP_SEL0_SERROR
230.org exc_vector + 0x200
231 handler EXC_CURRENT_EL_SP_SELX_SYNCH
232.org exc_vector + 0x280
233 handler EXC_CURRENT_EL_SP_SELX_IRQ
234.org exc_vector + 0x300
235 handler EXC_CURRENT_EL_SP_SELX_FIQ
236.org exc_vector + 0x380
237 handler EXC_CURRENT_EL_SP_SELX_SERROR
238.org exc_vector + 0x400
239 handler EXC_LOWER_EL_AARCH64_SYNCH
240.org exc_vector + 0x480
241 handler EXC_LOWER_EL_AARCH64_IRQ
242.org exc_vector + 0x500
243 handler EXC_LOWER_EL_AARCH64_FIQ
244.org exc_vector + 0x580
245 handler EXC_LOWER_EL_AARCH64_SERROR
246.org exc_vector + 0x600
247 handler EXC_LOWER_EL_AARCH32_SYNCH
248.org exc_vector + 0x680
249 handler EXC_LOWER_EL_AARCH32_IRQ
250.org exc_vector + 0x700
251 handler EXC_LOWER_EL_AARCH32_FIQ
252.org exc_vector + 0x780
253 handler EXC_LOWER_EL_AARCH32_SERROR
254.org exc_vector + 0x800
Note: See TracBrowser for help on using the repository browser.