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

TOMOYO Linux Cross Reference
Linux/arch/sparc/mm/leon_mm.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/sparc/mm/leon_mm.c (Architecture i386) and /arch/alpha/mm/leon_mm.c (Architecture alpha)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  *  linux/arch/sparc/mm/leon_m.c                  
  4  *                                                
  5  * Copyright (C) 2004 Konrad Eisele (eiselekd@    
  6  * Copyright (C) 2009 Daniel Hellstrom (daniel    
  7  * Copyright (C) 2009 Konrad Eisele (konrad@ga    
  8  *                                                
  9  * do srmmu probe in software                     
 10  *                                                
 11  */                                               
 12                                                   
 13 #include <linux/kernel.h>                         
 14 #include <linux/mm.h>                             
 15 #include <asm/asi.h>                              
 16 #include <asm/leon.h>                             
 17 #include <asm/tlbflush.h>                         
 18                                                   
 19 #include "mm_32.h"                                
 20                                                   
 21 int leon_flush_during_switch = 1;                 
 22 static int srmmu_swprobe_trace;                   
 23                                                   
 24 static inline unsigned long leon_get_ctable_pt    
 25 {                                                 
 26         unsigned int retval;                      
 27                                                   
 28         __asm__ __volatile__("lda [%1] %2, %0\    
 29                              "=r" (retval) :      
 30                              "r" (SRMMU_CTXTBL    
 31                              "i" (ASI_LEON_MMU    
 32         return (retval & SRMMU_CTX_PMASK) << 4    
 33 }                                                 
 34                                                   
 35                                                   
 36 unsigned long leon_swprobe(unsigned long vaddr    
 37 {                                                 
 38                                                   
 39         unsigned int ctxtbl;                      
 40         unsigned int pgd, pmd, ped;               
 41         unsigned int ptr;                         
 42         unsigned int lvl, pte;                    
 43         unsigned int ctx;                         
 44         unsigned int paddr_calc;                  
 45                                                   
 46         if (srmmu_swprobe_trace)                  
 47                 printk(KERN_INFO "swprobe: tra    
 48                                                   
 49         ctxtbl = leon_get_ctable_ptr();           
 50         if (!(ctxtbl)) {                          
 51                 if (srmmu_swprobe_trace)          
 52                         printk(KERN_INFO "swpr    
 53                 return 0;                         
 54         }                                         
 55         if (!_pfn_valid(PFN(ctxtbl))) {           
 56                 if (srmmu_swprobe_trace)          
 57                         printk(KERN_INFO          
 58                                "swprobe: !_pfn    
 59                                PFN(ctxtbl));      
 60                 return 0;                         
 61         }                                         
 62                                                   
 63         ctx = srmmu_get_context();                
 64         if (srmmu_swprobe_trace)                  
 65                 printk(KERN_INFO "swprobe:  --    
 66                                                   
 67         pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ct    
 68                                                   
 69         if (((pgd & SRMMU_ET_MASK) == SRMMU_ET    
 70                 if (srmmu_swprobe_trace)          
 71                         printk(KERN_INFO "swpr    
 72                 lvl = 3;                          
 73                 pte = pgd;                        
 74                 goto ready;                       
 75         }                                         
 76         if (((pgd & SRMMU_ET_MASK) != SRMMU_ET    
 77                 if (srmmu_swprobe_trace)          
 78                         printk(KERN_INFO "swpr    
 79                 return 0;                         
 80         }                                         
 81                                                   
 82         if (srmmu_swprobe_trace)                  
 83                 printk(KERN_INFO "swprobe:  --    
 84                                                   
 85         ptr = (pgd & SRMMU_PTD_PMASK) << 4;       
 86         ptr += ((((vaddr) >> LEON_PGD_SH) & LE    
 87         if (!_pfn_valid(PFN(ptr)))                
 88                 return 0;                         
 89                                                   
 90         pmd = LEON_BYPASS_LOAD_PA(ptr);           
 91         if (((pmd & SRMMU_ET_MASK) == SRMMU_ET    
 92                 if (srmmu_swprobe_trace)          
 93                         printk(KERN_INFO "swpr    
 94                 lvl = 2;                          
 95                 pte = pmd;                        
 96                 goto ready;                       
 97         }                                         
 98         if (((pmd & SRMMU_ET_MASK) != SRMMU_ET    
 99                 if (srmmu_swprobe_trace)          
100                         printk(KERN_INFO "swpr    
101                 return 0;                         
102         }                                         
103                                                   
104         if (srmmu_swprobe_trace)                  
105                 printk(KERN_INFO "swprobe:  --    
106                                                   
107         ptr = (pmd & SRMMU_PTD_PMASK) << 4;       
108         ptr += (((vaddr >> LEON_PMD_SH) & LEON    
109         if (!_pfn_valid(PFN(ptr))) {              
110                 if (srmmu_swprobe_trace)          
111                         printk(KERN_INFO "swpr    
112                                PFN(ptr));         
113                 return 0;                         
114         }                                         
115                                                   
116         ped = LEON_BYPASS_LOAD_PA(ptr);           
117                                                   
118         if (((ped & SRMMU_ET_MASK) == SRMMU_ET    
119                 if (srmmu_swprobe_trace)          
120                         printk(KERN_INFO "swpr    
121                 lvl = 1;                          
122                 pte = ped;                        
123                 goto ready;                       
124         }                                         
125         if (((ped & SRMMU_ET_MASK) != SRMMU_ET    
126                 if (srmmu_swprobe_trace)          
127                         printk(KERN_INFO "swpr    
128                 return 0;                         
129         }                                         
130                                                   
131         if (srmmu_swprobe_trace)                  
132                 printk(KERN_INFO "swprobe:  --    
133                                                   
134         ptr = (ped & SRMMU_PTD_PMASK) << 4;       
135         ptr += (((vaddr >> LEON_PTE_SH) & LEON    
136         if (!_pfn_valid(PFN(ptr)))                
137                 return 0;                         
138                                                   
139         ptr = LEON_BYPASS_LOAD_PA(ptr);           
140         if (((ptr & SRMMU_ET_MASK) == SRMMU_ET    
141                 if (srmmu_swprobe_trace)          
142                         printk(KERN_INFO "swpr    
143                 lvl = 0;                          
144                 pte = ptr;                        
145                 goto ready;                       
146         }                                         
147         if (srmmu_swprobe_trace)                  
148                 printk(KERN_INFO "swprobe: ptr    
149         return 0;                                 
150                                                   
151 ready:                                            
152         switch (lvl) {                            
153         case 0:                                   
154                 paddr_calc =                      
155                     (vaddr & ~(-1 << LEON_PTE_    
156                 break;                            
157         case 1:                                   
158                 paddr_calc =                      
159                     (vaddr & ~(-1 << LEON_PMD_    
160                 break;                            
161         case 2:                                   
162                 paddr_calc =                      
163                     (vaddr & ~(-1 << LEON_PGD_    
164                 break;                            
165         default:                                  
166         case 3:                                   
167                 paddr_calc = vaddr;               
168                 break;                            
169         }                                         
170         if (srmmu_swprobe_trace)                  
171                 printk(KERN_INFO "swprobe: pad    
172         if (paddr)                                
173                 *paddr = paddr_calc;              
174         return pte;                               
175 }                                                 
176                                                   
177 void leon_flush_icache_all(void)                  
178 {                                                 
179         __asm__ __volatile__(" flush ");          
180 }                                                 
181                                                   
182 void leon_flush_dcache_all(void)                  
183 {                                                 
184         __asm__ __volatile__("sta %%g0, [%%g0]    
185                              "i"(ASI_LEON_DFLU    
186 }                                                 
187                                                   
188 void leon_flush_pcache_all(struct vm_area_stru    
189 {                                                 
190         if (vma->vm_flags & VM_EXEC)              
191                 leon_flush_icache_all();          
192         leon_flush_dcache_all();                  
193 }                                                 
194                                                   
195 void leon_flush_cache_all(void)                   
196 {                                                 
197         __asm__ __volatile__(" flush ");          
198         __asm__ __volatile__("sta %%g0, [%%g0]    
199                              "i"(ASI_LEON_DFLU    
200 }                                                 
201                                                   
202 void leon_flush_tlb_all(void)                     
203 {                                                 
204         leon_flush_cache_all();                   
205         __asm__ __volatile__("sta %%g0, [%0] %    
206                              "i"(ASI_LEON_MMUF    
207 }                                                 
208                                                   
209 /* get all cache regs */                          
210 void leon3_getCacheRegs(struct leon3_cacheregs    
211 {                                                 
212         unsigned long ccr, iccr, dccr;            
213                                                   
214         if (!regs)                                
215                 return;                           
216         /* Get Cache regs from "Cache ASI" add    
217         __asm__ __volatile__("lda [%%g0] %3, %    
218                              "mov 0x08, %%g1\n    
219                              "lda [%%g1] %3, %    
220                              "mov 0x0c, %%g1\n    
221                              "lda [%%g1] %3, %    
222                              : "=r"(ccr), "=r"    
223                                /* output */       
224                              : "i"(ASI_LEON_CA    
225                              : "g1"     /* clo    
226             );                                    
227         regs->ccr = ccr;                          
228         regs->iccr = iccr;                        
229         regs->dccr = dccr;                        
230 }                                                 
231                                                   
232 /* Due to virtual cache we need to check cache    
233  * it is possible to skip flushing in some cas    
234  *                                                
235  * Leon2 and Leon3 differ in their way of tell    
236  *                                                
237  */                                               
238 int __init leon_flush_needed(void)                
239 {                                                 
240         int flush_needed = -1;                    
241         unsigned int ssize, sets;                 
242         char *setStr[4] =                         
243             { "direct mapped", "2-way associat    
244                 "4-way associative"               
245         };                                        
246         /* leon 3 */                              
247         struct leon3_cacheregs cregs;             
248         leon3_getCacheRegs(&cregs);               
249         sets = (cregs.dccr & LEON3_XCCR_SETS_M    
250         /* (ssize=>realsize) 0=>1k, 1=>2k, 2=>    
251         ssize = 1 << ((cregs.dccr & LEON3_XCCR    
252                                                   
253         printk(KERN_INFO "CACHE: %s cache, set    
254                sets > 3 ? "unknown" : setStr[s    
255         if ((ssize <= (PAGE_SIZE / 1024)) && (    
256                 /* Set Size <= Page size  ==>     
257                    flush on every context swit    
258                 flush_needed = 0;                 
259                 printk(KERN_INFO "CACHE: not f    
260         }                                         
261         return flush_needed;                      
262 }                                                 
263                                                   
264 void leon_switch_mm(void)                         
265 {                                                 
266         flush_tlb_mm((void *)0);                  
267         if (leon_flush_during_switch)             
268                 leon_flush_cache_all();           
269 }                                                 
270                                                   
271 static void leon_flush_cache_mm(struct mm_stru    
272 {                                                 
273         leon_flush_cache_all();                   
274 }                                                 
275                                                   
276 static void leon_flush_cache_page(struct vm_ar    
277 {                                                 
278         leon_flush_pcache_all(vma, page);         
279 }                                                 
280                                                   
281 static void leon_flush_cache_range(struct vm_a    
282                                    unsigned lo    
283                                    unsigned lo    
284 {                                                 
285         leon_flush_cache_all();                   
286 }                                                 
287                                                   
288 static void leon_flush_tlb_mm(struct mm_struct    
289 {                                                 
290         leon_flush_tlb_all();                     
291 }                                                 
292                                                   
293 static void leon_flush_tlb_page(struct vm_area    
294                                 unsigned long     
295 {                                                 
296         leon_flush_tlb_all();                     
297 }                                                 
298                                                   
299 static void leon_flush_tlb_range(struct vm_are    
300                                  unsigned long    
301                                  unsigned long    
302 {                                                 
303         leon_flush_tlb_all();                     
304 }                                                 
305                                                   
306 static void leon_flush_page_to_ram(unsigned lo    
307 {                                                 
308         leon_flush_cache_all();                   
309 }                                                 
310                                                   
311 static void leon_flush_sig_insns(struct mm_str    
312 {                                                 
313         leon_flush_cache_all();                   
314 }                                                 
315                                                   
316 static void leon_flush_page_for_dma(unsigned l    
317 {                                                 
318         leon_flush_dcache_all();                  
319 }                                                 
320                                                   
321 void __init poke_leonsparc(void)                  
322 {                                                 
323 }                                                 
324                                                   
325 static const struct sparc32_cachetlb_ops leon_    
326         .cache_all      = leon_flush_cache_all    
327         .cache_mm       = leon_flush_cache_mm,    
328         .cache_page     = leon_flush_cache_pag    
329         .cache_range    = leon_flush_cache_ran    
330         .tlb_all        = leon_flush_tlb_all,     
331         .tlb_mm         = leon_flush_tlb_mm,      
332         .tlb_page       = leon_flush_tlb_page,    
333         .tlb_range      = leon_flush_tlb_range    
334         .page_to_ram    = leon_flush_page_to_r    
335         .sig_insns      = leon_flush_sig_insns    
336         .page_for_dma   = leon_flush_page_for_    
337 };                                                
338                                                   
339 void __init init_leon(void)                       
340 {                                                 
341         srmmu_name = "LEON";                      
342         sparc32_cachetlb_ops = &leon_ops;         
343         poke_srmmu = poke_leonsparc;              
344                                                   
345         leon_flush_during_switch = leon_flush_    
346 }                                                 
347                                                   

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php