xref: /netbsd-src/sys/arch/arm/arm/cpufunc_asm_arm11x6.S (revision 12c0cd6454fbcceb60fcd846c613ef7e1da30b17)
1/*	$NetBSD: cpufunc_asm_arm11x6.S,v 1.10 2018/01/20 14:43:25 christos Exp $	*/
2
3/*
4 * Copyright (c) 2007 Microsoft
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Microsoft
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 2012 The NetBSD Foundation, Inc.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to The NetBSD Foundation
37 * by Eben Upton
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 *    notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 *    notice, this list of conditions and the following disclaimer in the
46 *    documentation and/or other materials provided with the distribution.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 * POSSIBILITY OF SUCH DAMAGE.
59 */
60
61
62#include "assym.h"
63#include <machine/asm.h>
64#include <arm/locore.h>
65
66RCSID("$NetBSD: cpufunc_asm_arm11x6.S,v 1.10 2018/01/20 14:43:25 christos Exp $")
67
68#if 0
69#define Invalidate_I_cache(Rtmp1, Rtmp2) \
70	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
71#else
72/*
73 * Workaround for
74 *
75 *    Erratum 411920 in ARM1136 (fixed in r1p4)
76 *    Erratum 415045 in ARM1176 (fixed in r0p5)
77 *
78 *	- value of arg 'reg' Should Be Zero
79 */
80#define Invalidate_I_cache(Rtmp1, Rtmp2) \
81	mov	Rtmp1, #0;		/* SBZ */			\
82	mrs	Rtmp2, cpsr;						\
83	cpsid	ifa;							\
84	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
85	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
86	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
87	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
88	msr	cpsr_cx, Rtmp2;						\
89	nop;								\
90	nop;								\
91	nop;								\
92	nop;								\
93	nop;								\
94	nop;								\
95	nop;								\
96	nop;								\
97	nop;								\
98	nop;								\
99	nop;
100#endif
101
102#if 1
103#define Flush_D_cache(reg) \
104	mov	reg, #0;		/* SBZ */					\
105	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
106	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
107#else
108#define Flush_D_cache(reg) \
1091:	mov	reg, #0;		/* SBZ */					\
110	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
111	mrc	p15, 0, reg, c7, c10, 6;/* Read Cache Dirty Status Register */		\
112	ands	reg, reg, #01;		/* Check if it is clean */			\
113	bne	1b;			/* loop if not */				\
114	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
115#endif
116
117ENTRY_NP(arm11x6_idcache_wbinv_all)
118	Flush_D_cache(r0)
119	Invalidate_I_cache(r0, r1)
120	RET
121END(arm11x6_idcache_wbinv_all)
122
123ENTRY_NP(arm11x6_dcache_wbinv_all)
124	Flush_D_cache(r0)
125	RET
126END(arm11x6_dcache_wbinv_all)
127
128ENTRY_NP(arm11x6_icache_sync_all)
129	Flush_D_cache(r0)
130	Invalidate_I_cache(r0, r1)
131	RET
132END(arm11x6_icache_sync_all)
133
134ENTRY_NP(arm11x6_flush_prefetchbuf)
135	mcr	p15, 0, r0, c7, c5, 4	/* Flush Prefetch Buffer */
136	RET
137END(arm11x6_flush_prefetchbuf)
138
139ENTRY_NP(arm11x6_icache_sync_range)
140	ldr	r2, .Larm_pcache
141	ldr	r2, [r2, #DCACHE_SIZE]
142	cmp	r1, r2
143	bge	arm11x6_icache_sync_all
144
145	add	r1, r1, r0
146	sub	r1, r1, #1
147	/* Erratum ARM1136 371025, workaround #2 */
148	/* Erratum ARM1176 371367, workaround #2 */
149	mrs	r2, cpsr		/* save the CPSR */
150	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
151	mov	r3, #0
152	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
153	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
154	add	r3, pc, #0x24
155	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
156	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
157	msr	cpsr_cx, r2		/* local_irq_restore */
158	nop
159	nop
160	nop
161	nop
162	nop
163	nop
164	nop
165
166	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
167	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
168	RET
169END(arm11x6_icache_sync_range)
170
171ENTRY_NP(arm11x6_idcache_wbinv_range)
172	ldr	r2, .Larm_pcache
173	ldr	r2, [r2, #DCACHE_SIZE]
174	cmp	r1, r2
175	bge	arm11x6_idcache_wbinv_all
176
177	add	r1, r1, r0
178	sub	r1, r1, #1
179	/* Erratum ARM1136 371025, workaround #2 */
180	/* Erratum ARM1176 371367, workaround #2 */
181	mrs	r2, cpsr		/* save the CPSR */
182	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
183	mov	r3, #0
184	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
185	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
186	add	r3, pc, #0x24
187	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
188	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
189	msr	cpsr_cx, r2		/* local_irq_restore */
190	nop
191	nop
192	nop
193	nop
194	nop
195	nop
196	nop
197
198	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
199	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
200	RET
201END(arm11x6_idcache_wbinv_range)
202
203/*
204 * Preload the cache before issuing the WFI by conditionally disabling the
205 * mcr intstructions the first time around the loop. Ensure the function is
206 * cacheline aligned.
207 */
208	.arch	armv6
209	.p2align 5
210
211ENTRY_NP(arm11x6_sleep)
212	mov	r0, #0
213	mov	r1, #2
2141:
215	subs	r1, #1
216	nop
217	mcreq	p15, 0, r0, c7, c10, 4		/* data sync barrier */
218	mcreq	p15, 0, r0, c7, c0, 4		/* wait for interrupt */
219	nop
220	nop
221	nop
222	bne	1b
223	RET
224END(arm11x6_sleep)
225
226.Larm_pcache:
227	.word arm_pcache
228