1/*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Email: opensource_embedded@phytium.com.cn
7 *
8 * Change Logs:
9 * Date        Author       Notes
10 * 2022-10-26  huanghe       first commit
11 * 2023-07-27  zhugengyu     flush cache in aarch64-el2
12 *
13 */
14
15.global _boot
16.set FPEXC_EN,		0x40000000		/* FPU enable bit, (1 << 30) */
17.org 0
18.text
19
20.section .boot,"ax"
21
22_boot:
23 	/* hard code aarch64 instruction to flush dcache, refer to rt-thread __asm_flush_dcache_all */
24	.long 0xd2800000	/* mov	x0, #0x0 // clean and invaildate d-cache */
25	.long 0x1400001a	/* b	<InvalidateFlushDcaches> */
26
27InvalidateFlushDcacheLevel:
28	.long 0xd37ff80c	/* lsl	x12, x0, #1 */
29	.long 0xd51a000c	/* msr	csselr_el1, x12 */
30	.long 0xd5033fdf	/* isb */
31	.long 0xd5390006	/* mrs	x6, ccsidr_el1 */
32	.long 0x924008c2	/* and	x2, x6, #0x7 */
33	.long 0x91001042	/* add	x2, x2, #0x4 */
34	.long 0xd2807fe3	/* mov	x3, #0x3ff */
35	.long 0x8a460c63	/* and	x3, x3, x6, lsr #3 */
36	.long 0x5ac01065	/* clz	w5, w3 */
37	.long 0xd28fffe4	/* mov	x4, #0x7fff */
38	.long 0x8a463484	/* and	x4, x4, x6, lsr #13 */
39
40InvalidateFlushCacheSet:
41	.long 0xaa0303e6	/* mov	x6, x3 */
42
43InvalidateFlushCacheWay:
44	.long 0x9ac520c7	/* lsl	x7, x6, x5 */
45	.long 0xaa070189	/* orr	x9, x12, x7 */
46	.long 0x9ac22087	/* lsl	x7, x4, x2 */
47	.long 0xaa070129	/* orr	x9, x9, x7 */
48	.long 0x36000061	/* tbz	w1, #0, <InvalidateFlushCacheWay+0x1c> */
49	.long 0xd5087649	/* dc	isw, x9 */
50	.long 0x14000002	/* b	<InvalidateFlushCacheWay+0x20> */
51	.long 0xd5087e49	/* dc	cisw, x9 */
52	.long 0xf10004c6	/* subs	x6, x6, #0x1 */
53	.long 0x54fffeea	/* b.ge	 <InvalidateFlushCacheWay> */
54	.long 0xf1000484	/* subs	x4, x4, #0x1 */
55	.long 0x54fffe8a	/* b.ge	 <InvalidateFlushCacheSet> */
56	.long 0xd65f03c0	/* ret */
57
58InvalidateFlushDcaches:
59	.long 0xaa0003e1	/* mov	x1, x0 */
60	.long 0xd5033f9f	/* dsb	sy */
61	.long 0xd539002a	/* mrs	x10, clidr_el1 */
62	.long 0xd358fd4b	/* lsr	x11, x10, #24 */
63	.long 0x9240096b	/* and	x11, x11, #0x7 */
64	.long 0xb400024b	/* cbz	x11, <InvalidateFlushDcacheEnd> */
65	.long 0xaa1e03ef	/* mov	x15, x30 */
66	.long 0xd2800000	/* mov	x0, #0x0 */
67
68InvalidateFlushCachesLoopLevel:
69	.long 0xd37ff80c	/* lsl	x12, x0, #1 */
70	.long 0x8b00018c	/* add	x12, x12, x0 */
71	.long 0x9acc254c	/* lsr	x12, x10, x12 */
72	.long 0x9240098c	/* and	x12, x12, #0x7 */
73	.long 0xf100099f	/* cmp	x12, #0x2 */
74	.long 0x5400004b	/* b.lt	<InvalidateFlushCachesSkipLevel> */
75	.long 0x97ffffd9	/* bl	<InvalidateFlushDcacheLevel> */
76
77InvalidateFlushCachesSkipLevel:
78	.long 0x91000400	/* add	x0, x0, #0x1 */
79	.long 0xeb00017f	/* cmp	x11, x0 */
80	.long 0x54fffeec	/* b.gt	<InvalidateFlushCachesLoopLevel> */
81	.long 0xd2800000	/* mov	x0, #0x0 */
82	.long 0xd51a0000	/* msr	csselr_el1, x0 */
83	.long 0xd5033f9f	/* dsb	sy */
84	.long 0xd5033fdf	/* isb */
85	.long 0xaa0f03fe	/* mov	x30, x15 */
86
87InvalidateFlushDcacheEnd:
88/***************************************************************/
89
90/* switch from aarch64-el2 to aarch32-el1 */
91Startup_Aarch32:
92    .long 0xd5384240 	/* mrs	x0, currentel                      */
93    .long 0xd342fc00 	/* lsr	x0, x0, #2                         */
94    .long 0x92400400 	/* and	x0, x0, #0x3                       */
95    .long 0xf1000c1f 	/* cmp	x0, #0x3                           */
96    .long 0x540003a1 	/* b.ne	1d0080c4 <el2_mode>                */
97
98el3_mode:
99    .long 0xd53ecca0 	/* mrs	x0, s3_6_c12_c12_5 - ICC_SRE_EL3   */
100    .long 0xb2400c00 	/* orr	x0, x0, #0xf                       */
101    .long 0xd51ecca0 	/* msr	s3_6_c12_c12_5, x0                 */
102    .long 0xd5033fdf 	/* isb                                     */
103    .long 0xd53cc9a0 	/* mrs	x0, s3_4_c12_c9_5 - ICC_SRE_EL2    */
104    .long 0xb2400c00 	/* orr	x0, x0, #0xf                       */
105    .long 0xd51cc9a0 	/* msr	s3_4_c12_c9_5, x0                  */
106    .long 0xd5033fdf 	/* isb                                     */
107    .long 0xd538cca0 	/* mrs	x0, s3_0_c12_c12_5 - ICC_SRE_EL1   */
108    .long 0xb2400000 	/* orr	x0, x0, #0x1                       */
109    .long 0xd518cca0 	/* msr	s3_0_c12_c12_5, x0                 */
110    .long 0xd5033fdf 	/* isb                                     */
111
112    .long 0xd2803620 	/* mov	x0, #0x1b1                         */
113    .long 0xd51e1100 	/* msr	scr_el3, x0                        */
114    .long 0xd2867fe0 	/* mov	x0, #0x33ff                        */
115    .long 0xd51c1140 	/* msr	cptr_el2, x0                       */
116    .long 0xd2810000 	/* mov	x0, #0x800                         */
117    .long 0xf2a61a00 	/* movk	x0, #0x30d0, lsl #16               */
118    .long 0xd5181000 	/* msr	sctlr_el1, x0                      */
119    .long 0x910003e0 	/* mov	x0, sp                             */
120    .long 0xd51c4100 	/* msr	sp_el1, x0                         */
121    .long 0xd53ec000 	/* mrs	x0, vbar_el3                       */
122    .long 0xd518c000 	/* msr	vbar_el1, x0                       */
123    .long 0xd2803a60 	/* mov	x0, #0x1d3                         */
124    .long 0xd51e4000 	/* msr	spsr_el3, x0                       */
125    .long 0x10000500 	/* adr	x0, 1d008158 <el1_mode>            */
126    .long 0xd51e4020 	/* msr	elr_el3, x0                        */
127    .long 0xd69f03e0 	/* eret                                    */
128
129el2_mode:
130    .long 0xd53cc9a0 	/* mrs	x0, s3_4_c12_c9_5 - ICC_SRE_EL2    */
131    .long 0xb2400c00 	/* orr	x0, x0, #0xf                       */
132    .long 0xd51cc9a0 	/* msr	s3_4_c12_c9_5, x0                  */
133    .long 0xd5033fdf 	/* isb                                     */
134    .long 0xd538cca0 	/* mrs	x0, s3_0_c12_c12_5 - ICC_SRE_EL1   */
135    .long 0xb2400000 	/* orr	x0, x0, #0x1                       */
136    .long 0xd518cca0 	/* msr	s3_0_c12_c12_5, x0                 */
137    .long 0xd5033fdf 	/* isb                                     */
138    .long 0xd53ce100 	/* mrs	x0, cnthctl_el2                    */
139    .long 0xb2400400 	/* orr	x0, x0, #0x3                       */
140    .long 0xd51ce100 	/* msr	cnthctl_el2, x0                    */
141    .long 0xd51ce07f 	/* msr	cntvoff_el2, xzr                   */
142    .long 0xd5380000 	/* mrs	x0, midr_el1                       */
143    .long 0xd53800a1 	/* mrs	x1, mpidr_el1                      */
144    .long 0xd51c0000 	/* msr	vpidr_el2, x0                      */
145    .long 0xd51c00a1 	/* msr	vmpidr_el2, x1                     */
146    .long 0xd2867fe0 	/* mov	x0, #0x33ff                        */
147    .long 0xd51c1140 	/* msr	cptr_el2, x0                       */
148    .long 0xd51c117f 	/* msr	hstr_el2, xzr                      */
149    .long 0xd2a00600 	/* mov	x0, #0x300000                      */
150    .long 0xd5181040 	/* msr	cpacr_el1, x0                      */
151    .long 0xd2800000 	/* mov	x0, #0x0                           */
152    .long 0xb2630000 	/* orr	x0, x0, #0x20000000                */
153    .long 0xd51c1100 	/* msr	hcr_el2, x0                        */
154    .long 0xd53c1100 	/* mrs	x0, hcr_el2                        */
155    .long 0xd2810000 	/* mov	x0, #0x800                         */
156    .long 0xf2a61a00 	/* movk	x0, #0x30d0, lsl #16               */
157    .long 0xd5181000 	/* msr	sctlr_el1, x0                      */
158    .long 0x910003e0 	/* mov	x0, sp                             */
159    .long 0xd51c4100 	/* msr	sp_el1, x0                         */
160    .long 0xd53cc000 	/* mrs	x0, vbar_el2                       */
161    .long 0xd518c000 	/* msr	vbar_el1, x0                       */
162    .long 0xd2803a60 	/* mov	x0, #0x1d3                         */
163    .long 0xd51c4000 	/* msr	spsr_el2, x0                       */
164    .long 0x10000060 	/* adr	x0, 1d008158 <el1_mode>            */
165    .long 0xd51c4020 	/* msr	elr_el2, x0                        */
166    .long 0xd69f03e0 	/* eret                                    */
167
168el1_mode:
169    mov      r0, #0
170    mov      r1, #0
171    mov      r2, #0
172    mov      r3, #0
173    mov      r4, #0
174    mov      r5, #0
175    mov      r6, #0
176    mov      r7, #0
177    mov      r8, #0
178    mov      r9, #0
179    mov      r10, #0
180    mov      r11, #0
181    mov      r12, #0
182    mcr      p15, 0, r0, c1, c0, 0  /* reset control register */
183    isb
184
185    /* enable vfp, therefore f_prink workable */
186    vmrs	r1, FPEXC			/* read the exception register */
187    orr	    r1,r1, #FPEXC_EN	/* set VFP enable bit, leave the others in orig state */
188    vmsr	FPEXC, r1			/* write back the exception register */
189
190    bl      system_vectors      /* jump to libcpu/arm/cortex-a/vector_gcc.S */
191
192