1201468Srpaulo/*	$NetBSD: cpufunc_asm_fa526.S,v 1.3 2008/10/15 16:56:49 matt Exp $*/
2201468Srpaulo/*-
3201468Srpaulo * Copyright (c) 2008 The NetBSD Foundation, Inc.
4201468Srpaulo * All rights reserved.
5201468Srpaulo *
6201468Srpaulo * This code is derived from software contributed to The NetBSD Foundation
7201468Srpaulo * by Matt Thomas <matt@3am-software.com>
8201468Srpaulo *
9201468Srpaulo * Redistribution and use in source and binary forms, with or without
10201468Srpaulo * modification, are permitted provided that the following conditions
11201468Srpaulo * are met:
12201468Srpaulo * 1. Redistributions of source code must retain the above copyright
13201468Srpaulo *    notice, this list of conditions and the following disclaimer.
14201468Srpaulo * 2. Redistributions in binary form must reproduce the above copyright
15201468Srpaulo *    notice, this list of conditions and the following disclaimer in the
16201468Srpaulo *    documentation and/or other materials provided with the distribution.
17201468Srpaulo *
18201468Srpaulo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19201468Srpaulo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20201468Srpaulo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21201468Srpaulo * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22201468Srpaulo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23201468Srpaulo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24201468Srpaulo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25201468Srpaulo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26201468Srpaulo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27201468Srpaulo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28201468Srpaulo * POSSIBILITY OF SUCH DAMAGE.
29201468Srpaulo */
30201468Srpaulo
31201468Srpaulo
32201468Srpaulo#include <machine/asm.h>
33201468Srpaulo__FBSDID("$FreeBSD$");
34201468Srpaulo
35207611Skevlo#ifdef CPU_FA526
36201468Srpaulo#define	CACHELINE_SIZE	16
37207611Skevlo#else
38207611Skevlo#define	CACHELINE_SIZE	32
39207611Skevlo#endif
40201468Srpaulo
41201468SrpauloENTRY(fa526_setttb)
42201468Srpaulo	mov	r1, #0
43201468Srpaulo	mcr	p15, 0, r1, c7, c14, 0	/* clean and invalidate D$ */
44201468Srpaulo	mcr	p15, 0, r1, c7, c5, 0	/* invalidate I$ */
45201468Srpaulo	mcr	p15, 0, r1, c7, c5, 6	/* invalidate BTB */
46201468Srpaulo	mcr	p15, 0, r1, c7, c10, 4	/* drain write and fill buffer */
47201468Srpaulo
48201468Srpaulo	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
49201468Srpaulo
50201468Srpaulo	/* If we have updated the TTB we must flush the TLB */
51201468Srpaulo	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLB */
52201468Srpaulo
53201468Srpaulo	/* Make sure that pipeline is emptied */
54201468Srpaulo	mov	r0, r0
55201468Srpaulo	mov	r0, r0
56201468Srpaulo	mov	pc, lr
57248361SandrewEND(fa526_setttb)
58201468Srpaulo
59201468Srpaulo/*
60201468Srpaulo * TLB functions
61201468Srpaulo */
62201468SrpauloENTRY(fa526_tlb_flushID_SE)
63201468Srpaulo	mcr	p15, 0, r0, c8, c7, 1	/* flush Utlb single entry */
64201468Srpaulo	mov	pc, lr
65248361SandrewEND(fa526_tlb_flushID_SE)
66201468Srpaulo
67201468SrpauloENTRY(fa526_cpu_sleep)
68201468Srpaulo	mov	r0, #0
69201468Srpaulo/*	nop
70201468Srpaulo	nop*/
71201468Srpaulo	mcr	p15, 0, r0, c7, c0, 4	/* Wait for interrupt*/
72201468Srpaulo	mov	pc, lr
73248361SandrewEND(fa526_cpu_sleep)
74201468Srpaulo
75201468Srpaulo/*
76201468Srpaulo * Cache functions
77201468Srpaulo */
78201468SrpauloENTRY(fa526_idcache_wbinv_all)
79201468Srpaulo	mov	r0, #0
80201468Srpaulo	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
81201468Srpaulo	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
82201468Srpaulo	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
83201468Srpaulo	mov	pc, lr
84248361SandrewEND(fa526_idcache_wbinv_all)
85201468Srpaulo
86201468SrpauloENTRY(fa526_dcache_wbinv_all)
87201468Srpaulo	mov	r0, #0
88201468Srpaulo	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
89201468Srpaulo	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
90201468Srpaulo	mov	pc, lr
91248361SandrewEND(fa526_dcache_wbinv_all)
92201468Srpaulo
93201468Srpaulo/*
94201468Srpaulo * Soft functions
95201468Srpaulo */
96201468SrpauloENTRY(fa526_dcache_wbinv_range)
97201468Srpaulo	cmp	r1, #0x4000
98201468Srpaulo	bhs	_C_LABEL(fa526_dcache_wbinv_all)
99201468Srpaulo
100201468Srpaulo	and	r2, r0, #(CACHELINE_SIZE - 1)
101201468Srpaulo	add	r1, r1, r2
102201468Srpaulo	bic	r0, r0, #(CACHELINE_SIZE - 1)
103201468Srpaulo
104201468Srpaulo1:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
105201468Srpaulo	add	r0, r0, #CACHELINE_SIZE
106201468Srpaulo	subs	r1, r1, #CACHELINE_SIZE
107201468Srpaulo	bhi	1b
108201468Srpaulo
109201468Srpaulo	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
110201468Srpaulo	mov	pc, lr
111248361SandrewEND(fa526_dcache_wbinv_range)
112201468Srpaulo
113201468SrpauloENTRY(fa526_dcache_wb_range)
114201468Srpaulo	cmp	r1, #0x4000
115201468Srpaulo	bls	1f
116201468Srpaulo
117201468Srpaulo	mov	r0, #0
118201468Srpaulo	mcr	p15, 0, r0, c7, c10, 0	/* clean entire D$ */
119201468Srpaulo	b	3f
120201468Srpaulo
121201468Srpaulo1:	and	r2, r0, #(CACHELINE_SIZE - 1)
122201468Srpaulo	add	r1, r1, r2
123201468Srpaulo	bic	r0, r0, #(CACHELINE_SIZE - 1)
124201468Srpaulo
125201468Srpaulo2:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
126201468Srpaulo	add	r0, r0, #CACHELINE_SIZE
127201468Srpaulo	subs	r1, r1, #CACHELINE_SIZE
128201468Srpaulo	bhi	2b
129201468Srpaulo
130201468Srpaulo3:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
131201468Srpaulo	mov	pc, lr
132248361SandrewEND(fa526_dcache_wb_range)
133201468Srpaulo
134201468SrpauloENTRY(fa526_dcache_inv_range)
135201468Srpaulo	and	r2, r0, #(CACHELINE_SIZE - 1)
136201468Srpaulo	add	r1, r1, r2
137201468Srpaulo	bic	r0, r0, #(CACHELINE_SIZE - 1)
138201468Srpaulo
139201468Srpaulo1:	mcr	p15, 0, r0, c7, c6, 1	/* invalidate D$ single entry */
140201468Srpaulo	add	r0, r0, #CACHELINE_SIZE
141201468Srpaulo	subs	r1, r1, #CACHELINE_SIZE
142201468Srpaulo	bhi	1b
143201468Srpaulo
144201468Srpaulo	mov	pc, lr
145248361SandrewEND(fa526_dcache_inv_range)
146201468Srpaulo
147201468SrpauloENTRY(fa526_idcache_wbinv_range)
148201468Srpaulo	cmp	r1, #0x4000
149201468Srpaulo	bhs	_C_LABEL(fa526_idcache_wbinv_all)
150201468Srpaulo
151201468Srpaulo	and	r2, r0, #(CACHELINE_SIZE - 1)
152201468Srpaulo	add	r1, r1, r2
153201468Srpaulo	bic	r0, r0, #(CACHELINE_SIZE - 1)
154201468Srpaulo
155201468Srpaulo1:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
156201468Srpaulo	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
157201468Srpaulo	add	r0, r0, #CACHELINE_SIZE
158201468Srpaulo	subs	r1, r1, #CACHELINE_SIZE
159201468Srpaulo	bhi	1b
160201468Srpaulo
161201468Srpaulo2:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
162201468Srpaulo	mov	pc, lr
163248361SandrewEND(fa526_idcache_wbinv_range)
164201468Srpaulo
165201468SrpauloENTRY(fa526_icache_sync_range)
166201468Srpaulo	cmp	r1, #0x4000
167295207Smmel	bhs	.Lfa526_icache_sync_all
168201468Srpaulo
169201468Srpaulo	and	r2, r0, #(CACHELINE_SIZE - 1)
170201468Srpaulo	add	r1, r1, r2
171201468Srpaulo	bic	r0, r0, #(CACHELINE_SIZE - 1)
172201468Srpaulo
173201468Srpaulo1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
174201468Srpaulo	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
175201468Srpaulo	add	r0, r0, #CACHELINE_SIZE
176201468Srpaulo	subs	r1, r1, #CACHELINE_SIZE
177201468Srpaulo	bhi	1b
178201468Srpaulo
179201468Srpaulo2:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
180201468Srpaulo	mov	pc, lr
181295207Smmel
182295207Smmel.Lfa526_icache_sync_all:
183295207Smmel	mov	r0, #0
184295207Smmel	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
185295207Smmel	mov	pc, lr
186248361SandrewEND(fa526_icache_sync_range)
187201468Srpaulo
188201468SrpauloENTRY(fa526_context_switch)
189201468Srpaulo	/*
190201468Srpaulo	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
191201468Srpaulo	 * Thus the data cache will contain only kernel data and the
192201468Srpaulo	 * instruction cache will contain only kernel code, and all
193201468Srpaulo	 * kernel mappings are shared by all processes.
194201468Srpaulo	 */
195201468Srpaulo
196201468Srpaulo	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
197201468Srpaulo
198201468Srpaulo	/* If we have updated the TTB we must flush the TLB */
199201468Srpaulo	mov	r0, #0
200201468Srpaulo	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
201201468Srpaulo
202201468Srpaulo	/* Make sure that pipeline is emptied */
203201468Srpaulo	mov	r0, r0
204201468Srpaulo	mov	r0, r0
205201468Srpaulo	mov	pc, lr
206248361SandrewEND(fa526_context_switch)
207201468Srpaulo
208