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

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/head_85xx.S

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/powerpc/kernel/head_85xx.S (Architecture i386) and /arch/sparc/kernel/head_85xx.S (Architecture sparc)


  1 /* SPDX-License-Identifier: GPL-2.0-or-later *    
  2 /*                                                
  3  * Kernel execution entry point code.             
  4  *                                                
  5  *    Copyright (c) 1995-1996 Gary Thomas <gdt@    
  6  *      Initial PowerPC version.                  
  7  *    Copyright (c) 1996 Cort Dougan <cort@cs.n    
  8  *      Rewritten for PReP                        
  9  *    Copyright (c) 1996 Paul Mackerras <paulus    
 10  *      Low-level exception handers, MMU suppo    
 11  *    Copyright (c) 1997 Dan Malek <dmalek@jlc.    
 12  *      PowerPC 8xx modifications.                
 13  *    Copyright (c) 1998-1999 TiVo, Inc.          
 14  *      PowerPC 403GCX modifications.             
 15  *    Copyright (c) 1999 Grant Erickson <grant@    
 16  *      PowerPC 403GCX/405GP modifications.       
 17  *    Copyright 2000 MontaVista Software Inc.     
 18  *      PPC405 modifications                      
 19  *      PowerPC 403GCX/405GP modifications.       
 20  *      Author: MontaVista Software, Inc.         
 21  *              frank_rowand@mvista.com or sou    
 22  *              debbie_chu@mvista.com             
 23  *    Copyright 2002-2004 MontaVista Software,    
 24  *      PowerPC 44x support, Matt Porter <mport    
 25  *    Copyright 2004 Freescale Semiconductor,     
 26  *      PowerPC e500 modifications, Kumar Gala<    
 27  */                                               
 28                                                   
 29 #include <linux/init.h>                           
 30 #include <linux/threads.h>                        
 31 #include <linux/pgtable.h>                        
 32 #include <linux/linkage.h>                        
 33                                                   
 34 #include <asm/processor.h>                        
 35 #include <asm/page.h>                             
 36 #include <asm/mmu.h>                              
 37 #include <asm/cputable.h>                         
 38 #include <asm/thread_info.h>                      
 39 #include <asm/ppc_asm.h>                          
 40 #include <asm/asm-offsets.h>                      
 41 #include <asm/cache.h>                            
 42 #include <asm/ptrace.h>                           
 43 #include <asm/feature-fixups.h>                   
 44 #include "head_booke.h"                           
 45                                                   
 46 /* As with the other PowerPC ports, it is expe    
 47  * execution begins here, the following regist    
 48  * optional, information:                         
 49  *                                                
 50  *   r3 - Board info structure pointer (DRAM,     
 51  *   r4 - Starting address of the init RAM dis    
 52  *   r5 - Ending address of the init RAM disk     
 53  *   r6 - Start of kernel command line string     
 54  *   r7 - End of kernel command line string       
 55  *                                                
 56  */                                               
 57         __HEAD                                    
 58 _GLOBAL(_stext);                                  
 59 _GLOBAL(_start);                                  
 60         /*                                        
 61          * Reserve a word at a fixed location     
 62          * of abatron_pteptrs                     
 63          */                                       
 64         nop                                       
 65                                                   
 66         /* Translate device tree address to ph    
 67         bl      get_phys_addr                     
 68         mr      r30,r3                            
 69         mr      r31,r4                            
 70                                                   
 71         li      r25,0                   /* phy    
 72         li      r24,0                   /* CPU    
 73         li      r23,0                   /* phy    
 74                                                   
 75 #ifdef CONFIG_RELOCATABLE                         
 76         LOAD_REG_ADDR_PIC(r3, _stext)   /* Get    
 77                                                   
 78         /* Translate _stext address to physica    
 79         bl      get_phys_addr                     
 80         mr      r23,r3                            
 81         mr      r25,r4                            
 82                                                   
 83         bcl     20,31,$+4                         
 84 0:      mflr    r8                                
 85         addis   r3,r8,(is_second_reloc - 0b)@h    
 86         lwz     r19,(is_second_reloc - 0b)@l(r    
 87                                                   
 88         /* Check if this is the second relocat    
 89         cmpwi   r19,1                             
 90         bne     1f                                
 91                                                   
 92         /*                                        
 93          * For the second relocation, we alrea    
 94          * from device tree. So we will map PA    
 95          * then the virtual address of start k    
 96          *          PAGE_OFFSET + (kernstart_a    
 97          * Since the offset between kernstart_    
 98          * never be beyond 1G, so we can just     
 99          * for the calculation.                   
100          */                                       
101         lis     r3,PAGE_OFFSET@h                  
102                                                   
103         addis   r4,r8,(kernstart_addr - 0b)@ha    
104         addi    r4,r4,(kernstart_addr - 0b)@l     
105         lwz     r5,4(r4)                          
106                                                   
107         addis   r6,r8,(memstart_addr - 0b)@ha     
108         addi    r6,r6,(memstart_addr - 0b)@l      
109         lwz     r7,4(r6)                          
110                                                   
111         subf    r5,r7,r5                          
112         add     r3,r3,r5                          
113         b       2f                                
114                                                   
115 1:                                                
116         /*                                        
117          * We have the runtime (virtual) addre    
118          * We calculate our shift of offset fr    
119          * We could map the 64M page we belong    
120          * get going from there.                  
121          */                                       
122         lis     r4,KERNELBASE@h                   
123         ori     r4,r4,KERNELBASE@l                
124         rlwinm  r6,r25,0,0x3ffffff                
125         rlwinm  r5,r4,0,0x3ffffff                 
126         subf    r3,r5,r6                          
127         add     r3,r4,r3                          
128                                                   
129 2:      bl      relocate                          
130                                                   
131         /*                                        
132          * For the second relocation, we alrea    
133          * for the kernel space, so skip the c    
134         */                                        
135         cmpwi   r19,1                             
136         beq     set_ivor                          
137 #endif                                            
138                                                   
139 /* We try to not make any assumptions about ho    
140  * setup or used the TLBs.  We invalidate all     
141  * boot loader and load a single entry in TLB1    
142  * first 64M of kernel memory.  Any boot info     
143  * bootloader needs to live in this first 64M.    
144  *                                                
145  * Requirement on bootloader:                     
146  *  - The page we're executing in needs to res    
147  *    have IPROT=1.  If not an invalidate broa    
148  *    evict the entry we're currently executin    
149  *                                                
150  *  r3 = Index of TLB1 were executing in          
151  *  r4 = Current MSR[IS]                          
152  *  r5 = Index of TLB1 temp mapping               
153  *                                                
154  * Later in mapin_ram we will correctly map lo    
155  * if needed                                      
156  */                                               
157                                                   
158 _GLOBAL(__early_start)                            
159         LOAD_REG_ADDR_PIC(r20, kernstart_virt_    
160         lwz     r20,0(r20)                        
161                                                   
162 #define ENTRY_MAPPING_BOOT_SETUP                  
163 #include "85xx_entry_mapping.S"                   
164 #undef ENTRY_MAPPING_BOOT_SETUP                   
165                                                   
166 set_ivor:                                         
167         /* Establish the interrupt vector offs    
168         SET_IVOR(0,  CriticalInput);              
169         SET_IVOR(1,  MachineCheck);               
170         SET_IVOR(2,  DataStorage);                
171         SET_IVOR(3,  InstructionStorage);         
172         SET_IVOR(4,  ExternalInput);              
173         SET_IVOR(5,  Alignment);                  
174         SET_IVOR(6,  Program);                    
175         SET_IVOR(7,  FloatingPointUnavailable)    
176         SET_IVOR(8,  SystemCall);                 
177         SET_IVOR(9,  AuxillaryProcessorUnavail    
178         SET_IVOR(10, Decrementer);                
179         SET_IVOR(11, FixedIntervalTimer);         
180         SET_IVOR(12, WatchdogTimer);              
181         SET_IVOR(13, DataTLBError);               
182         SET_IVOR(14, InstructionTLBError);        
183         SET_IVOR(15, DebugCrit);                  
184                                                   
185         /* Establish the interrupt vector base    
186         lis     r4,interrupt_base@h     /* IVP    
187         mtspr   SPRN_IVPR,r4                      
188                                                   
189         /* Setup the defaults for TLB entries     
190         li      r2,(MAS4_TSIZED(BOOK3E_PAGESZ_    
191         mtspr   SPRN_MAS4, r2                     
192                                                   
193 #if !defined(CONFIG_BDI_SWITCH)                   
194         /*                                        
195          * The Abatron BDI JTAG debugger does     
196          * mucking with the debug registers.      
197          */                                       
198         lis     r2,DBCR0_IDM@h                    
199         mtspr   SPRN_DBCR0,r2                     
200         isync                                     
201         /* clear any residual debug events */     
202         li      r2,-1                             
203         mtspr   SPRN_DBSR,r2                      
204 #endif                                            
205                                                   
206 #ifdef CONFIG_SMP                                 
207         /* Check to see if we're the second pr    
208          * to the secondary_start code if so      
209          */                                       
210         LOAD_REG_ADDR_PIC(r24, boot_cpuid)        
211         lwz     r24, 0(r24)                       
212         cmpwi   r24, -1                           
213         mfspr   r24,SPRN_PIR                      
214         bne     __secondary_start                 
215 #endif                                            
216                                                   
217         /*                                        
218          * This is where the main kernel code     
219          */                                       
220                                                   
221         /* ptr to current */                      
222         lis     r2,init_task@h                    
223         ori     r2,r2,init_task@l                 
224                                                   
225         /* ptr to current thread */               
226         addi    r4,r2,THREAD    /* init task's    
227         mtspr   SPRN_SPRG_THREAD,r4               
228                                                   
229         /* stack */                               
230         lis     r1,init_thread_union@h            
231         ori     r1,r1,init_thread_union@l         
232         li      r0,0                              
233         stwu    r0,THREAD_SIZE-STACK_FRAME_MIN    
234                                                   
235 #ifdef CONFIG_SMP                                 
236         stw     r24, TASK_CPU(r2)                 
237 #endif                                            
238                                                   
239         bl      early_init                        
240                                                   
241 #ifdef CONFIG_KASAN                               
242         bl      kasan_early_init                  
243 #endif                                            
244 #ifdef CONFIG_RELOCATABLE                         
245         mr      r3,r30                            
246         mr      r4,r31                            
247 #ifdef CONFIG_PHYS_64BIT                          
248         mr      r5,r23                            
249         mr      r6,r25                            
250 #else                                             
251         mr      r5,r25                            
252 #endif                                            
253         bl      relocate_init                     
254 #endif                                            
255                                                   
256 #ifdef CONFIG_DYNAMIC_MEMSTART                    
257         lis     r3,kernstart_addr@ha              
258         la      r3,kernstart_addr@l(r3)           
259 #ifdef CONFIG_PHYS_64BIT                          
260         stw     r23,0(r3)                         
261         stw     r25,4(r3)                         
262 #else                                             
263         stw     r25,0(r3)                         
264 #endif                                            
265 #endif                                            
266                                                   
267 /*                                                
268  * Decide what sort of machine this is and ini    
269  */                                               
270         mr      r3,r30                            
271         mr      r4,r31                            
272         bl      machine_init                      
273         bl      MMU_init                          
274                                                   
275         /* Setup PTE pointers for the Abatron     
276         lis     r6, swapper_pg_dir@h              
277         ori     r6, r6, swapper_pg_dir@l          
278         lis     r5, abatron_pteptrs@h             
279         ori     r5, r5, abatron_pteptrs@l         
280         lis     r3, kernstart_virt_addr@ha        
281         lwz     r4, kernstart_virt_addr@l(r3)     
282         stw     r5, 0(r4)       /* Save abatro    
283         stw     r6, 0(r5)                         
284                                                   
285         /* Let's move on */                       
286         lis     r4,start_kernel@h                 
287         ori     r4,r4,start_kernel@l              
288         lis     r3,MSR_KERNEL@h                   
289         ori     r3,r3,MSR_KERNEL@l                
290         mtspr   SPRN_SRR0,r4                      
291         mtspr   SPRN_SRR1,r3                      
292         rfi                     /* change cont    
293                                                   
294 /* Macros to hide the PTE size differences        
295  *                                                
296  * FIND_PTE -- walks the page tables given EA     
297  *   r10 -- free                                  
298  *   r11 -- PGDIR pointer                         
299  *   r12 -- free                                  
300  *   r13 -- EA of fault                           
301  *   label 2: is the bailout case                 
302  *                                                
303  * if we find the pte (fall through):             
304  *   r11 is low pte word                          
305  *   r12 is pointer to the pte                    
306  *   r10 is the pshift from the PGD, if we're     
307  */                                               
308 #ifdef CONFIG_PTE_64BIT                           
309 #ifdef CONFIG_HUGETLB_PAGE                        
310 #define FIND_PTE        \                         
311         rlwinm  r12, r13, 14, 18, 28;   /* Com    
312         add     r12, r11, r12;                    
313         lwz     r11, 4(r12);            /* Get    
314         rlwinm. r10, r11, 32 - _PAGE_PSIZE_SHI    
315         bne     1000f;                  /* Hug    
316         rlwinm. r12, r11, 0, 0, 20;     /* Ext    
317         beq     2f;                     /* Bai    
318         rlwimi  r12, r13, 23, 20, 28;   /* Com    
319         li      r10, 0;                 /* cle    
320         lwz     r11, 4(r12);            /* Get    
321 1000:                                             
322 #else                                             
323 #define FIND_PTE        \                         
324         rlwinm  r12, r13, 14, 18, 28;   /* Com    
325         add     r12, r11, r12;                    
326         lwz     r11, 4(r12);            /* Get    
327         rlwinm. r12, r11, 0, 0, 20;     /* Ext    
328         beq     2f;                     /* Bai    
329         rlwimi  r12, r13, 23, 20, 28;   /* Com    
330         lwz     r11, 4(r12);            /* Get    
331 #endif /* HUGEPAGE */                             
332 #else /* !PTE_64BIT */                            
333 #define FIND_PTE        \                         
334         rlwimi  r11, r13, 12, 20, 29;   /* Cre    
335         lwz     r11, 0(r11);            /* Get    
336         rlwinm. r12, r11, 0, 0, 19;     /* Ext    
337         beq     2f;                     /* Bai    
338         rlwimi  r12, r13, 22, 20, 29;   /* Com    
339         lwz     r11, 0(r12);            /* Get    
340 #endif                                            
341                                                   
342 /*                                                
343  * Interrupt vector entry code                    
344  *                                                
345  * The Book E MMUs are always on so we don't n    
346  * interrupts in real mode as with previous PP    
347  * this case we handle interrupts in the kerne    
348  * space.                                         
349  *                                                
350  * Interrupt vectors are dynamically placed re    
351  * interrupt prefix as determined by the addre    
352  * The interrupt vectors offsets are programme    
353  * for each interrupt vector entry.               
354  *                                                
355  * Interrupt vectors must be aligned on a 16 b    
356  * We align on a 32 byte cache line boundary f    
357  */                                               
358                                                   
359 interrupt_base:                                   
360         /* Critical Input Interrupt */            
361         CRITICAL_EXCEPTION(0x0100, CRITICAL, C    
362                                                   
363         /* Machine Check Interrupt */             
364         MCHECK_EXCEPTION(0x0200, MachineCheck,    
365                                                   
366         /* Data Storage Interrupt */              
367         START_EXCEPTION(DataStorage)              
368         NORMAL_EXCEPTION_PROLOG(0x300, DATA_ST    
369         mfspr   r5,SPRN_ESR             /* Gra    
370         stw     r5,_ESR(r11)                      
371         mfspr   r4,SPRN_DEAR            /* Gra    
372         stw     r4, _DEAR(r11)                    
373         andis.  r10,r5,(ESR_ILK|ESR_DLK)@h        
374         bne     1f                                
375         prepare_transfer_to_handler               
376         bl      do_page_fault                     
377         b       interrupt_return                  
378 1:                                                
379         prepare_transfer_to_handler               
380         bl      CacheLockingException             
381         b       interrupt_return                  
382                                                   
383         /* Instruction Storage Interrupt */       
384         INSTRUCTION_STORAGE_EXCEPTION             
385                                                   
386         /* External Input Interrupt */            
387         EXCEPTION(0x0500, EXTERNAL, ExternalIn    
388                                                   
389         /* Alignment Interrupt */                 
390         ALIGNMENT_EXCEPTION                       
391                                                   
392         /* Program Interrupt */                   
393         PROGRAM_EXCEPTION                         
394                                                   
395         /* Floating Point Unavailable Interrup    
396 #ifdef CONFIG_PPC_FPU                             
397         FP_UNAVAILABLE_EXCEPTION                  
398 #else                                             
399         EXCEPTION(0x0800, FP_UNAVAIL, Floating    
400 #endif                                            
401                                                   
402         /* System Call Interrupt */               
403         START_EXCEPTION(SystemCall)               
404         SYSCALL_ENTRY   0xc00 BOOKE_INTERRUPT_    
405                                                   
406         /* Auxiliary Processor Unavailable Int    
407         EXCEPTION(0x2900, AP_UNAVAIL, Auxillar    
408                                                   
409         /* Decrementer Interrupt */               
410         DECREMENTER_EXCEPTION                     
411                                                   
412         /* Fixed Internal Timer Interrupt */      
413         /* TODO: Add FIT support */               
414         EXCEPTION(0x3100, FIT, FixedIntervalTi    
415                                                   
416         /* Watchdog Timer Interrupt */            
417 #ifdef CONFIG_BOOKE_WDT                           
418         CRITICAL_EXCEPTION(0x3200, WATCHDOG, W    
419 #else                                             
420         CRITICAL_EXCEPTION(0x3200, WATCHDOG, W    
421 #endif                                            
422                                                   
423         /* Data TLB Error Interrupt */            
424         START_EXCEPTION(DataTLBError)             
425         mtspr   SPRN_SPRG_WSCRATCH0, r10 /* Sa    
426         mfspr   r10, SPRN_SPRG_THREAD             
427         stw     r11, THREAD_NORMSAVE(0)(r10)      
428 #ifdef CONFIG_KVM_BOOKE_HV                        
429 BEGIN_FTR_SECTION                                 
430         mfspr   r11, SPRN_SRR1                    
431 END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)             
432 #endif                                            
433         stw     r12, THREAD_NORMSAVE(1)(r10)      
434         stw     r13, THREAD_NORMSAVE(2)(r10)      
435         mfcr    r13                               
436         stw     r13, THREAD_NORMSAVE(3)(r10)      
437         DO_KVM  BOOKE_INTERRUPT_DTLB_MISS SPRN    
438 START_BTB_FLUSH_SECTION                           
439         mfspr r11, SPRN_SRR1                      
440         andi. r10,r11,MSR_PR                      
441         beq 1f                                    
442         BTB_FLUSH(r10)                            
443 1:                                                
444 END_BTB_FLUSH_SECTION                             
445         mfspr   r13, SPRN_DEAR          /* Get    
446                                                   
447         /* If we are faulting a kernel address    
448          * kernel page tables.                    
449          */                                       
450         lis     r11, PAGE_OFFSET@h                
451         cmplw   5, r13, r11                       
452         blt     5, 3f                             
453         lis     r11, swapper_pg_dir@h             
454         ori     r11, r11, swapper_pg_dir@l        
455                                                   
456         mfspr   r12,SPRN_MAS1           /* Set    
457         rlwinm  r12,r12,0,16,1                    
458         mtspr   SPRN_MAS1,r12                     
459                                                   
460         b       4f                                
461                                                   
462         /* Get the PGD for the current thread     
463 3:                                                
464         mfspr   r11,SPRN_SPRG_THREAD              
465         lwz     r11,PGDIR(r11)                    
466                                                   
467 #ifdef CONFIG_PPC_KUAP                            
468         mfspr   r12, SPRN_MAS1                    
469         rlwinm. r12,r12,0,0x3fff0000              
470         beq     2f                      /* KUA    
471 #endif                                            
472                                                   
473 4:                                                
474         FIND_PTE                                  
475                                                   
476 #ifdef CONFIG_PTE_64BIT                           
477         li      r13,_PAGE_PRESENT|_PAGE_BAP_SR    
478         oris    r13,r13,_PAGE_ACCESSED@h          
479 #else                                             
480         li      r13,_PAGE_PRESENT|_PAGE_READ|_    
481 #endif                                            
482         andc.   r13,r13,r11             /* Che    
483                                                   
484 #ifdef CONFIG_PTE_64BIT                           
485 #ifdef CONFIG_SMP                                 
486         subf    r13,r11,r12             /* cre    
487         lwzx    r13,r11,r13             /* Get    
488 #else                                             
489         lwz     r13,0(r12)              /* Get    
490 #endif                                            
491 #endif                                            
492                                                   
493         bne     2f                      /* Bai    
494                                                   
495         /* Jump to common tlb load */             
496         b       finish_tlb_load                   
497 2:                                                
498         /* The bailout.  Restore registers to     
499          * and call the heavyweights to help u    
500          */                                       
501         mfspr   r10, SPRN_SPRG_THREAD             
502         lwz     r11, THREAD_NORMSAVE(3)(r10)      
503         mtcr    r11                               
504         lwz     r13, THREAD_NORMSAVE(2)(r10)      
505         lwz     r12, THREAD_NORMSAVE(1)(r10)      
506         lwz     r11, THREAD_NORMSAVE(0)(r10)      
507         mfspr   r10, SPRN_SPRG_RSCRATCH0          
508         b       DataStorage                       
509                                                   
510         /* Instruction TLB Error Interrupt */     
511         /*                                        
512          * Nearly the same as above, except we    
513          * information from different register    
514          * to a different point.                  
515          */                                       
516         START_EXCEPTION(InstructionTLBError)      
517         mtspr   SPRN_SPRG_WSCRATCH0, r10 /* Sa    
518         mfspr   r10, SPRN_SPRG_THREAD             
519         stw     r11, THREAD_NORMSAVE(0)(r10)      
520 #ifdef CONFIG_KVM_BOOKE_HV                        
521 BEGIN_FTR_SECTION                                 
522         mfspr   r11, SPRN_SRR1                    
523 END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)             
524 #endif                                            
525         stw     r12, THREAD_NORMSAVE(1)(r10)      
526         stw     r13, THREAD_NORMSAVE(2)(r10)      
527         mfcr    r13                               
528         stw     r13, THREAD_NORMSAVE(3)(r10)      
529         DO_KVM  BOOKE_INTERRUPT_ITLB_MISS SPRN    
530 START_BTB_FLUSH_SECTION                           
531         mfspr r11, SPRN_SRR1                      
532         andi. r10,r11,MSR_PR                      
533         beq 1f                                    
534         BTB_FLUSH(r10)                            
535 1:                                                
536 END_BTB_FLUSH_SECTION                             
537                                                   
538         mfspr   r13, SPRN_SRR0          /* Get    
539                                                   
540         /* If we are faulting a kernel address    
541          * kernel page tables.                    
542          */                                       
543         lis     r11, PAGE_OFFSET@h                
544         cmplw   5, r13, r11                       
545         blt     5, 3f                             
546         lis     r11, swapper_pg_dir@h             
547         ori     r11, r11, swapper_pg_dir@l        
548                                                   
549         mfspr   r12,SPRN_MAS1           /* Set    
550         rlwinm  r12,r12,0,16,1                    
551         mtspr   SPRN_MAS1,r12                     
552                                                   
553         FIND_PTE                                  
554         /* Make up the required permissions fo    
555 #ifdef CONFIG_PTE_64BIT                           
556         li      r13,_PAGE_PRESENT | _PAGE_BAP_    
557         oris    r13,r13,_PAGE_ACCESSED@h          
558 #else                                             
559         li      r13,_PAGE_PRESENT | _PAGE_ACCE    
560 #endif                                            
561         b       4f                                
562                                                   
563         /* Get the PGD for the current thread     
564 3:                                                
565         mfspr   r11,SPRN_SPRG_THREAD              
566         lwz     r11,PGDIR(r11)                    
567                                                   
568 #ifdef CONFIG_PPC_KUAP                            
569         mfspr   r12, SPRN_MAS1                    
570         rlwinm. r12,r12,0,0x3fff0000              
571         beq     2f                      /* KUA    
572 #endif                                            
573                                                   
574         FIND_PTE                                  
575         /* Make up the required permissions fo    
576 #ifdef CONFIG_PTE_64BIT                           
577         li      r13,_PAGE_PRESENT | _PAGE_BAP_    
578         oris    r13,r13,_PAGE_ACCESSED@h          
579 #else                                             
580         li      r13,_PAGE_PRESENT | _PAGE_ACCE    
581 #endif                                            
582                                                   
583 4:                                                
584         andc.   r13,r13,r11             /* Che    
585                                                   
586 #ifdef CONFIG_PTE_64BIT                           
587 #ifdef CONFIG_SMP                                 
588         subf    r13,r11,r12             /* cre    
589         lwzx    r13,r11,r13             /* Get    
590 #else                                             
591         lwz     r13,0(r12)              /* Get    
592 #endif                                            
593 #endif                                            
594                                                   
595         bne     2f                      /* Bai    
596                                                   
597         /* Jump to common TLB load point */       
598         b       finish_tlb_load                   
599                                                   
600 2:                                                
601         /* The bailout.  Restore registers to     
602          * and call the heavyweights to help u    
603          */                                       
604         mfspr   r10, SPRN_SPRG_THREAD             
605         lwz     r11, THREAD_NORMSAVE(3)(r10)      
606         mtcr    r11                               
607         lwz     r13, THREAD_NORMSAVE(2)(r10)      
608         lwz     r12, THREAD_NORMSAVE(1)(r10)      
609         lwz     r11, THREAD_NORMSAVE(0)(r10)      
610         mfspr   r10, SPRN_SPRG_RSCRATCH0          
611         b       InstructionStorage                
612                                                   
613 /* Define SPE handlers for e500v2 */              
614 #ifdef CONFIG_SPE                                 
615         /* SPE Unavailable */                     
616         START_EXCEPTION(SPEUnavailable)           
617         NORMAL_EXCEPTION_PROLOG(0x2010, SPE_UN    
618         beq     1f                                
619         bl      load_up_spe                       
620         b       fast_exception_return             
621 1:      prepare_transfer_to_handler               
622         bl      KernelSPE                         
623         b       interrupt_return                  
624 #elif defined(CONFIG_SPE_POSSIBLE)                
625         EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnav    
626 #endif /* CONFIG_SPE_POSSIBLE */                  
627                                                   
628         /* SPE Floating Point Data */             
629 #ifdef CONFIG_SPE                                 
630         START_EXCEPTION(SPEFloatingPointData)     
631         NORMAL_EXCEPTION_PROLOG(0x2030, SPE_FP    
632         prepare_transfer_to_handler               
633         bl      SPEFloatingPointException         
634         REST_NVGPRS(r1)                           
635         b       interrupt_return                  
636                                                   
637         /* SPE Floating Point Round */            
638         START_EXCEPTION(SPEFloatingPointRound)    
639         NORMAL_EXCEPTION_PROLOG(0x2050, SPE_FP    
640         prepare_transfer_to_handler               
641         bl      SPEFloatingPointRoundException    
642         REST_NVGPRS(r1)                           
643         b       interrupt_return                  
644 #elif defined(CONFIG_SPE_POSSIBLE)                
645         EXCEPTION(0x2040, SPE_FP_DATA, SPEFloa    
646         EXCEPTION(0x2050, SPE_FP_ROUND, SPEFlo    
647 #endif /* CONFIG_SPE_POSSIBLE */                  
648                                                   
649                                                   
650         /* Performance Monitor */                 
651         EXCEPTION(0x2060, PERFORMANCE_MONITOR,    
652                   performance_monitor_exceptio    
653                                                   
654         EXCEPTION(0x2070, DOORBELL, Doorbell,     
655                                                   
656         CRITICAL_EXCEPTION(0x2080, DOORBELL_CR    
657                            CriticalDoorbell, u    
658                                                   
659         /* Debug Interrupt */                     
660         DEBUG_DEBUG_EXCEPTION                     
661         DEBUG_CRIT_EXCEPTION                      
662                                                   
663         GUEST_DOORBELL_EXCEPTION                  
664                                                   
665         CRITICAL_EXCEPTION(0, GUEST_DBELL_CRIT    
666                            unknown_exception)     
667                                                   
668         /* Hypercall */                           
669         EXCEPTION(0, HV_SYSCALL, Hypercall, un    
670                                                   
671         /* Embedded Hypervisor Privilege */       
672         EXCEPTION(0, HV_PRIV, Ehvpriv, unknown    
673                                                   
674 interrupt_end:                                    
675                                                   
676 /*                                                
677  * Local functions                                
678  */                                               
679                                                   
680 /*                                                
681  * Both the instruction and data TLB miss get     
682  * point to load the TLB.                         
683  *      r10 - tsize encoding (if HUGETLB_PAGE)    
684  *      r11 - TLB (info from Linux PTE)           
685  *      r12 - available to use                    
686  *      r13 - upper bits of PTE (if PTE_64BIT)    
687  *      CR5 - results of addr >= PAGE_OFFSET      
688  *      MAS0, MAS1 - loaded with proper value     
689  *      MAS2, MAS3 - will need additional info    
690  *      Upon exit, we reload everything and RF    
691  */                                               
692 finish_tlb_load:                                  
693 #ifdef CONFIG_HUGETLB_PAGE                        
694         cmpwi   6, r10, 0                         
695         beq     6, finish_tlb_load_cont           
696                                                   
697         /* Alas, we need more scratch register    
698         mfspr   r12, SPRN_SPRG_THREAD             
699         stw     r14, THREAD_NORMSAVE(4)(r12)      
700         stw     r15, THREAD_NORMSAVE(5)(r12)      
701         stw     r16, THREAD_NORMSAVE(6)(r12)      
702         stw     r17, THREAD_NORMSAVE(7)(r12)      
703                                                   
704         /* Get the next_tlbcam_idx percpu var     
705 #ifdef CONFIG_SMP                                 
706         lwz     r15, TASK_CPU-THREAD(r12)         
707         lis     r14, __per_cpu_offset@h           
708         ori     r14, r14, __per_cpu_offset@l      
709         rlwinm  r15, r15, 2, 0, 29                
710         lwzx    r16, r14, r15                     
711 #else                                             
712         li      r16, 0                            
713 #endif                                            
714         lis     r17, next_tlbcam_idx@h            
715         ori     r17, r17, next_tlbcam_idx@l       
716         add     r17, r17, r16                     
717         lwz     r15, 0(r17)                       
718                                                   
719         lis     r14, MAS0_TLBSEL(1)@h             
720         rlwimi  r14, r15, 16, 4, 15               
721         mtspr   SPRN_MAS0, r14                    
722                                                   
723         /* Extract TLB1CFG(NENTRY) */             
724         mfspr   r16, SPRN_TLB1CFG                 
725         andi.   r16, r16, 0xfff                   
726                                                   
727         /* Update next_tlbcam_idx, wrapping wh    
728         addi    r15, r15, 1                       
729         cmpw    r15, r16                          
730         blt     100f                              
731         lis     r14, tlbcam_index@h               
732         ori     r14, r14, tlbcam_index@l          
733         lwz     r15, 0(r14)                       
734 100:    stw     r15, 0(r17)                       
735                                                   
736         mfspr   r16, SPRN_MAS1                    
737         rlwimi  r16, r10, MAS1_TSIZE_SHIFT, MA    
738         mtspr   SPRN_MAS1, r16                    
739                                                   
740         /* copy the pshift for use later */       
741         addi    r14, r10, _PAGE_PSIZE_SHIFT_OF    
742                                                   
743         /* fall through */                        
744                                                   
745 #endif /* CONFIG_HUGETLB_PAGE */                  
746                                                   
747         /*                                        
748          * We set execute, because we don't ha    
749          * properly set this at the page level    
750          * Many of these bits are software onl    
751          * here we (properly should) assume ha    
752          */                                       
753 finish_tlb_load_cont:                             
754 #ifdef CONFIG_PTE_64BIT                           
755         rlwinm  r12, r11, 32-2, 26, 31  /* Mov    
756         andi.   r10, r11, _PAGE_DIRTY             
757         bne     1f                                
758         li      r10, MAS3_SW | MAS3_UW            
759         andc    r12, r12, r10                     
760 1:      rlwimi  r12, r13, 20, 0, 11     /* gra    
761         rlwimi  r12, r11, 20, 12, 19    /* gra    
762 2:      mtspr   SPRN_MAS3, r12                    
763 BEGIN_MMU_FTR_SECTION                             
764         srwi    r10, r13, 12            /* gra    
765         mtspr   SPRN_MAS7, r10                    
766 END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)       
767 #else                                             
768         li      r10, (_PAGE_EXEC | _PAGE_READ)    
769         mr      r13, r11                          
770         rlwimi  r10, r11, 31, 29, 29    /* ext    
771         and     r12, r11, r10                     
772         mcrf    cr0, cr5                /* Tes    
773         slwi    r10, r12, 1                       
774         or      r10, r10, r12                     
775         rlwinm  r10, r10, 0, ~_PAGE_EXEC          
776         isellt  r12, r10, r12                     
777         rlwimi  r13, r12, 0, 20, 31     /* Get    
778         mtspr   SPRN_MAS3, r13                    
779 #endif                                            
780                                                   
781         mfspr   r12, SPRN_MAS2                    
782 #ifdef CONFIG_PTE_64BIT                           
783         rlwimi  r12, r11, 32-19, 27, 31 /* ext    
784 #else                                             
785         rlwimi  r12, r11, 26, 27, 31    /* ext    
786 #endif                                            
787 #ifdef CONFIG_HUGETLB_PAGE                        
788         beq     6, 3f                   /* don    
789         li      r13, 1                            
790         slw     r13, r13, r14                     
791         subi    r13, r13, 1                       
792         rlwinm  r13, r13, 0, 0, 19      /* bot    
793         andc    r12, r12, r13           /* mas    
794 #endif                                            
795 3:      mtspr   SPRN_MAS2, r12                    
796                                                   
797 tlb_write_entry:                                  
798         tlbwe                                     
799                                                   
800         /* Done...restore registers and get ou    
801         mfspr   r10, SPRN_SPRG_THREAD             
802 #ifdef CONFIG_HUGETLB_PAGE                        
803         beq     6, 8f /* skip restore for 4k p    
804         lwz     r14, THREAD_NORMSAVE(4)(r10)      
805         lwz     r15, THREAD_NORMSAVE(5)(r10)      
806         lwz     r16, THREAD_NORMSAVE(6)(r10)      
807         lwz     r17, THREAD_NORMSAVE(7)(r10)      
808 #endif                                            
809 8:      lwz     r11, THREAD_NORMSAVE(3)(r10)      
810         mtcr    r11                               
811         lwz     r13, THREAD_NORMSAVE(2)(r10)      
812         lwz     r12, THREAD_NORMSAVE(1)(r10)      
813         lwz     r11, THREAD_NORMSAVE(0)(r10)      
814         mfspr   r10, SPRN_SPRG_RSCRATCH0          
815         rfi                                       
816                                                   
817 #ifdef CONFIG_SPE                                 
818 /* Note that the SPE support is closely modele    
819  * support.  Changes to one are likely to be a    
820  * other!  */                                     
821 _GLOBAL(load_up_spe)                              
822 /*                                                
823  * Disable SPE for the task which had SPE prev    
824  * and save its SPE registers in its thread_st    
825  * Enables SPE for use in the kernel on return    
826  * On SMP we know the SPE units are free, sinc    
827  * switch.  -- Kumar                              
828  */                                               
829         mfmsr   r5                                
830         oris    r5,r5,MSR_SPE@h                   
831         mtmsr   r5                      /* ena    
832         isync                                     
833         /* enable use of SPE after return */      
834         oris    r9,r9,MSR_SPE@h                   
835         mfspr   r5,SPRN_SPRG_THREAD     /* cur    
836         li      r4,1                              
837         li      r10,THREAD_ACC                    
838         stw     r4,THREAD_USED_SPE(r5)            
839         evlddx  evr4,r10,r5                       
840         evmra   evr4,evr4                         
841         REST_32EVRS(0,r10,r5,THREAD_EVR0)         
842         blr                                       
843                                                   
844 /*                                                
845  * SPE unavailable trap from kernel - print a     
846  * the task use SPE in the kernel until it ret    
847  */                                               
848 SYM_FUNC_START_LOCAL(KernelSPE)                   
849         lwz     r3,_MSR(r1)                       
850         oris    r3,r3,MSR_SPE@h                   
851         stw     r3,_MSR(r1)     /* enable use     
852 #ifdef CONFIG_PRINTK                              
853         lis     r3,87f@h                          
854         ori     r3,r3,87f@l                       
855         mr      r4,r2           /* current */     
856         lwz     r5,_NIP(r1)                       
857         bl      _printk                           
858 #endif                                            
859         b       interrupt_return                  
860 #ifdef CONFIG_PRINTK                              
861 87:     .string "SPE used in kernel  (task=%p,    
862 #endif                                            
863         .align  4,0                               
864                                                   
865 SYM_FUNC_END(KernelSPE)                           
866 #endif /* CONFIG_SPE */                           
867                                                   
868 /*                                                
869  * Translate the effec addr in r3 to phys addr    
870  * into r3(higher 32bit) and r4(lower 32bit)      
871  */                                               
872 SYM_FUNC_START_LOCAL(get_phys_addr)               
873         mfmsr   r8                                
874         mfspr   r9,SPRN_PID                       
875         rlwinm  r9,r9,16,0x3fff0000     /* tur    
876         rlwimi  r9,r8,28,0x00000001     /* tur    
877         mtspr   SPRN_MAS6,r9                      
878                                                   
879         tlbsx   0,r3                    /* mus    
880                                                   
881         mfspr   r8,SPRN_MAS1                      
882         mfspr   r12,SPRN_MAS3                     
883         rlwinm  r9,r8,25,0x1f           /* r9     
884         li      r10,1024                          
885         slw     r10,r10,r9              /* r10    
886         addi    r10,r10,-1                        
887         and     r11,r3,r10              /* r11    
888         andc    r4,r12,r10              /* r4     
889         or      r4,r4,r11               /* r4     
890 #ifdef CONFIG_PHYS_64BIT                          
891         mfspr   r3,SPRN_MAS7                      
892 #endif                                            
893         blr                                       
894 SYM_FUNC_END(get_phys_addr)                       
895                                                   
896 /*                                                
897  * Global functions                               
898  */                                               
899                                                   
900 #ifdef CONFIG_PPC_E500                            
901 #ifndef CONFIG_PPC_E500MC                         
902 /* Adjust or setup IVORs for e500v1/v2 */         
903 _GLOBAL(__setup_e500_ivors)                       
904         li      r3,DebugCrit@l                    
905         mtspr   SPRN_IVOR15,r3                    
906         li      r3,SPEUnavailable@l               
907         mtspr   SPRN_IVOR32,r3                    
908         li      r3,SPEFloatingPointData@l         
909         mtspr   SPRN_IVOR33,r3                    
910         li      r3,SPEFloatingPointRound@l        
911         mtspr   SPRN_IVOR34,r3                    
912         li      r3,PerformanceMonitor@l           
913         mtspr   SPRN_IVOR35,r3                    
914         sync                                      
915         blr                                       
916 #else                                             
917 /* Adjust or setup IVORs for e500mc */            
918 _GLOBAL(__setup_e500mc_ivors)                     
919         li      r3,DebugDebug@l                   
920         mtspr   SPRN_IVOR15,r3                    
921         li      r3,PerformanceMonitor@l           
922         mtspr   SPRN_IVOR35,r3                    
923         li      r3,Doorbell@l                     
924         mtspr   SPRN_IVOR36,r3                    
925         li      r3,CriticalDoorbell@l             
926         mtspr   SPRN_IVOR37,r3                    
927         sync                                      
928         blr                                       
929                                                   
930 /* setup ehv ivors for */                         
931 _GLOBAL(__setup_ehv_ivors)                        
932         li      r3,GuestDoorbell@l                
933         mtspr   SPRN_IVOR38,r3                    
934         li      r3,CriticalGuestDoorbell@l        
935         mtspr   SPRN_IVOR39,r3                    
936         li      r3,Hypercall@l                    
937         mtspr   SPRN_IVOR40,r3                    
938         li      r3,Ehvpriv@l                      
939         mtspr   SPRN_IVOR41,r3                    
940         sync                                      
941         blr                                       
942 #endif /* CONFIG_PPC_E500MC */                    
943 #endif /* CONFIG_PPC_E500 */                      
944                                                   
945 #ifdef CONFIG_SPE                                 
946 /*                                                
947  * extern void __giveup_spe(struct task_struct    
948  *                                                
949  */                                               
950 _GLOBAL(__giveup_spe)                             
951         addi    r3,r3,THREAD            /* wan    
952         lwz     r5,PT_REGS(r3)                    
953         cmpi    0,r5,0                            
954         SAVE_32EVRS(0, r4, r3, THREAD_EVR0)       
955         evxor   evr6, evr6, evr6        /* cle    
956         evmwumiaa evr6, evr6, evr6      /* evr    
957         li      r4,THREAD_ACC                     
958         evstddx evr6, r4, r3            /* sav    
959         beq     1f                                
960         lwz     r4,_MSR-STACK_INT_FRAME_REGS(r    
961         lis     r3,MSR_SPE@h                      
962         andc    r4,r4,r3                /* dis    
963         stw     r4,_MSR-STACK_INT_FRAME_REGS(r    
964 1:                                                
965         blr                                       
966 #endif /* CONFIG_SPE */                           
967                                                   
968 /*                                                
969  * extern void abort(void)                        
970  *                                                
971  * At present, this routine just applies a sys    
972  */                                               
973 _GLOBAL(abort)                                    
974         li      r13,0                             
975         mtspr   SPRN_DBCR0,r13          /* dis    
976         isync                                     
977         mfmsr   r13                               
978         ori     r13,r13,MSR_DE@l        /* Ena    
979         mtmsr   r13                               
980         isync                                     
981         mfspr   r13,SPRN_DBCR0                    
982         lis     r13,(DBCR0_IDM|DBCR0_RST_CHIP)    
983         mtspr   SPRN_DBCR0,r13                    
984         isync                                     
985                                                   
986 #ifdef CONFIG_SMP                                 
987 /* When we get here, r24 needs to hold the CPU    
988         .globl __secondary_start                  
989 __secondary_start:                                
990         LOAD_REG_ADDR_PIC(r3, tlbcam_index)       
991         lwz     r3,0(r3)                          
992         mtctr   r3                                
993         li      r26,0           /* r26 safe? *    
994                                                   
995         bl      switch_to_as1                     
996         mr      r27,r3          /* tlb entry *    
997         /* Load each CAM entry */                 
998 1:      mr      r3,r26                            
999         bl      loadcam_entry                     
1000         addi    r26,r26,1                        
1001         bdnz    1b                               
1002         mr      r3,r27          /* tlb entry     
1003         LOAD_REG_ADDR_PIC(r4, memstart_addr)     
1004         lwz     r4,0(r4)                         
1005         mr      r5,r25          /* phys kerne    
1006         rlwinm  r5,r5,0,~0x3ffffff      /* al    
1007         subf    r4,r5,r4        /* memstart_a    
1008         lis     r7,KERNELBASE@h                  
1009         ori     r7,r7,KERNELBASE@l               
1010         cmpw    r20,r7          /* if kernsta    
1011         beq     2f                               
1012         li      r4,0                             
1013 2:      li      r5,0            /* no device     
1014         li      r6,0            /* not boot c    
1015         bl      restore_to_as0                   
1016                                                  
1017                                                  
1018         lis     r3,__secondary_hold_acknowled    
1019         ori     r3,r3,__secondary_hold_acknow    
1020         stw     r24,0(r3)                        
1021                                                  
1022         li      r3,0                             
1023         mr      r4,r24          /* Why? */       
1024         bl      call_setup_cpu                   
1025                                                  
1026         /* get current's stack and current */    
1027         lis     r2,secondary_current@ha          
1028         lwz     r2,secondary_current@l(r2)       
1029         lwz     r1,TASK_STACK(r2)                
1030                                                  
1031         /* stack */                              
1032         addi    r1,r1,THREAD_SIZE-STACK_FRAME    
1033         li      r0,0                             
1034         stw     r0,0(r1)                         
1035                                                  
1036         /* ptr to current thread */              
1037         addi    r4,r2,THREAD    /* address of    
1038         mtspr   SPRN_SPRG_THREAD,r4              
1039                                                  
1040         /* Setup the defaults for TLB entries    
1041         li      r4,(MAS4_TSIZED(BOOK3E_PAGESZ    
1042         mtspr   SPRN_MAS4,r4                     
1043                                                  
1044         /* Jump to start_secondary */            
1045         lis     r4,MSR_KERNEL@h                  
1046         ori     r4,r4,MSR_KERNEL@l               
1047         lis     r3,start_secondary@h             
1048         ori     r3,r3,start_secondary@l          
1049         mtspr   SPRN_SRR0,r3                     
1050         mtspr   SPRN_SRR1,r4                     
1051         sync                                     
1052         rfi                                      
1053         sync                                     
1054                                                  
1055         .globl __secondary_hold_acknowledge      
1056 __secondary_hold_acknowledge:                    
1057         .long   -1                               
1058 #endif                                           
1059                                                  
1060 /*                                               
1061  * Create a 64M tlb by address and entry         
1062  * r3 - entry                                    
1063  * r4 - virtual address                          
1064  * r5/r6 - physical address                      
1065  */                                              
1066 _GLOBAL(create_kaslr_tlb_entry)                  
1067         lis     r7,0x1000               /* Se    
1068         rlwimi  r7,r3,16,4,15           /* Se    
1069         mtspr   SPRN_MAS0,r7            /* Wr    
1070                                                  
1071         lis     r3,(MAS1_VALID|MAS1_IPROT)@h     
1072         ori     r3,r3,(MAS1_TSIZE(BOOK3E_PAGE    
1073         mtspr   SPRN_MAS1,r3            /* Wr    
1074                                                  
1075         lis     r3,MAS2_EPN_MASK(BOOK3E_PAGES    
1076         ori     r3,r3,MAS2_EPN_MASK(BOOK3E_PA    
1077         and     r3,r3,r4                         
1078         ori     r3,r3,MAS2_M_IF_NEEDED@l         
1079         mtspr   SPRN_MAS2,r3            /* Wr    
1080                                                  
1081 #ifdef CONFIG_PHYS_64BIT                         
1082         ori     r8,r6,(MAS3_SW|MAS3_SR|MAS3_S    
1083         mtspr   SPRN_MAS3,r8            /* Wr    
1084         mtspr   SPRN_MAS7,r5                     
1085 #else                                            
1086         ori     r8,r5,(MAS3_SW|MAS3_SR|MAS3_S    
1087         mtspr   SPRN_MAS3,r8            /* Wr    
1088 #endif                                           
1089                                                  
1090         tlbwe                           /* Wr    
1091         isync                                    
1092         sync                                     
1093         blr                                      
1094                                                  
1095 /*                                               
1096  * Return to the start of the relocated kerne    
1097  * r3 - virtual address of fdt                   
1098  * r4 - entry of the kernel                      
1099  */                                              
1100 _GLOBAL(reloc_kernel_entry)                      
1101         mfmsr   r7                               
1102         rlwinm  r7, r7, 0, ~(MSR_IS | MSR_DS)    
1103                                                  
1104         mtspr   SPRN_SRR0,r4                     
1105         mtspr   SPRN_SRR1,r7                     
1106         rfi                                      
1107                                                  
1108 /*                                               
1109  * Create a tlb entry with the same effective    
1110  * the tlb entry used by the current running     
1111  * Then switch to the address space 1. It wil    
1112  * the ESEL of the new created tlb.              
1113  */                                              
1114 _GLOBAL(switch_to_as1)                           
1115         mflr    r5                               
1116                                                  
1117         /* Find a entry not used */              
1118         mfspr   r3,SPRN_TLB1CFG                  
1119         andi.   r3,r3,0xfff                      
1120         mfspr   r4,SPRN_PID                      
1121         rlwinm  r4,r4,16,0x3fff0000     /* tu    
1122         mtspr   SPRN_MAS6,r4                     
1123 1:      lis     r4,0x1000               /* Se    
1124         addi    r3,r3,-1                         
1125         rlwimi  r4,r3,16,4,15           /* Se    
1126         mtspr   SPRN_MAS0,r4                     
1127         tlbre                                    
1128         mfspr   r4,SPRN_MAS1                     
1129         andis.  r4,r4,MAS1_VALID@h               
1130         bne     1b                               
1131                                                  
1132         /* Get the tlb entry used by the curr    
1133         bcl     20,31,$+4                        
1134 0:      mflr    r4                               
1135         tlbsx   0,r4                             
1136                                                  
1137         mfspr   r4,SPRN_MAS1                     
1138         ori     r4,r4,MAS1_TS           /* Se    
1139         mtspr   SPRN_MAS1,r4                     
1140                                                  
1141         mfspr   r4,SPRN_MAS0                     
1142         rlwinm  r4,r4,0,~MAS0_ESEL_MASK          
1143         rlwimi  r4,r3,16,4,15           /* Se    
1144         mtspr   SPRN_MAS0,r4                     
1145         tlbwe                                    
1146         isync                                    
1147         sync                                     
1148                                                  
1149         mfmsr   r4                               
1150         ori     r4,r4,MSR_IS | MSR_DS            
1151         mtspr   SPRN_SRR0,r5                     
1152         mtspr   SPRN_SRR1,r4                     
1153         sync                                     
1154         rfi                                      
1155                                                  
1156 /*                                               
1157  * Restore to the address space 0 and also in    
1158  * by switch_to_as1.                             
1159  * r3 - the tlb entry which should be invalid    
1160  * r4 - __pa(PAGE_OFFSET in AS1) - __pa(PAGE_    
1161  * r5 - device tree virtual address. If r4 is    
1162  * r6 - boot cpu                                 
1163 */                                               
1164 _GLOBAL(restore_to_as0)                          
1165         mflr    r0                               
1166                                                  
1167         bcl     20,31,$+4                        
1168 0:      mflr    r9                               
1169         addi    r9,r9,1f - 0b                    
1170                                                  
1171         /*                                       
1172          * We may map the PAGE_OFFSET in AS0     
1173          * so we need calculate the right jum    
1174          * on the offset passed by r4.           
1175          */                                      
1176         add     r9,r9,r4                         
1177         add     r5,r5,r4                         
1178         add     r0,r0,r4                         
1179                                                  
1180 2:      mfmsr   r7                               
1181         li      r8,(MSR_IS | MSR_DS)             
1182         andc    r7,r7,r8                         
1183                                                  
1184         mtspr   SPRN_SRR0,r9                     
1185         mtspr   SPRN_SRR1,r7                     
1186         sync                                     
1187         rfi                                      
1188                                                  
1189         /* Invalidate the temporary tlb entry    
1190 1:      lis     r9,0x1000               /* Se    
1191         rlwimi  r9,r3,16,4,15           /* Se    
1192         mtspr   SPRN_MAS0,r9                     
1193         tlbre                                    
1194         mfspr   r9,SPRN_MAS1                     
1195         rlwinm  r9,r9,0,2,31            /* Cl    
1196         mtspr   SPRN_MAS1,r9                     
1197         tlbwe                                    
1198         isync                                    
1199                                                  
1200         cmpwi   r4,0                             
1201         cmpwi   cr1,r6,0                         
1202         cror    eq,4*cr1+eq,eq                   
1203         bne     3f                      /* of    
1204         mtlr    r0                               
1205         blr                                      
1206                                                  
1207         /*                                       
1208          * The PAGE_OFFSET will map to a diff    
1209          * jump to _start to do another reloc    
1210         */                                       
1211 3:      mr      r3,r5                            
1212         bl      _start                           
                                                      

~ [ 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