1244480Sgonzo/*	$NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $	*/
2244480Sgonzo
3244480Sgonzo/*
4244480Sgonzo * Copyright (c) 2007 Microsoft
5244480Sgonzo * All rights reserved.
6244480Sgonzo *
7244480Sgonzo * Redistribution and use in source and binary forms, with or without
8244480Sgonzo * modification, are permitted provided that the following conditions
9244480Sgonzo * are met:
10244480Sgonzo * 1. Redistributions of source code must retain the above copyright
11244480Sgonzo *    notice, this list of conditions and the following disclaimer.
12244480Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
13244480Sgonzo *    notice, this list of conditions and the following disclaimer in the
14244480Sgonzo *    documentation and/or other materials provided with the distribution.
15244480Sgonzo * 3. All advertising materials mentioning features or use of this software
16244480Sgonzo *    must display the following acknowledgement:
17244480Sgonzo *	This product includes software developed by Microsoft
18244480Sgonzo *
19244480Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20244480Sgonzo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21244480Sgonzo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22244480Sgonzo * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
23244480Sgonzo * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24244480Sgonzo * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25244480Sgonzo * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26244480Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27244480Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28244480Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29244480Sgonzo * SUCH DAMAGE.
30244480Sgonzo */
31244480Sgonzo
32244480Sgonzo/*-
33244480Sgonzo * Copyright (c) 2012 The NetBSD Foundation, Inc.
34244480Sgonzo * All rights reserved.
35244480Sgonzo *
36244480Sgonzo * This code is derived from software contributed to The NetBSD Foundation
37244480Sgonzo * by Eben Upton
38244480Sgonzo *
39244480Sgonzo * Redistribution and use in source and binary forms, with or without
40244480Sgonzo * modification, are permitted provided that the following conditions
41244480Sgonzo * are met:
42244480Sgonzo * 1. Redistributions of source code must retain the above copyright
43244480Sgonzo *    notice, this list of conditions and the following disclaimer.
44244480Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
45244480Sgonzo *    notice, this list of conditions and the following disclaimer in the
46244480Sgonzo *    documentation and/or other materials provided with the distribution.
47244480Sgonzo *
48244480Sgonzo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
49244480Sgonzo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50244480Sgonzo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51244480Sgonzo * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
52244480Sgonzo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53244480Sgonzo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54244480Sgonzo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55244480Sgonzo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56244480Sgonzo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57244480Sgonzo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58244480Sgonzo * POSSIBILITY OF SUCH DAMAGE.
59244480Sgonzo */
60244480Sgonzo
61244480Sgonzo
62244480Sgonzo#include <machine/asm.h>
63244480Sgonzo__FBSDID("$FreeBSD$");
64244480Sgonzo
65275523Sandrew	.cpu arm1176jz-s
66248028Skientzle
67244480Sgonzo#if 0
68244480Sgonzo#define Invalidate_I_cache(Rtmp1, Rtmp2) \
69244480Sgonzo	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
70244480Sgonzo#else
71244480Sgonzo/*
72244480Sgonzo * Workaround for
73244480Sgonzo *
74244480Sgonzo *    Erratum 411920 in ARM1136 (fixed in r1p4)
75244480Sgonzo *    Erratum 415045 in ARM1176 (fixed in r0p5?)
76283366Sandrew *
77244480Sgonzo *	- value of arg 'reg' Should Be Zero
78244480Sgonzo */
79244480Sgonzo#define Invalidate_I_cache(Rtmp1, Rtmp2) \
80244480Sgonzo	mov	Rtmp1, #0;		/* SBZ */			\
81244480Sgonzo	mrs	Rtmp2, cpsr;						\
82244480Sgonzo	cpsid	ifa;							\
83244480Sgonzo	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
84244480Sgonzo	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
85244480Sgonzo	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
86244480Sgonzo	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
87244480Sgonzo	msr	cpsr_cx, Rtmp2;						\
88244480Sgonzo	nop;								\
89244480Sgonzo	nop;								\
90244480Sgonzo	nop;								\
91244480Sgonzo	nop;								\
92244480Sgonzo	nop;								\
93244480Sgonzo	nop;								\
94244480Sgonzo	nop;								\
95244480Sgonzo	nop;								\
96244480Sgonzo	nop;								\
97244480Sgonzo	nop;								\
98244480Sgonzo	nop;
99244480Sgonzo#endif
100244480Sgonzo
101244480Sgonzo#if 1
102244480Sgonzo#define Flush_D_cache(reg) \
103244480Sgonzo	mov	reg, #0;		/* SBZ */					\
104244480Sgonzo	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
105244480Sgonzo	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
106244480Sgonzo#else
107244480Sgonzo#define Flush_D_cache(reg) \
108244480Sgonzo1:	mov	reg, #0;		/* SBZ */					\
109244480Sgonzo	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
110244480Sgonzo	mrc	p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */		\
111244480Sgonzo	ands	reg, reg, #01;		/* Check if it is clean */			\
112244480Sgonzo	bne	1b;			/* loop if not */				\
113244480Sgonzo	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
114244480Sgonzo#endif
115244480Sgonzo
116244480SgonzoENTRY(arm11x6_setttb)
117244480Sgonzo	mov	r1, #0
118244480Sgonzo	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
119244480Sgonzo	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLBs */
120244480Sgonzo	mcr	p15, 0, r1, c7, c10, 4	/* drain write buffer */
121244480Sgonzo	RET
122248361SandrewEND(arm11x6_setttb)
123244480Sgonzo
124244480SgonzoENTRY_NP(arm11x6_idcache_wbinv_all)
125244480Sgonzo	Flush_D_cache(r0)
126244480Sgonzo	Invalidate_I_cache(r0, r1)
127244480Sgonzo	RET
128248361SandrewEND(arm11x6_idcache_wbinv_all)
129244480Sgonzo
130244480SgonzoENTRY_NP(arm11x6_dcache_wbinv_all)
131244480Sgonzo	Flush_D_cache(r0)
132244480Sgonzo	RET
133248361SandrewEND(arm11x6_dcache_wbinv_all)
134244480Sgonzo
135244480SgonzoENTRY_NP(arm11x6_icache_sync_range)
136244480Sgonzo	add	r1, r1, r0
137244480Sgonzo	sub	r1, r1, #1
138244480Sgonzo	/* Erratum ARM1136 371025, workaround #2 */
139244480Sgonzo	/* Erratum ARM1176 371367 */
140244480Sgonzo	mrs	r2, cpsr		/* save the CPSR */
141244480Sgonzo	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
142283366Sandrew	mov	r3, #0
143244480Sgonzo	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
144244480Sgonzo	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
145283366Sandrew	add	r3, pc, #0x24
146244480Sgonzo	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
147244480Sgonzo	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
148244480Sgonzo	msr	cpsr_cx, r2		/* local_irq_restore */
149283366Sandrew	nop
150283366Sandrew	nop
151283366Sandrew	nop
152283366Sandrew	nop
153283366Sandrew	nop
154283366Sandrew	nop
155283366Sandrew	nop
156244480Sgonzo
157244480Sgonzo	mcrr	p15, 0, r1, r0, c12	/* clean and invalidate D cache range */ /* XXXNH */
158244480Sgonzo	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
159244480Sgonzo	RET
160248361SandrewEND(arm11x6_icache_sync_range)
161244480Sgonzo
162244480SgonzoENTRY_NP(arm11x6_idcache_wbinv_range)
163244480Sgonzo	add	r1, r1, r0
164244480Sgonzo	sub	r1, r1, #1
165244480Sgonzo	/* Erratum ARM1136 371025, workaround #2 */
166244480Sgonzo	/* Erratum ARM1176 371367 */
167244480Sgonzo	mrs	r2, cpsr		/* save the CPSR */
168244480Sgonzo	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
169283366Sandrew	mov	r3, #0
170244480Sgonzo	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
171244480Sgonzo	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
172283366Sandrew	add	r3, pc, #0x24
173244480Sgonzo	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
174244480Sgonzo	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
175244480Sgonzo	msr	cpsr_cx, r2		/* local_irq_restore */
176283366Sandrew	nop
177283366Sandrew	nop
178283366Sandrew	nop
179283366Sandrew	nop
180283366Sandrew	nop
181283366Sandrew	nop
182283366Sandrew	nop
183244480Sgonzo
184244480Sgonzo	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
185244480Sgonzo	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
186244480Sgonzo	RET
187248361SandrewEND(arm11x6_idcache_wbinv_range)
188244480Sgonzo
189244480Sgonzo/*
190244480Sgonzo * Preload the cache before issuing the WFI by conditionally disabling the
191283366Sandrew * mcr intstructions the first time around the loop. Ensure the function is
192244480Sgonzo * cacheline aligned.
193244480Sgonzo */
194244480Sgonzo	.arch	armv6
195244480Sgonzo	.p2align 5
196244480Sgonzo
197244480SgonzoENTRY_NP(arm11x6_sleep)
198244480Sgonzo	mov	r0, #0
199244480Sgonzo	mov	r1, #2
200244480Sgonzo1:
201244480Sgonzo	subs	r1, #1
202244480Sgonzo	nop
203244480Sgonzo	mcreq	p15, 0, r0, c7, c10, 4		/* data sync barrier */
204244480Sgonzo	mcreq	p15, 0, r0, c7, c0, 4		/* wait for interrupt */
205244480Sgonzo	nop
206244480Sgonzo	nop
207244480Sgonzo	nop
208244480Sgonzo	bne	1b
209244480Sgonzo	RET
210248361SandrewEND(arm11x6_sleep)
211248361Sandrew
212