1 /*
2  * Copyright (c) 2016 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/arch/cpu.h>
8 #include <zephyr/sys/__assert.h>
9 
10 
11 /**
12  * Flush the entire instruction cache and pipeline.
13  *
14  * You will need to call this function if the application writes new program
15  * text to memory, such as a boot copier or runtime synthesis of code.  If the
16  * new text was written with instructions that do not bypass cache memories,
17  * this should immediately be followed by an invocation of
18  * z_nios2_dcache_flush_all() so that cached instruction data is committed to
19  * RAM.
20  *
21  * See Chapter 9 of the Nios II Gen 2 Software Developer's Handbook for more
22  * information on cache considerations.
23  */
24 #if ALT_CPU_ICACHE_SIZE > 0
z_nios2_icache_flush_all(void)25 void z_nios2_icache_flush_all(void)
26 {
27 	uint32_t i;
28 
29 	for (i = 0U; i < ALT_CPU_ICACHE_SIZE; i += ALT_CPU_ICACHE_LINE_SIZE) {
30 		z_nios2_icache_flush(i);
31 	}
32 
33 	/* Get rid of any stale instructions in the pipeline */
34 	z_nios2_pipeline_flush();
35 }
36 #endif
37 
38 /**
39  * Flush the entire data cache.
40  *
41  * This will be typically needed after writing new program text to memory
42  * after flushing the instruction cache.
43  *
44  * The Nios II does not support hardware cache coherency for multi-master
45  * or multi-processor systems and software coherency must be implemented
46  * when communicating with shared memory. If support for this is introduced
47  * in Zephyr additional APIs for flushing ranges of the data cache will need
48  * to be implemented.
49  *
50  * See Chapter 9 of the Nios II Gen 2 Software Developer's Handbook for more
51  * information on cache considerations.
52  */
53 #if ALT_CPU_DCACHE_SIZE > 0
z_nios2_dcache_flush_all(void)54 void z_nios2_dcache_flush_all(void)
55 {
56 	uint32_t i;
57 
58 	for (i = 0U; i < ALT_CPU_DCACHE_SIZE; i += ALT_CPU_DCACHE_LINE_SIZE) {
59 		z_nios2_dcache_flush(i);
60 	}
61 }
62 #endif
63 
64 /*
65  * z_nios2_dcache_flush_no_writeback() is called to flush the data cache for a
66  * memory region of length "len" bytes, starting at address "start".
67  *
68  * Any dirty lines in the data cache are NOT written back to memory.
69  * Make sure you really want this behavior.  If you aren't 100% sure,
70  * use the z_nios2_dcache_flush() routine instead.
71  */
72 #if ALT_CPU_DCACHE_SIZE > 0
z_nios2_dcache_flush_no_writeback(void * start,uint32_t len)73 void z_nios2_dcache_flush_no_writeback(void *start, uint32_t len)
74 {
75 	uint8_t *i;
76 	uint8_t *end = ((char *) start) + len;
77 
78 	for (i = start; i < end; i += ALT_CPU_DCACHE_LINE_SIZE) {
79 		__asm__ volatile ("initda (%0)" :: "r" (i));
80 	}
81 
82 	/*
83 	 * For an unaligned flush request, we've got one more line left.
84 	 * Note that this is dependent on ALT_CPU_DCACHE_LINE_SIZE to be a
85 	 * multiple of 2 (which it always is).
86 	 */
87 
88 	if (((uint32_t) start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) {
89 		__asm__ volatile ("initda (%0)" :: "r" (i));
90 	}
91 }
92 #endif
93