~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/v850/kernel/v850e_cache.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * arch/v850/kernel/v850e_cache.c -- Cache control for V850E cache memories
  3  *
  4  *  Copyright (C) 2003  NEC Electronics Corporation
  5  *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
  6  *
  7  * This file is subject to the terms and conditions of the GNU General
  8  * Public License.  See the file COPYING in the main directory of this
  9  * archive for more details.
 10  *
 11  * Written by Miles Bader <miles@gnu.org>
 12  */
 13 
 14 /* This file implements cache control for the rather simple cache used on
 15    some V850E CPUs, specifically the NB85E/TEG CPU-core and the V850E/ME2
 16    CPU.  V850E2 processors have their own (better) cache
 17    implementation.  */
 18 
 19 #include <asm/entry.h>
 20 #include <asm/v850e_cache.h>
 21 
 22 #define WAIT_UNTIL_CLEAR(value) while (value) {}
 23 
 24 /* Set caching params via the BHC and DCC registers.  */
 25 void v850e_cache_enable (u16 bhc, u16 icc, u16 dcc)
 26 {
 27         unsigned long *r0_ram = (unsigned long *)R0_RAM_ADDR;
 28         register u16 bhc_val asm ("r6") = bhc;
 29 
 30         /* Read the instruction cache control register (ICC) and confirm
 31            that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
 32         WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
 33         V850E_CACHE_ICC = icc;
 34 
 35 #ifdef V850E_CACHE_DCC
 36         /* Configure data-cache.  */
 37         V850E_CACHE_DCC = dcc;
 38 #endif /* V850E_CACHE_DCC */
 39 
 40         /* Configure caching for various memory regions by writing the BHC
 41            register.  The documentation says that an instruction _cannot_
 42            enable/disable caching for the memory region in which the
 43            instruction itself exists; to work around this, we store
 44            appropriate instructions into the on-chip RAM area (which is never
 45            cached), and briefly jump there to do the work.  */
 46 #ifdef V850E_CACHE_WRITE_IBS
 47         *r0_ram++       = 0xf0720760;   /* st.h r0, 0xfffff072[r0] */
 48 #endif
 49         *r0_ram++       = 0xf06a3760;   /* st.h r6, 0xfffff06a[r0] */
 50         *r0_ram         = 0x5640006b;   /* jmp [r11] */
 51 
 52         asm ("mov hilo(1f), r11; jmp [%1]; 1:;"
 53              :: "r" (bhc_val), "r" (R0_RAM_ADDR) : "r11");
 54 }
 55 
 56 static void clear_icache (void)
 57 {
 58         /* 1. Read the instruction cache control register (ICC) and confirm
 59               that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
 60         WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
 61 
 62         /* 2. Read the ICC register and confirm that bit 12 (LOCK0) is
 63               cleared.  Bit 13 of the ICC register is always cleared.  */
 64         WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x1000);
 65 
 66         /* 3. Set the TCLR0 and TCLR1 bits of the ICC register as follows,
 67               when clearing way 0 and way 1 at the same time:
 68                 (a) Set the TCLR0 and TCLR1 bits.
 69                 (b) Read the TCLR0 and TCLR1 bits to confirm that these bits
 70                     are cleared.
 71                 (c) Perform (a) and (b) above again.  */
 72         V850E_CACHE_ICC |= 0x3;
 73         WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
 74 
 75 #ifdef V850E_CACHE_REPEAT_ICC_WRITE
 76         /* Do it again.  */
 77         V850E_CACHE_ICC |= 0x3;
 78         WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
 79 #endif
 80 }
 81 
 82 #ifdef V850E_CACHE_DCC
 83 /* Flush or clear (or both) the data cache, depending on the value of FLAGS;
 84    the procedure is the same for both, just the control bits used differ (and
 85    both may be performed simultaneously).  */
 86 static void dcache_op (unsigned short flags)
 87 {
 88         /* 1. Read the data cache control register (DCC) and confirm that bits
 89               0, 1, 4, and 5 (DC00, DC01, DC04, DC05) are all cleared.  */
 90         WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & 0x33);
 91 
 92         /* 2. Clear DCC register bit 12 (DC12), bit 13 (DC13), or both
 93               depending on the way for which tags are to be cleared.  */
 94         V850E_CACHE_DCC &= ~0xC000;
 95 
 96         /* 3. Set DCC register bit 0 (DC00), bit 1 (DC01) or both depending on
 97               the way for which tags are to be cleared.
 98               ...
 99               Set DCC register bit 4 (DC04), bit 5 (DC05), or both depending
100               on the way to be data flushed.  */
101         V850E_CACHE_DCC |= flags;
102 
103         /* 4. Read DCC register bit DC00, DC01 [DC04, DC05], or both depending
104               on the way for which tags were cleared [flushed] and confirm
105               that that bit is cleared.  */
106         WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & flags);
107 }
108 #endif /* V850E_CACHE_DCC */
109 
110 /* Flushes the contents of the dcache to memory.  */
111 static inline void flush_dcache (void)
112 {
113 #ifdef V850E_CACHE_DCC
114         /* We only need to do something if in write-back mode.  */
115         if (V850E_CACHE_DCC & 0x0400)
116                 dcache_op (0x30);
117 #endif /* V850E_CACHE_DCC */
118 }
119 
120 /* Flushes the contents of the dcache to memory, and then clears it.  */
121 static inline void clear_dcache (void)
122 {
123 #ifdef V850E_CACHE_DCC
124         /* We only need to do something if the dcache is enabled.  */
125         if (V850E_CACHE_DCC & 0x0C00)
126                 dcache_op (0x33);
127 #endif /* V850E_CACHE_DCC */
128 }
129 
130 /* Clears the dcache without flushing to memory first.  */
131 static inline void clear_dcache_no_flush (void)
132 {
133 #ifdef V850E_CACHE_DCC
134         /* We only need to do something if the dcache is enabled.  */
135         if (V850E_CACHE_DCC & 0x0C00)
136                 dcache_op (0x3);
137 #endif /* V850E_CACHE_DCC */
138 }
139 
140 static inline void cache_exec_after_store (void)
141 {
142         flush_dcache ();
143         clear_icache ();
144 }
145 
146 
147 /* Exported functions.  */
148 
149 void flush_icache (void)
150 {
151         cache_exec_after_store ();
152 }
153 
154 void flush_icache_range (unsigned long start, unsigned long end)
155 {
156         cache_exec_after_store ();
157 }
158 
159 void flush_icache_page (struct vm_area_struct *vma, struct page *page)
160 {
161         cache_exec_after_store ();
162 }
163 
164 void flush_icache_user_range (struct vm_area_struct *vma, struct page *page,
165                               unsigned long adr, int len)
166 {
167         cache_exec_after_store ();
168 }
169 
170 void flush_cache_sigtramp (unsigned long addr)
171 {
172         cache_exec_after_store ();
173 }
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp