1/*	$NetBSD: cpufunc_asm_fa526.S,v 1.3 2008/10/15 16:56:49 matt Exp $*/
2/*-
3 * Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas <matt@3am-software.com>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32#include <machine/asm.h>
33__FBSDID("$FreeBSD$");
34
35#ifdef CPU_FA526
36#define	CACHELINE_SIZE	16
37#else
38#define	CACHELINE_SIZE	32
39#endif
40
41ENTRY(fa526_setttb)
42	mov	r1, #0
43	mcr	p15, 0, r1, c7, c14, 0	/* clean and invalidate D$ */
44	mcr	p15, 0, r1, c7, c5, 0	/* invalidate I$ */
45	mcr	p15, 0, r1, c7, c5, 6	/* invalidate BTB */
46	mcr	p15, 0, r1, c7, c10, 4	/* drain write and fill buffer */
47
48	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
49
50	/* If we have updated the TTB we must flush the TLB */
51	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLB */
52
53	/* Make sure that pipeline is emptied */
54	mov	r0, r0
55	mov	r0, r0
56	mov	pc, lr
57END(fa526_setttb)
58
59/*
60 * TLB functions
61 */
62ENTRY(fa526_tlb_flushID_SE)
63	mcr	p15, 0, r0, c8, c7, 1	/* flush Utlb single entry */
64	mov	pc, lr
65END(fa526_tlb_flushID_SE)
66
67/*
68 * TLB functions
69 */
70ENTRY(fa526_tlb_flushI_SE)
71	mcr	p15, 0, r0, c8, c5, 1	/* flush Itlb single entry */
72	mov	pc, lr
73END(fa526_tlb_flushI_SE)
74
75ENTRY(fa526_cpu_sleep)
76	mov	r0, #0
77/*	nop
78	nop*/
79	mcr	p15, 0, r0, c7, c0, 4	/* Wait for interrupt*/
80	mov	pc, lr
81END(fa526_cpu_sleep)
82
83ENTRY(fa526_flush_prefetchbuf)
84	mov	r0, #0
85	mcr	p15, 0, r0, c7, c5, 4	/* Pre-fetch flush */
86	mov	pc, lr
87END(fa526_flush_prefetchbuf)
88
89/*
90 * Cache functions
91 */
92ENTRY(fa526_idcache_wbinv_all)
93	mov	r0, #0
94	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
95	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
96	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
97	mov	pc, lr
98END(fa526_idcache_wbinv_all)
99
100ENTRY(fa526_icache_sync_all)
101	mov	r0, #0
102	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
103	mov	pc, lr
104END(fa526_icache_sync_all)
105
106ENTRY(fa526_dcache_wbinv_all)
107	mov	r0, #0
108	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
109	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
110	mov	pc, lr
111END(fa526_dcache_wbinv_all)
112
113/*
114 * Soft functions
115 */
116ENTRY(fa526_dcache_wbinv_range)
117	cmp	r1, #0x4000
118	bhs	_C_LABEL(fa526_dcache_wbinv_all)
119
120	and	r2, r0, #(CACHELINE_SIZE - 1)
121	add	r1, r1, r2
122	bic	r0, r0, #(CACHELINE_SIZE - 1)
123
1241:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
125	add	r0, r0, #CACHELINE_SIZE
126	subs	r1, r1, #CACHELINE_SIZE
127	bhi	1b
128
129	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
130	mov	pc, lr
131END(fa526_dcache_wbinv_range)
132
133ENTRY(fa526_dcache_wb_range)
134	cmp	r1, #0x4000
135	bls	1f
136
137	mov	r0, #0
138	mcr	p15, 0, r0, c7, c10, 0	/* clean entire D$ */
139	b	3f
140
1411:	and	r2, r0, #(CACHELINE_SIZE - 1)
142	add	r1, r1, r2
143	bic	r0, r0, #(CACHELINE_SIZE - 1)
144
1452:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
146	add	r0, r0, #CACHELINE_SIZE
147	subs	r1, r1, #CACHELINE_SIZE
148	bhi	2b
149
1503:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
151	mov	pc, lr
152END(fa526_dcache_wb_range)
153
154ENTRY(fa526_dcache_inv_range)
155	and	r2, r0, #(CACHELINE_SIZE - 1)
156	add	r1, r1, r2
157	bic	r0, r0, #(CACHELINE_SIZE - 1)
158
1591:	mcr	p15, 0, r0, c7, c6, 1	/* invalidate D$ single entry */
160	add	r0, r0, #CACHELINE_SIZE
161	subs	r1, r1, #CACHELINE_SIZE
162	bhi	1b
163
164	mov	pc, lr
165END(fa526_dcache_inv_range)
166
167ENTRY(fa526_idcache_wbinv_range)
168	cmp	r1, #0x4000
169	bhs	_C_LABEL(fa526_idcache_wbinv_all)
170
171	and	r2, r0, #(CACHELINE_SIZE - 1)
172	add	r1, r1, r2
173	bic	r0, r0, #(CACHELINE_SIZE - 1)
174
1751:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
176	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
177	add	r0, r0, #CACHELINE_SIZE
178	subs	r1, r1, #CACHELINE_SIZE
179	bhi	1b
180
1812:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
182	mov	pc, lr
183END(fa526_idcache_wbinv_range)
184
185ENTRY(fa526_icache_sync_range)
186	cmp	r1, #0x4000
187	bhs	_C_LABEL(fa526_icache_sync_all)
188
189	and	r2, r0, #(CACHELINE_SIZE - 1)
190	add	r1, r1, r2
191	bic	r0, r0, #(CACHELINE_SIZE - 1)
192
1931:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
194	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
195	add	r0, r0, #CACHELINE_SIZE
196	subs	r1, r1, #CACHELINE_SIZE
197	bhi	1b
198
1992:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
200	mov	pc, lr
201END(fa526_icache_sync_range)
202
203ENTRY(fa526_flush_brnchtgt_E)
204	mov	r0, #0
205	mcr	p15, 0, r0, c7, c5, 6	/* invalidate BTB cache */
206	mov	pc, lr
207END(fa526_flush_brnchtgt_E)
208
209ENTRY(fa526_context_switch)
210	/*
211	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
212	 * Thus the data cache will contain only kernel data and the
213	 * instruction cache will contain only kernel code, and all
214	 * kernel mappings are shared by all processes.
215	 */
216
217	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
218
219	/* If we have updated the TTB we must flush the TLB */
220	mov	r0, #0
221	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
222
223	/* Make sure that pipeline is emptied */
224	mov	r0, r0
225	mov	r0, r0
226	mov	pc, lr
227END(fa526_context_switch)
228
229