xref: /openbsd-src/sys/arch/arm/arm/cpufunc_asm_armv7.S (revision 8162193374858e8d7dceca506657f13b21b8be44)
1/* $OpenBSD: cpufunc_asm_armv7.S,v 1.19 2022/12/08 01:25:44 guenther Exp $ */
2/*
3 * Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <machine/asm.h>
19#include <arm/armreg.h>
20#include <arm/sysreg.h>
21
22ENTRY(armv7_cpu_sleep)
23	wfi
24	mov	pc, lr
25
26ENTRY(armv7_drain_writebuf)
27	dsb	sy
28	isb	sy
29	mov	pc, lr
30
31/*
32 * Function to read the MPCore base address
33 */
34ENTRY(armv7_periphbase)
35	mrc	CP15_CBAR(r0)
36	mov	pc, lr
37
38/* Suitable default for a uniprocessor kernel. */
39#define TTBR_DEFAULT	(TTBR_IRGN_WBNWA | TTBR_RGN_WBNWA)
40
41/*
42 * Functions to set the MMU Translation Table Base register
43 */
44ENTRY(armv7_setttb)
45	mcr	CP15_ICIALLU		/* Flush I cache */
46	dsb	sy
47	isb	sy
48
49	orr	r0, r0, #TTBR_DEFAULT
50	mcr	CP15_TTBR0(r0)		/* load new TTB */
51	mcr	CP15_TLBIALL(r0)	/* invalidate unified TLB */
52	dsb	sy
53	isb	sy
54
55	mov	pc, lr
56
57/*
58 * TLB functions
59 */
60ENTRY(armv7_tlb_flushID_SE)
61	mcr	CP15_TLBIMVA(r0)	/* flush unified tlb single entry */
62	mcr	CP15_BPIMVA		/* flush va from BP */
63	dsb	sy
64	isb	sy
65	mov	pc, lr
66
67ENTRY(armv7_tlb_flushID)
68	mcr	CP15_TLBIALL(r0)	/* flush unified tlb */
69	mcr	CP15_BPIALL		/* Flush BP cache */
70	dsb	sy
71	isb	sy
72	mov	pc, lr
73
74ENTRY(armv7_tlb_flushD_SE)
75	mcr	CP15_TLBIMVA(r0)	/* flush unified tlb single entry */
76	dsb	sy
77	isb	sy
78	mov	pc, lr
79
80ENTRY(armv7_tlb_flushD)
81	mcr	CP15_TLBIALL(r0)	/* flush unified tlb */
82	dsb	sy
83	isb	sy
84	mov	pc, lr
85
86
87/*
88 * Cache operations.  For the entire cache we use the set/index
89 * operations.
90 */
91.Larmv7_dcache_line_size:
92	.word	arm_dcache_min_line_size
93.Larmv7_icache_line_size:
94	.word	arm_icache_min_line_size
95.Larmv7_idcache_line_size:
96	.word	arm_idcache_min_line_size
97
98	s_max	.req r0
99	i_max	.req r1
100	s_inc	.req r2
101	i_inc	.req r3
102ENTRY(armv7_icache_sync_range)
103	ldr	ip, .Larmv7_icache_line_size
104	ldr	ip, [ip]
105	sub	r3, ip, #1
106	and	r2, r0, r3
107	add	r1, r1, r2
108	bic	r0, r0, r3
1091:
110	mcr	CP15_DCCMVAU(r0)	/* Clean D cache SE with VA to PoU */
111	mcr	CP15_ICIMVAU(r0)	/* Invalidate I cache SE with VA */
112	add	r0, r0, ip
113	subs	r1, r1, ip
114	bhi	1b
115	mcr	CP15_BPIALL		/* Flush BP cache */
116	dsb	sy
117	isb	sy
118	mov	pc, lr
119
120ENTRY(armv7_icache_sync_all)
121.Larmv7_icache_sync_all:
122	/*
123	 * We assume that the code here can never be out of sync with the
124	 * dcache, so that we can safely flush the Icache and fall through
125	 * into the Dcache cleaning code.
126	 */
127	mcr	CP15_ICIALLU		/* Flush I cache */
128	isb	sy
129	mov	pc, lr
130
131ENTRY(armv7_dcache_wb_range)
132	ldr	ip, .Larmv7_dcache_line_size
133	ldr	ip, [ip]
134	sub	r3, ip, #1
135	and	r2, r0, r3
136	add	r1, r1, r2
137	bic	r0, r0, r3
1381:
139	mcr	CP15_DCCMVAC(r0)	/* Clean D cache SE with VA */
140	add	r0, r0, ip
141	subs	r1, r1, ip
142	bhi	1b
143	dsb	sy
144	isb	sy
145	mov	pc, lr
146
147ENTRY(armv7_idcache_wbinv_range)
148	ldr	ip, .Larmv7_idcache_line_size
149	ldr	ip, [ip]
150	sub	r3, ip, #1
151	and	r2, r0, r3
152	add	r1, r1, r2
153	bic	r0, r0, r3
1541:
155	mcr	CP15_DCCMVAU(r0)	/* Clean D cache SE with VA to PoU */
156	mcr	CP15_ICIMVAU(r0)	/* Invalidate I cache SE with VA */
157	mcr	CP15_DCCIMVAC(r0)	/* Purge D cache SE with VA */
158	add	r0, r0, ip
159	subs	r1, r1, ip
160	bhi	1b
161	mcr	CP15_BPIALL		/* Flush BP cache */
162	dsb	sy
163	isb	sy
164	mov	pc, lr
165
166ENTRY(armv7_dcache_wbinv_range)
167	ldr	ip, .Larmv7_dcache_line_size
168	ldr	ip, [ip]
169	sub	r3, ip, #1
170	and	r2, r0, r3
171	add	r1, r1, r2
172	bic	r0, r0, r3
1731:
174	mcr	CP15_DCCMVAU(r0)	/* Clean D cache SE with VA to PoU */
175	mcr	CP15_ICIMVAU(r0)	/* Invalidate I cache SE with VA */
176	mcr	CP15_DCCIMVAC(r0)	/* Purge D cache SE with VA */
177	add	r0, r0, ip
178	subs	r1, r1, ip
179	bhi	1b
180	dsb	sy
181	isb	sy
182	mov	pc, lr
183
184ENTRY(armv7_dcache_inv_range)
185	ldr	ip, .Larmv7_dcache_line_size
186	ldr	ip, [ip]
187	sub	r3, ip, #1
188	and	r2, r0, r3
189	add	r1, r1, r2
190	bic	r0, r0, r3
1911:
192	mcr	CP15_DCCMVAU(r0)	/* Clean D cache SE with VA to PoU */
193	mcr	CP15_ICIMVAU(r0)	/* Invalidate I cache SE with VA */
194	mcr	CP15_DCIMVAC(r0)	/* Invalidate D cache SE with VA */
195	add	r0, r0, ip
196	subs	r1, r1, ip
197	bhi	1b
198	dsb	sy
199	isb	sy
200	mov	pc, lr
201
202
203/*
204 * BTB functions.
205 */
206ENTRY(armv7_flush_bp)
207	mcr	CP15_BPIALL
208	mov	pc, lr
209
210ENTRY(cortex_a15_flush_bp)
211	mcr	CP15_ICIALLU		/* Heavy hammer; BPIALL is a no-op */
212	mov	pc, lr
213
214/*
215 * Context switch.
216 *
217 * These is the CPU-specific parts of the context switcher cpu_switch()
218 * These functions actually perform the TTB reload.
219 *
220 * NOTE: Special calling convention
221 *	r1, r4-r13 must be preserved
222 */
223ENTRY(armv7_context_switch)
224	/*
225	 * We can assume that the caches will only contain kernel addresses
226	 * at this point.  So no need to flush them again.
227	 */
228	mcr	CP15_ICIALLU		/* Flush I cache */
229	dsb	sy
230	isb	sy
231
232	orr	r0, r0, #TTBR_DEFAULT
233	mcr	CP15_TTBR0(r0)		/* set the new TTB */
234	mcr	CP15_TLBIALL(r0)	/* and flush the unified tlb */
235	dsb	sy
236	isb	sy
237	mov	pc, lr
238
239/* XXX The following macros should probably be moved to asm.h */
240#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x:
241#define C_OBJECT(x)	_DATA_OBJECT(x)
242
243	.align 2
244C_OBJECT(armv7_dcache_sets_max)
245	.word	0
246C_OBJECT(armv7_dcache_index_max)
247	.word	0
248C_OBJECT(armv7_dcache_sets_inc)
249	.word	0
250C_OBJECT(armv7_dcache_index_inc)
251	.word	0
252