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
67ENTRY(fa526_cpu_sleep)
68	mov	r0, #0
69/*	nop
70	nop*/
71	mcr	p15, 0, r0, c7, c0, 4	/* Wait for interrupt*/
72	mov	pc, lr
73END(fa526_cpu_sleep)
74
75/*
76 * Cache functions
77 */
78ENTRY(fa526_idcache_wbinv_all)
79	mov	r0, #0
80	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
81	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
82	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
83	mov	pc, lr
84END(fa526_idcache_wbinv_all)
85
86ENTRY(fa526_dcache_wbinv_all)
87	mov	r0, #0
88	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
89	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
90	mov	pc, lr
91END(fa526_dcache_wbinv_all)
92
93/*
94 * Soft functions
95 */
96ENTRY(fa526_dcache_wbinv_range)
97	cmp	r1, #0x4000
98	bhs	_C_LABEL(fa526_dcache_wbinv_all)
99
100	and	r2, r0, #(CACHELINE_SIZE - 1)
101	add	r1, r1, r2
102	bic	r0, r0, #(CACHELINE_SIZE - 1)
103
1041:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
105	add	r0, r0, #CACHELINE_SIZE
106	subs	r1, r1, #CACHELINE_SIZE
107	bhi	1b
108
109	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
110	mov	pc, lr
111END(fa526_dcache_wbinv_range)
112
113ENTRY(fa526_dcache_wb_range)
114	cmp	r1, #0x4000
115	bls	1f
116
117	mov	r0, #0
118	mcr	p15, 0, r0, c7, c10, 0	/* clean entire D$ */
119	b	3f
120
1211:	and	r2, r0, #(CACHELINE_SIZE - 1)
122	add	r1, r1, r2
123	bic	r0, r0, #(CACHELINE_SIZE - 1)
124
1252:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
126	add	r0, r0, #CACHELINE_SIZE
127	subs	r1, r1, #CACHELINE_SIZE
128	bhi	2b
129
1303:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
131	mov	pc, lr
132END(fa526_dcache_wb_range)
133
134ENTRY(fa526_dcache_inv_range)
135	and	r2, r0, #(CACHELINE_SIZE - 1)
136	add	r1, r1, r2
137	bic	r0, r0, #(CACHELINE_SIZE - 1)
138
1391:	mcr	p15, 0, r0, c7, c6, 1	/* invalidate D$ single entry */
140	add	r0, r0, #CACHELINE_SIZE
141	subs	r1, r1, #CACHELINE_SIZE
142	bhi	1b
143
144	mov	pc, lr
145END(fa526_dcache_inv_range)
146
147ENTRY(fa526_idcache_wbinv_range)
148	cmp	r1, #0x4000
149	bhs	_C_LABEL(fa526_idcache_wbinv_all)
150
151	and	r2, r0, #(CACHELINE_SIZE - 1)
152	add	r1, r1, r2
153	bic	r0, r0, #(CACHELINE_SIZE - 1)
154
1551:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
156	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
157	add	r0, r0, #CACHELINE_SIZE
158	subs	r1, r1, #CACHELINE_SIZE
159	bhi	1b
160
1612:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
162	mov	pc, lr
163END(fa526_idcache_wbinv_range)
164
165ENTRY(fa526_icache_sync_range)
166	cmp	r1, #0x4000
167	bhs	.Lfa526_icache_sync_all
168
169	and	r2, r0, #(CACHELINE_SIZE - 1)
170	add	r1, r1, r2
171	bic	r0, r0, #(CACHELINE_SIZE - 1)
172
1731:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
174	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
175	add	r0, r0, #CACHELINE_SIZE
176	subs	r1, r1, #CACHELINE_SIZE
177	bhi	1b
178
1792:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
180	mov	pc, lr
181
182.Lfa526_icache_sync_all:
183	mov	r0, #0
184	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
185	mov	pc, lr
186END(fa526_icache_sync_range)
187
188ENTRY(fa526_context_switch)
189	/*
190	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
191	 * Thus the data cache will contain only kernel data and the
192	 * instruction cache will contain only kernel code, and all
193	 * kernel mappings are shared by all processes.
194	 */
195
196	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
197
198	/* If we have updated the TTB we must flush the TLB */
199	mov	r0, #0
200	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
201
202	/* Make sure that pipeline is emptied */
203	mov	r0, r0
204	mov	r0, r0
205	mov	pc, lr
206END(fa526_context_switch)
207
208