xref: /openbmc/linux/arch/arm/mm/cache-v6.S (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1/*
2 *  linux/arch/arm/mm/cache-v6.S
3 *
4 *  Copyright (C) 2001 Deep Blue Solutions Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  This is the "shell" of the ARMv6 processor support.
11 */
12#include <linux/linkage.h>
13#include <linux/init.h>
14#include <asm/assembler.h>
15
16#include "proc-macros.S"
17
18#define HARVARD_CACHE
19#define CACHE_LINE_SIZE		32
20#define D_CACHE_LINE_SIZE	32
21
22/*
23 *	v6_flush_cache_all()
24 *
25 *	Flush the entire cache.
26 *
27 *	It is assumed that:
28 */
29ENTRY(v6_flush_kern_cache_all)
30	mov	r0, #0
31#ifdef HARVARD_CACHE
32	mcr	p15, 0, r0, c7, c14, 0		@ D cache clean+invalidate
33	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
34#else
35	mcr	p15, 0, r0, c7, c15, 0		@ Cache clean+invalidate
36#endif
37	mov	pc, lr
38
39/*
40 *	v6_flush_cache_all()
41 *
42 *	Flush all TLB entries in a particular address space
43 *
44 *	- mm    - mm_struct describing address space
45 */
46ENTRY(v6_flush_user_cache_all)
47	/*FALLTHROUGH*/
48
49/*
50 *	v6_flush_cache_range(start, end, flags)
51 *
52 *	Flush a range of TLB entries in the specified address space.
53 *
54 *	- start - start address (may not be aligned)
55 *	- end   - end address (exclusive, may not be aligned)
56 *	- flags	- vm_area_struct flags describing address space
57 *
58 *	It is assumed that:
59 *	- we have a VIPT cache.
60 */
61ENTRY(v6_flush_user_cache_range)
62	mov	pc, lr
63
64/*
65 *	v6_coherent_kern_range(start,end)
66 *
67 *	Ensure that the I and D caches are coherent within specified
68 *	region.  This is typically used when code has been written to
69 *	a memory region, and will be executed.
70 *
71 *	- start   - virtual start address of region
72 *	- end     - virtual end address of region
73 *
74 *	It is assumed that:
75 *	- the Icache does not read data from the write buffer
76 */
77ENTRY(v6_coherent_kern_range)
78	/* FALLTHROUGH */
79
80/*
81 *	v6_coherent_user_range(start,end)
82 *
83 *	Ensure that the I and D caches are coherent within specified
84 *	region.  This is typically used when code has been written to
85 *	a memory region, and will be executed.
86 *
87 *	- start   - virtual start address of region
88 *	- end     - virtual end address of region
89 *
90 *	It is assumed that:
91 *	- the Icache does not read data from the write buffer
92 */
93ENTRY(v6_coherent_user_range)
94	bic	r0, r0, #CACHE_LINE_SIZE - 1
951:
96#ifdef HARVARD_CACHE
97	mcr	p15, 0, r0, c7, c10, 1		@ clean D line
98	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I line
99#endif
100	mcr	p15, 0, r0, c7, c5, 7		@ invalidate BTB entry
101	add	r0, r0, #CACHE_LINE_SIZE
102	cmp	r0, r1
103	blo	1b
104#ifdef HARVARD_CACHE
105	mov	r0, #0
106	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
107#endif
108	mov	pc, lr
109
110/*
111 *	v6_flush_kern_dcache_page(kaddr)
112 *
113 *	Ensure that the data held in the page kaddr is written back
114 *	to the page in question.
115 *
116 *	- kaddr   - kernel address (guaranteed to be page aligned)
117 */
118ENTRY(v6_flush_kern_dcache_page)
119	add	r1, r0, #PAGE_SZ
1201:
121#ifdef HARVARD_CACHE
122	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
123#else
124	mcr	p15, 0, r0, c7, c15, 1		@ clean & invalidate unified line
125#endif
126	add	r0, r0, #D_CACHE_LINE_SIZE
127	cmp	r0, r1
128	blo	1b
129#ifdef HARVARD_CACHE
130	mov	r0, #0
131	mcr	p15, 0, r0, c7, c10, 4
132#endif
133	mov	pc, lr
134
135
136/*
137 *	v6_dma_inv_range(start,end)
138 *
139 *	Invalidate the data cache within the specified region; we will
140 *	be performing a DMA operation in this region and we want to
141 *	purge old data in the cache.
142 *
143 *	- start   - virtual start address of region
144 *	- end     - virtual end address of region
145 */
146ENTRY(v6_dma_inv_range)
147	tst	r0, #D_CACHE_LINE_SIZE - 1
148	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
149#ifdef HARVARD_CACHE
150	mcrne	p15, 0, r0, c7, c10, 1		@ clean D line
151#else
152	mcrne	p15, 0, r0, c7, c11, 1		@ clean unified line
153#endif
154	tst	r1, #D_CACHE_LINE_SIZE - 1
155	bic	r1, r1, #D_CACHE_LINE_SIZE - 1
156#ifdef HARVARD_CACHE
157	mcrne	p15, 0, r1, c7, c14, 1		@ clean & invalidate D line
158#else
159	mcrne	p15, 0, r1, c7, c15, 1		@ clean & invalidate unified line
160#endif
1611:
162#ifdef HARVARD_CACHE
163	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D line
164#else
165	mcr	p15, 0, r0, c7, c7, 1		@ invalidate unified line
166#endif
167	add	r0, r0, #D_CACHE_LINE_SIZE
168	cmp	r0, r1
169	blo	1b
170	mov	r0, #0
171	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
172	mov	pc, lr
173
174/*
175 *	v6_dma_clean_range(start,end)
176 *	- start   - virtual start address of region
177 *	- end     - virtual end address of region
178 */
179ENTRY(v6_dma_clean_range)
180	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
1811:
182#ifdef HARVARD_CACHE
183	mcr	p15, 0, r0, c7, c10, 1		@ clean D line
184#else
185	mcr	p15, 0, r0, c7, c11, 1		@ clean unified line
186#endif
187	add	r0, r0, #D_CACHE_LINE_SIZE
188	cmp	r0, r1
189	blo	1b
190	mov	r0, #0
191	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
192	mov	pc, lr
193
194/*
195 *	v6_dma_flush_range(start,end)
196 *	- start   - virtual start address of region
197 *	- end     - virtual end address of region
198 */
199ENTRY(v6_dma_flush_range)
200	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
2011:
202#ifdef HARVARD_CACHE
203	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
204#else
205	mcr	p15, 0, r0, c7, c15, 1		@ clean & invalidate line
206#endif
207	add	r0, r0, #D_CACHE_LINE_SIZE
208	cmp	r0, r1
209	blo	1b
210	mov	r0, #0
211	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
212	mov	pc, lr
213
214	__INITDATA
215
216	.type	v6_cache_fns, #object
217ENTRY(v6_cache_fns)
218	.long	v6_flush_kern_cache_all
219	.long	v6_flush_user_cache_all
220	.long	v6_flush_user_cache_range
221	.long	v6_coherent_kern_range
222	.long	v6_coherent_user_range
223	.long	v6_flush_kern_dcache_page
224	.long	v6_dma_inv_range
225	.long	v6_dma_clean_range
226	.long	v6_dma_flush_range
227	.size	v6_cache_fns, . - v6_cache_fns
228