1 /*
2  * xtensa/cacheasm.h -- assembler-specific cache related definitions
3  *			that depend on CORE configuration
4  *
5  *  This file is logically part of xtensa/coreasm.h ,
6  *  but is kept separate for modularity / compilation-performance.
7  */
8 
9 /*
10  * Copyright (c) 2001-2014 Cadence Design Systems, Inc.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining
13  * a copy of this software and associated documentation files (the
14  * "Software"), to deal in the Software without restriction, including
15  * without limitation the rights to use, copy, modify, merge, publish,
16  * distribute, sublicense, and/or sell copies of the Software, and to
17  * permit persons to whom the Software is furnished to do so, subject to
18  * the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included
21  * in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30  */
31 
32 #ifndef XTENSA_CACHEASM_H
33 #define XTENSA_CACHEASM_H
34 
35 #include <xtensa/coreasm.h>
36 #include <xtensa/corebits.h>
37 #include <xtensa/xtensa-xer.h>
38 #include <xtensa/xtensa-versions.h>
39 
40 /*
41  *  This header file defines assembler macros of the form:
42  *	<x>cache_<func>
43  *  where <x> is 'i' or 'd' for instruction and data caches,
44  *  and <func> indicates the function of the macro.
45  *
46  *  The following functions <func> are defined,
47  *  and apply only to the specified cache (I or D):
48  *
49  *  reset
50  *	Resets the cache.
51  *
52  *  sync
53  *	Makes sure any previous cache instructions have been completed;
54  *	ie. makes sure any previous cache control operations
55  *	have had full effect and been synchronized to memory.
56  *	Eg. any invalidate completed [so as not to generate a hit],
57  *	any writebacks or other pipelined writes written to memory, etc.
58  *
59  *  invalidate_line		(single cache line)
60  *  invalidate_region		(specified memory range)
61  *  invalidate_all		(entire cache)
62  *	Invalidates all cache entries that cache
63  *	data from the specified memory range.
64  *	NOTE: locked entries are not invalidated.
65  *
66  *  writeback_line		(single cache line)
67  *  writeback_region		(specified memory range)
68  *  writeback_all		(entire cache)
69  *	Writes back to memory all dirty cache entries
70  *	that cache data from the specified memory range,
71  *	and marks these entries as clean.
72  *	NOTE: on some future implementations, this might
73  *		also invalidate.
74  *	NOTE: locked entries are written back, but never invalidated.
75  *	NOTE: instruction caches never implement writeback.
76  *
77  *  writeback_inv_line		(single cache line)
78  *  writeback_inv_region	(specified memory range)
79  *  writeback_inv_all		(entire cache)
80  *	Writes back to memory all dirty cache entries
81  *	that cache data from the specified memory range,
82  *	and invalidates these entries (including all clean
83  *	cache entries that cache data from that range).
84  *	NOTE: locked entries are written back but not invalidated.
85  *	NOTE: instruction caches never implement writeback.
86  *
87  *  lock_line			(single cache line)
88  *  lock_region			(specified memory range)
89  *	Prefetch and lock the specified memory range into cache.
90  *	NOTE:  if any part of the specified memory range cannot
91  *	be locked, a Load/Store Error (for dcache) or Instruction
92  *	Fetch Error (for icache) exception occurs.  These macros don't
93  *	do anything special (yet anyway) to handle this situation.
94  *
95  *  unlock_line			(single cache line)
96  *  unlock_region		(specified memory range)
97  *  unlock_all			(entire cache)
98  *	Unlock cache entries that cache the specified memory range.
99  *	Entries not already locked are unaffected.
100  *
101  *  coherence_on
102  *  coherence_off
103  *      Turn off and on cache coherence
104  *
105  */
106 
107 
108 
109 /***************************   GENERIC -- ALL CACHES   ***************************/
110 
111 
112 /*
113  *  The following macros assume the following cache size/parameter limits
114  *  in the current Xtensa core implementation:
115  *	cache size:	1024 bytes minimum
116  *	line size:	16 - 64 bytes
117  *	way count:	1 - 4
118  *
119  *  Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4
120  *  Hence the assumption that each loop can execute four cache instructions.
121  *
122  *  Correspondingly, the offset range of instructions is assumed able to cover
123  *  four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for
124  *  both hit and indexed cache instructions.  Ie. these offsets are all
125  *  valid:  0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64).
126  *  This is true of all original cache instructions
127  *  (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets
128  *  of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2).
129  *  This is also true of subsequent cache instructions
130  *  (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets
131  *  of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4).
132  *
133  *  (Maximum cache size, currently 32k, doesn't affect the following macros.
134  *  Cache ways > MMU min page size cause aliasing but that's another matter.)
135  */
136 
137 
138 
139 /*
140  *  Macro to apply an 'indexed' cache instruction to the entire cache.
141  *
142  *  Parameters:
143  *	cainst      instruction/ that takes an address register parameter
144  *              and an offset parameter (in range 0 .. 3*linesize).
145  *	size        size of cache in bytes
146  *	linesize    size of cache line in bytes (always power-of-2)
147  *	assoc_or1   number of associativities (ways/sets) in cache
148  *                  if all sets affected by cainst,
149  *                  or 1 if only one set (or not all sets) of the cache
150  *                  is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]).
151  *	aa, ab      unique address registers (temporaries).
152  *	awb         set to other than a0 if wb type of instruction
153  *	loopokay    1 allows use of zero-overhead loops, 0 does not
154  *	immrange    range (max value) of cainst's immediate offset parameter, in bytes
155  *              (NOTE: macro assumes immrange allows power-of-2 number of lines)
156  */
157 
158 	.macro	cache_index_all		cainst, size, linesize, assoc_or1, aa, ab, loopokay, maxofs, awb=a0
159 
160 	//  Number of indices in cache (lines per way):
161 	.set	.Lindices, (\size / (\linesize * \assoc_or1))
162 	//  Number of indices processed per loop iteration (max 4):
163 	.set	.Lperloop, .Lindices
164 	.ifgt	.Lperloop - 4
165 	 .set	.Lperloop, 4
166 	.endif
167 	//  Also limit instructions per loop if cache line size exceeds immediate range:
168 	.set	.Lmaxperloop, (\maxofs / \linesize) + 1
169 	.ifgt	.Lperloop - .Lmaxperloop
170 	 .set	.Lperloop, .Lmaxperloop
171 	.endif
172 	//  Avoid addi of 128 which takes two instructions (addmi,addi):
173 	.ifeq	.Lperloop*\linesize - 128
174 	 .ifgt	.Lperloop - 1
175 	  .set	.Lperloop, .Lperloop / 2
176 	 .endif
177 	.endif
178 
179 	//  \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst.
180 	// XCHAL_ERRATUM_497 - don't execute using loop, to reduce the amount of added code
181 	.ifne	(\loopokay & XCHAL_HAVE_LOOPS && !XCHAL_ERRATUM_497)
182 
183 	movi	\aa, .Lindices / .Lperloop		// number of loop iterations
184 	// Possible improvement: need only loop if \aa > 1 ;
185 	// however \aa == 1 is highly unlikely.
186 	movi	\ab, 0		// to iterate over cache
187 	loop		\aa, .Lend_cachex\@
188 	.set	.Li, 0 ;     .rept .Lperloop
189 	  \cainst	\ab, .Li*\linesize
190 	.set	.Li, .Li+1 ; .endr
191 	addi		\ab, \ab, .Lperloop*\linesize	// move to next line
192 .Lend_cachex\@:
193 
194 	.else
195 
196 	movi	\aa, (\size / \assoc_or1)
197 	// Possible improvement: need only loop if \aa > 1 ;
198 	// however \aa == 1 is highly unlikely.
199 	movi	\ab, 0		// to iterate over cache
200 	.ifne	((\awb !=a0) & XCHAL_ERRATUM_497)		// don't use awb if set to a0
201 	movi \awb, 0
202 	.endif
203 .Lstart_cachex\@:
204 	.set	.Li, 0 ;     .rept .Lperloop
205 	  \cainst	\ab, .Li*\linesize
206 	.set	.Li, .Li+1 ; .endr
207 	.ifne	((\awb !=a0) & XCHAL_ERRATUM_497)		// do memw after 8 cainst wb instructions
208 	addi \awb, \awb, .Lperloop
209 	blti \awb, 8, .Lstart_memw\@
210 	memw
211 	movi \awb, 0
212 .Lstart_memw\@:
213 	.endif
214 	addi		\ab, \ab, .Lperloop*\linesize	// move to next line
215 	bltu		\ab, \aa, .Lstart_cachex\@
216 	.endif
217 
218 	.endm
219 
220 
221 /*
222  *  Macro to apply a 'hit' cache instruction to a memory region,
223  *  ie. to any cache entries that cache a specified portion (region) of memory.
224  *  Takes care of the unaligned cases, ie. may apply to one
225  *  more cache line than $asize / lineSize if $aaddr is not aligned.
226  *
227  *
228  *  Parameters are:
229  *	cainst	instruction/macro that takes an address register parameter
230  *		and an offset parameter (currently always zero)
231  *		and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.)
232  *	linesize_log2	log2(size of cache line in bytes)
233  *	addr	register containing start address of region (clobbered)
234  *	asize	register containing size of the region in bytes (clobbered)
235  *	askew	unique register used as temporary
236  *	awb		unique register used as temporary for erratum 497.
237  *
238  *  Note: A possible optimization to this macro is to apply the operation
239  *  to the entire cache if the region exceeds the size of the cache
240  *  by some empirically determined amount or factor.  Some experimentation
241  *  is required to determine the appropriate factors, which also need
242  *  to be tunable if required.
243  */
244 
245 	.macro	cache_hit_region	cainst, linesize_log2, addr, asize, askew, awb=a0
246 
247 	//  Make \asize the number of iterations:
248 	extui	\askew, \addr, 0, \linesize_log2	// get unalignment amount of \addr
249 	add	\asize, \asize, \askew			// ... and add it to \asize
250 	addi	\asize, \asize, (1 << \linesize_log2) - 1	// round up!
251 	srli	\asize, \asize, \linesize_log2
252 
253 	//  Iterate over region:
254 	.ifne	((\awb !=a0) & XCHAL_ERRATUM_497)		// don't use awb if set to a0
255 	movi \awb, 0
256 	.endif
257 	floopnez	\asize, cacheh\@
258 	\cainst		\addr, 0
259 	.ifne	((\awb !=a0) & XCHAL_ERRATUM_497)		// do memw after 8 cainst wb instructions
260 	addi \awb, \awb, 1
261 	blti \awb, 8, .Lstart_memw\@
262 	memw
263 	movi \awb, 0
264 .Lstart_memw\@:
265 	.endif
266 	addi		\addr, \addr, (1 << \linesize_log2)	// move to next line
267 	floopend	\asize, cacheh\@
268 	.endm
269 
270 
271 
272 
273 
274 /***************************   INSTRUCTION CACHE   ***************************/
275 
276 
277 /*
278  *  Reset/initialize the instruction cache by simply invalidating it:
279  *  (need to unlock first also, if cache locking implemented):
280  *
281  *  Parameters:
282  *	aa, ab		unique address registers (temporaries)
283  */
284 	.macro	icache_reset	aa, ab, loopokay=0
285 	icache_unlock_all	\aa, \ab, \loopokay
286 	icache_invalidate_all	\aa, \ab, \loopokay
287 	.endm
288 
289 
290 /*
291  * Synchronize after an instruction cache operation,
292  * to be sure everything is in sync with memory as to be
293  * expected following any previous instruction cache control operations.
294  *
295  * Even if a config doesn't have caches, an isync is still needed
296  * when instructions in any memory are modified, whether by a loader
297  * or self-modifying code.  Therefore, this macro always produces
298  * an isync, whether or not an icache is present.
299  *
300  * Parameters are:
301  *	ar	an address register (temporary) (currently unused, but may be used in future)
302  */
303 	.macro	icache_sync	ar
304 	isync
305 	.endm
306 
307 
308 
309 /*
310  *  Invalidate a single line of the instruction cache.
311  *  Parameters are:
312  *	ar	address register that contains (virtual) address to invalidate
313  *		(may get clobbered in a future implementation, but not currently)
314  *	offset	(optional) offset to add to \ar to compute effective address to invalidate
315  *		(note: some number of lsbits are ignored)
316  */
317 	.macro	icache_invalidate_line	ar, offset
318 #if XCHAL_ICACHE_SIZE > 0
319 	ihi	\ar, \offset		// invalidate icache line
320 	icache_sync	\ar
321 #endif
322 	.endm
323 
324 
325 
326 
327 /*
328  *  Invalidate instruction  cache entries that cache a specified portion of memory.
329  *  Parameters are:
330  *	astart	start address (register gets clobbered)
331  *	asize	size of the region in bytes (register gets clobbered)
332  *	ac	unique register used as temporary
333  */
334 	.macro	icache_invalidate_region	astart, asize, ac
335 #if XCHAL_ICACHE_SIZE > 0
336 	//  Instruction cache region invalidation:
337 	cache_hit_region	ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
338 	icache_sync	\ac
339 	//  End of instruction cache region invalidation
340 #endif
341 	.endm
342 
343 
344 
345 /*
346  *  Invalidate entire instruction cache.
347  *
348  *  Parameters:
349  *	aa, ab		unique address registers (temporaries)
350  */
351 	.macro	icache_invalidate_all	aa, ab, loopokay=1
352 #if XCHAL_ICACHE_SIZE > 0
353 	//  Instruction cache invalidation:
354 	cache_index_all		iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab, \loopokay, 1020
355 	icache_sync	\aa
356 	//  End of instruction cache invalidation
357 #endif
358 	.endm
359 
360 
361 
362 /*
363  *  Lock (prefetch & lock) a single line of the instruction cache.
364  *
365  *  Parameters are:
366  *	ar	address register that contains (virtual) address to lock
367  *		(may get clobbered in a future implementation, but not currently)
368  *	offset	offset to add to \ar to compute effective address to lock
369  *		(note: some number of lsbits are ignored)
370  */
371 	.macro	icache_lock_line	ar, offset
372 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
373 	ipfl	\ar, \offset	/* prefetch and lock icache line */
374 	icache_sync	\ar
375 #endif
376 	.endm
377 
378 
379 
380 /*
381  *  Lock (prefetch & lock) a specified portion of memory into the instruction cache.
382  *  Parameters are:
383  *	astart	start address (register gets clobbered)
384  *	asize	size of the region in bytes (register gets clobbered)
385  *	ac	unique register used as temporary
386  */
387 	.macro	icache_lock_region	astart, asize, ac
388 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
389 	//  Instruction cache region lock:
390 	cache_hit_region	ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
391 	icache_sync	\ac
392 	//  End of instruction cache region lock
393 #endif
394 	.endm
395 
396 
397 
398 /*
399  *  Unlock a single line of the instruction cache.
400  *
401  *  Parameters are:
402  *	ar	address register that contains (virtual) address to unlock
403  *		(may get clobbered in a future implementation, but not currently)
404  *	offset	offset to add to \ar to compute effective address to unlock
405  *		(note: some number of lsbits are ignored)
406  */
407 	.macro	icache_unlock_line	ar, offset
408 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
409 	ihu	\ar, \offset	/* unlock icache line */
410 	icache_sync	\ar
411 #endif
412 	.endm
413 
414 
415 
416 /*
417  *  Unlock a specified portion of memory from the instruction cache.
418  *  Parameters are:
419  *	astart	start address (register gets clobbered)
420  *	asize	size of the region in bytes (register gets clobbered)
421  *	ac	unique register used as temporary
422  */
423 	.macro	icache_unlock_region	astart, asize, ac
424 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
425 	//  Instruction cache region unlock:
426 	cache_hit_region	ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
427 	icache_sync	\ac
428 	//  End of instruction cache region unlock
429 #endif
430 	.endm
431 
432 
433 
434 /*
435  *  Unlock entire instruction cache.
436  *
437  *  Parameters:
438  *	aa, ab		unique address registers (temporaries)
439  */
440 	.macro	icache_unlock_all	aa, ab, loopokay=1
441 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
442 	//  Instruction cache unlock:
443 	cache_index_all		iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240
444 	icache_sync	\aa
445 	//  End of instruction cache unlock
446 #endif
447 	.endm
448 
449 
450 
451 
452 
453 /***************************   DATA CACHE   ***************************/
454 
455 
456 
457 /*
458  *  Reset/initialize the data cache by simply invalidating it
459  *  (need to unlock first also, if cache locking implemented):
460  *
461  *  Parameters:
462  *	aa, ab		unique address registers (temporaries)
463  */
464 	.macro	dcache_reset	aa, ab, loopokay=0
465 	dcache_unlock_all	\aa, \ab, \loopokay
466 	dcache_invalidate_all	\aa, \ab, \loopokay
467 	.endm
468 
469 
470 
471 
472 /*
473  * Synchronize after a data cache operation,
474  * to be sure everything is in sync with memory as to be
475  * expected following any previous data cache control operations.
476  *
477  * Parameters are:
478  *	ar	an address register (temporary) (currently unused, but may be used in future)
479  */
480 	.macro	dcache_sync	ar, wbtype=0
481 #if XCHAL_DCACHE_SIZE > 0
482 	//  No synchronization is needed.
483 	//  (memw may be desired e.g. after writeback operation to help ensure subsequent
484 	//   external accesses are seen to follow that writeback, however that's outside
485 	//   the scope of this macro)
486 
487 	//dsync
488 	.ifne	(\wbtype & XCHAL_ERRATUM_497)
489 	memw
490 	.endif
491 #endif
492 	.endm
493 
494 
495 
496 /*
497  * Turn on cache coherence.
498  *
499  * WARNING:  for RE-201x.x and later hardware, any interrupt that tries
500  * to change MEMCTL will see its changes dropped if the interrupt comes
501  * in the middle of this routine.  If this might be an issue, call this
502  * routine with interrupts disabled.
503  *
504  * Parameters are:
505  *	ar,at	two scratch address registers (both clobbered)
506  */
507 	.macro	cache_coherence_on	ar at
508 #if XCHAL_DCACHE_IS_COHERENT
509 # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
510 	/*  Have MEMCTL.  Enable snoop responses.  */
511 	rsr.memctl	\ar
512 	movi		\at, MEMCTL_SNOOP_EN
513 	or		\ar, \ar, \at
514 	wsr.memctl	\ar
515 # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX
516 	/* Opt into coherence for MX (for backward compatibility / testing).  */
517 	movi	\ar, 1
518 	movi	\at, XER_CCON
519 	wer	\ar, \at
520 	extw
521 # endif
522 #endif
523 	.endm
524 
525 
526 
527 /*
528  * Turn off cache coherence.
529  *
530  * NOTE:  this is generally preceded by emptying the cache;
531  * see xthal_cache_coherence_optout() in hal/coherence.c for details.
532  *
533  * WARNING:  for RE-201x.x and later hardware, any interrupt that tries
534  * to change MEMCTL will see its changes dropped if the interrupt comes
535  * in the middle of this routine.  If this might be an issue, call this
536  * routine with interrupts disabled.
537  *
538  * Parameters are:
539  *	ar,at	two scratch address registers (both clobbered)
540  */
541 	.macro	cache_coherence_off	ar at
542 #if XCHAL_DCACHE_IS_COHERENT
543 # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
544 	/*  Have MEMCTL.  Disable snoop responses.  */
545 	rsr.memctl	\ar
546 	movi		\at, ~MEMCTL_SNOOP_EN
547 	and		\ar, \ar, \at
548 	wsr.memctl	\ar
549 # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX
550 	/* Opt out of coherence, for MX (for backward compatibility / testing).  */
551 	extw
552 	movi	\at, 0
553 	movi	\ar, XER_CCON
554 	wer	\at, \ar
555 	extw
556 # endif
557 #endif
558 	.endm
559 
560 
561 
562 /*
563  * Synchronize after a data store operation,
564  * to be sure the stored data is completely off the processor
565  * (and assuming there is no buffering outside the processor,
566  *  that the data is in memory).  This may be required to
567  * ensure that the processor's write buffers are emptied.
568  * A MEMW followed by a read guarantees this, by definition.
569  * We also try to make sure the read itself completes.
570  *
571  * Parameters are:
572  *	ar	an address register (temporary)
573  */
574 	.macro	write_sync	ar
575 	memw			// ensure previous memory accesses are complete prior to subsequent memory accesses
576 	l32i	\ar, sp, 0	// completing this read ensures any previous write has completed, because of MEMW
577 	//slot
578 	add	\ar, \ar, \ar	// use the result of the read to help ensure the read completes (in future architectures)
579 	.endm
580 
581 
582 /*
583  *  Invalidate a single line of the data cache.
584  *  Parameters are:
585  *	ar	address register that contains (virtual) address to invalidate
586  *		(may get clobbered in a future implementation, but not currently)
587  *	offset	(optional) offset to add to \ar to compute effective address to invalidate
588  *		(note: some number of lsbits are ignored)
589  */
590 	.macro	dcache_invalidate_line	ar, offset
591 #if XCHAL_DCACHE_SIZE > 0
592 	dhi	\ar, \offset
593 	dcache_sync	\ar
594 #endif
595 	.endm
596 
597 
598 
599 
600 
601 /*
602  *  Invalidate data cache entries that cache a specified portion of memory.
603  *  Parameters are:
604  *	astart	start address (register gets clobbered)
605  *	asize	size of the region in bytes (register gets clobbered)
606  *	ac	unique register used as temporary
607  */
608 	.macro	dcache_invalidate_region	astart, asize, ac
609 #if XCHAL_DCACHE_SIZE > 0
610 	//  Data cache region invalidation:
611 	cache_hit_region	dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
612 	dcache_sync	\ac
613 	//  End of data cache region invalidation
614 #endif
615 	.endm
616 
617 
618 
619 /*
620  *  Invalidate entire data cache.
621  *
622  *  Parameters:
623  *	aa, ab		unique address registers (temporaries)
624  */
625 	.macro	dcache_invalidate_all	aa, ab, loopokay=1
626 #if XCHAL_DCACHE_SIZE > 0
627 	//  Data cache invalidation:
628 	cache_index_all		dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab, \loopokay, 1020
629 	dcache_sync	\aa
630 	//  End of data cache invalidation
631 #endif
632 	.endm
633 
634 
635 
636 /*
637  *  Writeback a single line of the data cache.
638  *  Parameters are:
639  *	ar	address register that contains (virtual) address to writeback
640  *		(may get clobbered in a future implementation, but not currently)
641  *	offset	offset to add to \ar to compute effective address to writeback
642  *		(note: some number of lsbits are ignored)
643  */
644 	.macro	dcache_writeback_line	ar, offset
645 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
646 	dhwb	\ar, \offset
647 	dcache_sync	\ar, wbtype=1
648 #endif
649 	.endm
650 
651 
652 
653 /*
654  *  Writeback dirty data cache entries that cache a specified portion of memory.
655  *  Parameters are:
656  *	astart	start address (register gets clobbered)
657  *	asize	size of the region in bytes (register gets clobbered)
658  *	ac	unique register used as temporary
659  */
660 	.macro	dcache_writeback_region		astart, asize, ac, awb
661 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
662 	//  Data cache region writeback:
663 	cache_hit_region	dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb
664 	dcache_sync	\ac, wbtype=1
665 	//  End of data cache region writeback
666 #endif
667 	.endm
668 
669 
670 
671 /*
672  *  Writeback entire data cache.
673  *  Parameters:
674  *	aa, ab		unique address registers (temporaries)
675  */
676 	.macro	dcache_writeback_all	aa, ab, awb, loopokay=1
677 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
678 	//  Data cache writeback:
679 	cache_index_all		diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb,
680 	dcache_sync	\aa, wbtype=1
681 	//  End of data cache writeback
682 #endif
683 	.endm
684 
685 
686 
687 /*
688  *  Writeback and invalidate a single line of the data cache.
689  *  Parameters are:
690  *	ar	address register that contains (virtual) address to writeback and invalidate
691  *		(may get clobbered in a future implementation, but not currently)
692  *	offset	offset to add to \ar to compute effective address to writeback and invalidate
693  *		(note: some number of lsbits are ignored)
694  */
695 	.macro	dcache_writeback_inv_line	ar, offset
696 #if XCHAL_DCACHE_SIZE > 0
697 	dhwbi	\ar, \offset	/* writeback and invalidate dcache line */
698 	dcache_sync	\ar, wbtype=1
699 #endif
700 	.endm
701 
702 
703 
704 /*
705  *  Writeback and invalidate data cache entries that cache a specified portion of memory.
706  *  Parameters are:
707  *	astart	start address (register gets clobbered)
708  *	asize	size of the region in bytes (register gets clobbered)
709  *	ac	unique register used as temporary
710  */
711 	.macro	dcache_writeback_inv_region	astart, asize, ac, awb
712 #if XCHAL_DCACHE_SIZE > 0
713 	//  Data cache region writeback and invalidate:
714 	cache_hit_region	dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb
715 	dcache_sync	\ac, wbtype=1
716 	//  End of data cache region writeback and invalidate
717 #endif
718 	.endm
719 
720 
721 
722 /*
723  *  Writeback and invalidate entire data cache.
724  *  Parameters:
725  *	aa, ab		unique address registers (temporaries)
726  */
727 	.macro	dcache_writeback_inv_all	aa, ab, awb, loopokay=1
728 #if XCHAL_DCACHE_SIZE > 0
729 	//  Data cache writeback and invalidate:
730 #if XCHAL_DCACHE_IS_WRITEBACK
731 	cache_index_all		diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb
732 	dcache_sync	\aa, wbtype=1
733 #else /*writeback*/
734 	//  Data cache does not support writeback, so just invalidate: */
735 	dcache_invalidate_all	\aa, \ab, \loopokay
736 #endif /*writeback*/
737 	//  End of data cache writeback and invalidate
738 #endif
739 	.endm
740 
741 
742 
743 
744 /*
745  *  Lock (prefetch & lock) a single line of the data cache.
746  *
747  *  Parameters are:
748  *	ar	address register that contains (virtual) address to lock
749  *		(may get clobbered in a future implementation, but not currently)
750  *	offset	offset to add to \ar to compute effective address to lock
751  *		(note: some number of lsbits are ignored)
752  */
753 	.macro	dcache_lock_line	ar, offset
754 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
755 	dpfl	\ar, \offset	/* prefetch and lock dcache line */
756 	dcache_sync	\ar
757 #endif
758 	.endm
759 
760 
761 
762 /*
763  *  Lock (prefetch & lock) a specified portion of memory into the data cache.
764  *  Parameters are:
765  *	astart	start address (register gets clobbered)
766  *	asize	size of the region in bytes (register gets clobbered)
767  *	ac	unique register used as temporary
768  */
769 	.macro	dcache_lock_region	astart, asize, ac
770 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
771 	//  Data cache region lock:
772 	cache_hit_region	dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
773 	dcache_sync	\ac
774 	//  End of data cache region lock
775 #endif
776 	.endm
777 
778 
779 
780 /*
781  *  Unlock a single line of the data cache.
782  *
783  *  Parameters are:
784  *	ar	address register that contains (virtual) address to unlock
785  *		(may get clobbered in a future implementation, but not currently)
786  *	offset	offset to add to \ar to compute effective address to unlock
787  *		(note: some number of lsbits are ignored)
788  */
789 	.macro	dcache_unlock_line	ar, offset
790 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
791 	dhu	\ar, \offset	/* unlock dcache line */
792 	dcache_sync	\ar
793 #endif
794 	.endm
795 
796 
797 
798 /*
799  *  Unlock a specified portion of memory from the data cache.
800  *  Parameters are:
801  *	astart	start address (register gets clobbered)
802  *	asize	size of the region in bytes (register gets clobbered)
803  *	ac	unique register used as temporary
804  */
805 	.macro	dcache_unlock_region	astart, asize, ac
806 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
807 	//  Data cache region unlock:
808 	cache_hit_region	dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
809 	dcache_sync	\ac
810 	//  End of data cache region unlock
811 #endif
812 	.endm
813 
814 
815 
816 /*
817  *  Unlock entire data cache.
818  *
819  *  Parameters:
820  *	aa, ab		unique address registers (temporaries)
821  */
822 	.macro	dcache_unlock_all	aa, ab, loopokay=1
823 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
824 	//  Data cache unlock:
825 	cache_index_all		diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab,  \loopokay, 240
826 	dcache_sync	\aa
827 	//  End of data cache unlock
828 #endif
829 	.endm
830 
831 
832 
833 /*
834  * Get the number of enabled icache ways. Note that this may
835  * be different from the value read from the MEMCTL register.
836  *
837  * Parameters:
838  *	aa	address register where value is returned
839  */
840 	.macro	icache_get_ways		aa
841 #if XCHAL_ICACHE_SIZE > 0
842 #if XCHAL_HAVE_ICACHE_DYN_WAYS
843 	// Read from MEMCTL and shift/mask
844 	rsr.memctl	\aa
845 	extui	\aa, \aa, MEMCTL_ICWU_SHIFT, MEMCTL_ICWU_BITS
846 	blti	\aa, XCHAL_ICACHE_WAYS, .Licgw
847 	movi	\aa, XCHAL_ICACHE_WAYS
848 .Licgw:
849 #else
850 	// All ways are always enabled
851 	movi	\aa, XCHAL_ICACHE_WAYS
852 #endif
853 #else
854 	// No icache
855 	movi	\aa, 0
856 #endif
857 	.endm
858 
859 
860 
861 /*
862  * Set the number of enabled icache ways.
863  *
864  * Parameters:
865  *	aa      address register specifying number of ways (trashed)
866  *	ab,ac	address register for scratch use (trashed)
867  */
868 	.macro  icache_set_ways		aa, ab, ac
869 #if XCHAL_ICACHE_SIZE > 0
870 #if XCHAL_HAVE_ICACHE_DYN_WAYS
871 	movi	\ac, MEMCTL_ICWU_CLR_MASK	// set up to clear bits 18-22
872 	rsr.memctl	\ab
873 	and	\ab, \ab, \ac
874 	movi	\ac, MEMCTL_INV_EN		// set bit 23
875 	slli	\aa, \aa, MEMCTL_ICWU_SHIFT	// move to right spot
876 	or	\ab, \ab, \aa
877 	or	\ab, \ab, \ac
878 	wsr.memctl	\ab
879 	isync
880 #else
881 	// All ways are always enabled
882 #endif
883 #else
884 	// No icache
885 #endif
886 	.endm
887 
888 
889 
890 /*
891  * Get the number of enabled dcache ways. Note that this may
892  * be different from the value read from the MEMCTL register.
893  *
894  * Parameters:
895  *	aa	address register where value is returned
896  */
897 	.macro	dcache_get_ways		aa
898 #if XCHAL_DCACHE_SIZE > 0
899 #if XCHAL_HAVE_DCACHE_DYN_WAYS
900 	// Read from MEMCTL and shift/mask
901 	rsr.memctl	\aa
902 	extui	\aa, \aa, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS
903 	blti	\aa, XCHAL_DCACHE_WAYS, .Ldcgw
904 	movi	\aa, XCHAL_DCACHE_WAYS
905 .Ldcgw:
906 #else
907 	// All ways are always enabled
908 	movi	\aa, XCHAL_DCACHE_WAYS
909 #endif
910 #else
911 	// No dcache
912 	movi	\aa, 0
913 #endif
914 	.endm
915 
916 
917 
918 /*
919  * Set the number of enabled dcache ways.
920  *
921  * Parameters:
922  *	aa	address register specifying number of ways (trashed)
923  *	ab,ac	address register for scratch use (trashed)
924  */
925 	.macro	dcache_set_ways		aa, ab, ac
926 #if (XCHAL_DCACHE_SIZE > 0) && XCHAL_HAVE_DCACHE_DYN_WAYS
927 	movi	\ac, MEMCTL_DCWA_CLR_MASK	// set up to clear bits 13-17
928 	rsr.memctl	\ab
929 	and	\ab, \ab, \ac			// clear ways allocatable
930 	slli	\ac, \aa, MEMCTL_DCWA_SHIFT
931 	or	\ab, \ab, \ac			// set ways allocatable
932 	wsr.memctl	\ab
933 #if XCHAL_DCACHE_IS_WRITEBACK
934 	// Check if the way count is increasing or decreasing
935 	extui	\ac, \ab, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS			// bits 8-12 - ways in use
936 	bge	\aa, \ac, .Ldsw3						// equal or increasing
937 	slli	\ab, \aa, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH	// start way number
938 	slli	\ac, \ac, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH	// end way number
939 .Ldsw1:
940 	diwbui.p	\ab		// auto-increments ab
941 	bge	\ab, \ac, .Ldsw2
942 	beqz	\ab, .Ldsw2
943 	j	.Ldsw1
944 .Ldsw2:
945 	rsr.memctl	\ab
946 #endif
947 .Ldsw3:
948 	// No dirty data to write back, just set the new number of ways
949 	movi	\ac, MEMCTL_DCWU_CLR_MASK		// set up to clear bits 8-12
950 	and	\ab, \ab, \ac				// clear ways in use
951 	movi	\ac, MEMCTL_INV_EN
952 	or	\ab, \ab, \ac				// set bit 23
953 	slli	\aa, \aa, MEMCTL_DCWU_SHIFT
954 	or	\ab, \ab, \aa				// set ways in use
955 	wsr.memctl	\ab
956 #else
957 	// No dcache or no way disable support
958 #endif
959 	.endm
960 
961 #endif /*XTENSA_CACHEASM_H*/
962 
963