fix to allow usb modules to compile
[linux-2.4.21-pre4.git] / arch / ppc / kernel / iSeries_head.S
1 /*
2  *  arch/ppc/kernel/iSeries_head.S
3  *
4  *  Adapted from arch/ppc/kernel/head.S
5  *
6  *  PowerPC version 
7  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8  *
9  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
10  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
11  *  Adapted for Power Macintosh by Paul Mackerras.
12  *  Low-level exception handlers and MMU support
13  *  rewritten by Paul Mackerras.
14  *    Copyright (C) 1996 Paul Mackerras.
15  *  Adapted for iSeries by Mike Corrigan
16  *  Updated by Dave Boutcher
17  *  
18  *  This file contains the low-level support and setup for the
19  *  iSeries LPAR platform.                                   
20  *
21  *  This program is free software; you can redistribute it and/or
22  *  modify it under the terms of the GNU General Public License
23  *  as published by the Free Software Foundation; either version
24  *  2 of the License, or (at your option) any later version.
25  *      
26  */
27
28 #include <linux/config.h>
29 #include <asm/processor.h>
30 #include <asm/page.h>
31 #include <asm/mmu.h>
32 #include <asm/pgtable.h>
33 #include <asm/ppc_asm.h>
34 #include "ppc_defs.h"
35 #include "iSeries_asm.h"
36
37
38         .text
39         .globl  _stext
40 _stext:
41
42 /* iSeries LPAR
43  *
44  * In an iSeries partition, the operating system has no direct access
45  * to the hashed page table.  The iSeries hypervisor manages the
46  * hashed page table, and is directed by the operating system in the
47  * partition.  The partition, Linux in this case, always runs with
48  * MSR.IR and MSR.DR equal to 1.  The hypervisor establishes    
49  * addressibility for the first 64 MB of memory at 0xC0000000 by  
50  * building a hashed page table and setting segment register 12.
51  *
52  * The partition memory is not physically contiguous, nor necessarily
53  * addressable with a 32-bit address.  The hypervisor provides functions
54  * which the kernel can use to discover the layout of memory.  The  
55  * iSeries LPAR specific code in the kernel will build a table that maps
56  * contiguous pseudo-real addresses starting at zero to the actual 
57  * physical addresses owned by this partition.  In 32-bit mode we will
58  * restrict ourselves to no more than 768 MB (or maybe 1 GB)
59  *
60  * When Linux interrupt handlers get control, the hypervisor has 
61  * already saved SRR0 and SRR1 into a control block shared between
62  * the hypervisor and Linux.  This is know as the ItLpPaca.  The values
63  * in the actual SRR0 and SRR1 are not valid.  This requires a change in
64  * the way the SPRG registers are used.  The definitions are:
65  *
66  *   Register          old definition              new definition
67  *
68  *   SPRG0             temp - used to save gpr     reserved for hypervisor
69  *   SPRG1             temp - used to save gpr     addr of Paca
70  *   SPRG2             0 or kernel stack frame     temp - used to save gpr
71  *   SPRG3             Linux thread                Linux thread
72  *
73  * The Paca contains the address of the ItLpPaca.  The Paca is known only 
74  * to Linux, while the ItLpPaca is shared between Linux and the 
75  * hypervisor.
76  *
77  * The value that used to be in SPRG2 will now be saved in the Paca,
78  * as will at least one GPR.
79  */
80         
81         .globl  __start
82 __start:
83         b       start_here
84
85
86         . = 0x020
87
88         /* iSeries LPAR hypervisor expects a 64-bit offset of 
89            the hvReleaseData structure (see HvReleaseData.h)
90            at offset 0x20.  This is the base for all common
91            control blocks between the hypervisor and the kernel
92         */
93
94         .long   0       
95         .long   hvReleaseData-KERNELBASE
96         .long   0
97         .long   msChunks-KERNELBASE
98         .long   0
99         .long   pidhash-KERNELBASE
100         /* Pointer to start of embedded System.map */
101         .long   0
102         .globl  embedded_sysmap_start
103 embedded_sysmap_start:
104         .long   0
105         /* Pointer to end of embedded System.map */
106         .long   0
107         .globl  embedded_sysmap_end
108 embedded_sysmap_end:
109         .long   0
110
111
112         . = 0x060
113         
114         .globl  ste_fault_count
115 ste_fault_count:
116         .long   0
117         .globl  set_context_count
118 set_context_count:
119         .long   0
120         .globl  yield_count
121 yield_count:
122         .long   0
123         .globl  update_times_count
124 update_times_count:
125         .long   0
126         .globl  update_wall_jiffies_count
127 update_wall_jiffies_count:
128         .long   0
129         .globl  update_wall_jiffies_ticks
130 update_wall_jiffies_ticks:
131         .long   0
132
133
134 /*
135  * We assume SPRG1 has the address of the Paca and SPRG3
136  * has the address of the task's thread_struct.
137  * SPRG2 is used as a scratch register (as required by the
138  * hypervisor).  SPRG0 is reserved for the hypervisor.
139  *
140  * The ItLpPaca has the values of SRR0 and SRR1 that the 
141  * hypervisor saved at the point of the actual interrupt.  
142  *
143  * The Paca contains the value that the non-LPAR PPC Linux Kernel
144  * keeps in SPRG2, which is either zero (if the interrupt
145  * occurred in the kernel) or the address of the available
146  * space on the kernel stack (if the interrupt occurred
147  * in user code).
148 */
149 #define EXCEPTION_PROLOG_1      \
150         mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg */\
151         mfspr   r20,SPRG1;              /* get Paca */\
152         /* must do std not stw because soft disable protects    \
153          * 64-bit register use (in HvCall, maybe others)        \
154          */\
155         std     r21,PACAR21(r20);       /* Save GPR21 in Paca */\
156         std     r22,PACAR22(r20);       /* Save GPR22 in Paca */\
157         mfcr    r22                     /* Get CR */
158
159 #define EXCEPTION_PROLOG_2      \
160         lwz     r21,PACAKSAVE(r20);     /* exception stack to use */\
161         cmpwi   0,r21,0;                /* user mode or kernel     */\
162         bne     1f;                     /* 0 -> r1, else use PACAKSAVE */\
163         subi    r21,r1,INT_FRAME_SIZE;  /* alloc exc. frame */\
164 1:      stw     r1,GPR1(r21);   \
165         mr      r1,r21;         \
166         stw     r22,_CCR(r1);           /* save CR in stackframe */ \
167         mflr    r22;            \
168         stw     r22,_LINK(r1);          /* Save LR in stackframe */ \
169         bl      save_regs;              /* now save everything else */ \
170         ld      r22,PACALPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\
171         ld      r23,PACALPPACA+LPPACASRR1(r20) /* Get SRR1 from ItLpPaca */
172
173 #define EXCEPTION_PROLOG_EXIT   \
174         mtcrf   0xff,r22;       \
175         ld      r22,PACALPPACA+LPPACASRR0(r20); \
176         ld      r21,PACALPPACA+LPPACASRR1(r20); \
177         mtspr   SRR0,r22;       \
178         mtspr   SRR1,r21;       \
179         ld      r22,PACAR22(r20);       \
180         ld      r21,PACAR21(r20);       \
181         mfspr   r20,SPRG2;      \
182         RFI
183
184 #define EXCEPTION_PROLOG        \
185         EXCEPTION_PROLOG_1;     \
186         EXCEPTION_PROLOG_2
187
188
189 /*
190  * Note: code which follows this uses cr0.eq (set if from kernel),
191  * r21, r22 (SRR0), and r23 (SRR1).
192  */
193
194 /*
195  * Exception vectors.
196  */
197 #define STD_EXCEPTION(n, label, hdlr)           \
198         . = n;                                  \
199 label:                                          \
200         EXCEPTION_PROLOG;                       \
201         addi    r3,r1,STACK_FRAME_OVERHEAD;     \
202         li      r20,0;                          /* soft disabled */\
203         bl      transfer_to_handler;            \
204         .long   hdlr;                           \
205         .long   ret_from_except
206
207 /* System reset */
208         . = 0x100
209 SystemReset:    
210         mfspr   r3,SPRG3                /* Get Paca address */
211         mtspr   SPRG1,r3                /* Set Linux SPRG1 -> Paca */
212         lhz     r24,PACAPACAINDEX(r3)   /* Get processor # */
213         cmpi    0,r24,0                 /* Are we processor 0? */
214         beq     start_here              /* Start up the first processor */
215         mfspr   r4,CTRLF
216         li      r5,RUNLATCH
217         andc    r4,r4,r5                /* Turn off the run light */
218         mtspr   CTRLT,r4
219 1:
220         HMT_LOW
221 #ifdef CONFIG_SMP
222         lbz     r23,PACAPROCSTART(r3)   /* Test if this processor 
223                                          * should start */
224         cmpi    0,r23,0
225         bne     secondary_start
226 secondary_smp_loop:
227         /* Let the Hypervisor know we are alive */
228         /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
229         lis     r3,0x8002
230         rldicr  r0,r3,32,15             /* r0 = (r3 << 32) & 0xffff000000000000 */
231         rldicl  r3,r3,0,48              /* r3 = r3 & 0x000000000000ffff */
232         or      r3,r3,r0                /* r3 = r3 | r0                 */
233 #else /* CONFIG_SMP */
234         /* Yield the processor.  This is required for non-SMP kernels
235            which are running on multi-threaded machines. */
236         lis     r3,0x8000
237         rldicr  r3,r3,32,15             /* r3 = (r3 << 32) & 0xffff000000000000 */
238         addi    r3,r3,18                /* r3 = 0x8000000000000012 which is "yield" */
239         li      r4,0                    /* "yield timed" */
240         li      r5,-1                   /* "yield forever" */
241 #endif /* CONFIG_SMP */
242         li      r0,-1                   /* r0=-1 indicates a Hypervisor call */ 
243         sc                              /* Invoke the hypervisor via a system call */
244         mfspr   r3,SPRG1                /* Put r3 back */
245         b       1b                      /* If SMP not configured, secondaries
246                                          * loop forever */
247
248 /* Machine check */
249         STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
250
251 /* Data access exception. */
252         . = 0x300
253 DataAccess:
254         EXCEPTION_PROLOG
255         mfspr   r4,DAR
256         stw     r4,_DAR(r1)
257         mfspr   r5,DSISR
258         stw     r5,_DSISR(r1)
259         
260         andis.  r0,r5,0x0020            /* Is this a segment fault? */
261         bne     ste_fault               /* Yes - go reload segment regs */
262         
263         /* This should and with 0xd7ff */
264         andis.  r0,r5,0xa470            /* Can we handle as little fault? */
265         bne     1f                      /*  */
266         
267         rlwinm  r3,r5,32-15,21,21       /* DSISR_STORE -> _PAGE_RW */
268
269         /* 
270          * r3 contains the required access permissions
271          * r4 contains the faulting address
272          */
273
274         stw     r22,_NIP(r1)            /* Help with debug if dsi loop */
275         bl      hash_page               /* Try to handle as hpte fault */
276         lwz     r4,_DAR(r1)             /* Get original DAR */
277         lwz     r5,_DSISR(r1)           /* and original DSISR */
278
279 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
280         lwz     r20,_SOFTE(r1)
281         bl      transfer_to_handler
282         .long   do_page_fault
283         .long   ret_from_except
284
285
286 /* Instruction access exception. */
287         . = 0x400
288 InstructionAccess:
289         EXCEPTION_PROLOG
290         mr      r4,r22
291         mr      r5,r23
292
293         andis.  r0,r23,0x0020           /* Is this a segment fault? */
294         bne     ste_fault               /* Yes - go reload segment regs */
295         
296         andis.  r0,r23,0x4000           /* no pte found? */
297         beq     1f                      /* if so, try to put a PTE */
298
299         li      r3,0                    
300         bl      hash_page               /* Try to handle as hpte fault */
301         mr      r4,r22
302         mr      r5,r23
303
304 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
305         lwz     r20,_SOFTE(r1)
306         bl      transfer_to_handler
307         .long   do_page_fault
308         .long   ret_from_except
309
310 /* External interrupt */
311         . = 0x500;
312 HardwareInterrupt:
313         EXCEPTION_PROLOG_1
314         lbz     r21,PACAPROCENABLED(r20)
315         cmpi    0,r21,0
316         bne     1f
317         EXCEPTION_PROLOG_EXIT
318 1:      EXCEPTION_PROLOG_2
319 do_pending_int:
320         addi    r3,r1,STACK_FRAME_OVERHEAD
321         li      r4,0
322         li      r20,0                   /* Soft disabled */
323         bl      transfer_to_handler
324         .globl do_IRQ_intercept
325 do_IRQ_intercept:
326         .long   do_IRQ;
327         .long   ret_from_intercept
328
329 /* Alignment exception */
330         . = 0x600
331 Alignment:
332         EXCEPTION_PROLOG
333         mfspr   r4,DAR
334         stw     r4,_DAR(r1)
335         mfspr   r5,DSISR
336         stw     r5,_DSISR(r1)
337         addi    r3,r1,STACK_FRAME_OVERHEAD
338         lbz     r20,PACAPROCENABLED(r20)        /* preserve soft en/disabled */
339         bl      transfer_to_handler
340         .long   AlignmentException
341         .long   ret_from_except
342
343 /* Program check exception */
344         . = 0x700
345 ProgramCheck:
346         EXCEPTION_PROLOG
347         addi    r3,r1,STACK_FRAME_OVERHEAD
348         lbz     r20,PACAPROCENABLED(r20)        /* preserve soft en/disabled */
349         bl      transfer_to_handler
350         .long   ProgramCheckException
351         .long   ret_from_except
352
353 /* Floating-point unavailable */
354         . = 0x800
355 FPUnavailable:
356         EXCEPTION_PROLOG
357         lwz     r3,PACAKSAVE(r20)
358         cmpwi   0,r3,0
359         beq     1f
360         b       load_up_fpu
361 1:
362         li      r20,0                   /* soft disabled */
363         bl      transfer_to_handler     /* if from kernel, take a trap */
364         .long   KernelFP
365         .long   ret_from_except
366
367         . = 0x900
368 Decrementer:
369         EXCEPTION_PROLOG_1
370         lbz     r21,PACAPROCENABLED(r20)
371         cmpi    0,r21,0
372         bne     1f
373         
374         li      r21,1
375         stb     r21,PACALPPACA+LPPACADECRINT(r20)
376         lwz     r21,PACADEFAULTDECR(r20)
377         mtspr   DEC,r21
378         EXCEPTION_PROLOG_EXIT
379 1:      EXCEPTION_PROLOG_2
380         addi    r3,r1,STACK_FRAME_OVERHEAD
381         li      r20,0           /* Soft disabled */
382         bl      transfer_to_handler
383         .globl timer_interrupt_intercept
384 timer_interrupt_intercept:
385         .long   timer_interrupt
386         .long   ret_from_intercept
387
388         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
389         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
390
391 /* System call */
392         . = 0xc00
393 SystemCall:
394         EXCEPTION_PROLOG
395         /* Store r3 to the kernel stack */
396         stw     r3,ORIG_GPR3(r1)
397         lbz     r20,PACAPROCENABLED(r20)        /* preserve soft en/disabled */
398         bl      transfer_to_handler
399         .long   DoSyscall
400         .long   ret_from_except
401
402 /* Single step - not used on 601 */
403         STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
404 /*
405         STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
406         STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
407 */
408         STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
409 /*
410         STD_EXCEPTION(0x1400, SMI, SMIException)
411         STD_EXCEPTION(0x1500, Trap_15, UnknownException)
412         STD_EXCEPTION(0x1600, Trap_16, UnknownException)
413         STD_EXCEPTION(0x1700, Trap_17, TAUException)
414         STD_EXCEPTION(0x1800, Trap_18, UnknownException)
415         STD_EXCEPTION(0x1900, Trap_19, UnknownException)
416         STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
417         STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
418         STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
419         STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
420         STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
421         STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
422         STD_EXCEPTION(0x2000, RunMode, RunModeException)
423         STD_EXCEPTION(0x2100, Trap_21, UnknownException)
424         STD_EXCEPTION(0x2200, Trap_22, UnknownException)
425         STD_EXCEPTION(0x2300, Trap_23, UnknownException)
426         STD_EXCEPTION(0x2400, Trap_24, UnknownException)
427         STD_EXCEPTION(0x2500, Trap_25, UnknownException)
428         STD_EXCEPTION(0x2600, Trap_26, UnknownException)
429         STD_EXCEPTION(0x2700, Trap_27, UnknownException)
430         STD_EXCEPTION(0x2800, Trap_28, UnknownException)
431         STD_EXCEPTION(0x2900, Trap_29, UnknownException)
432         STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
433         STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
434         STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
435         STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
436         STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
437         STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
438 */
439         . = 0x3000
440
441         /* This code saves: CTR, XER, DAR, DSISR, SRR0, SRR1, */
442         /*                  r0, r2-r13, r20-r24               */
443         /*                  It uses R22 as a scratch register */
444 save_regs:
445         ld      r22,PACAR21(r20)        /* Get GPR21 from Paca */
446         stw     r22,GPR21(r1)           /* Save GPR21 in stackframe */
447         ld      r22,PACAR22(r20)        /* Get GPR22 from Paca */
448         stw     r22,GPR22(r1)           /* Save GPR22 in stackframe */
449         stw     r23,GPR23(r1)           /* Save GPR23 in stackframe */
450         stw     r24,GPR24(r1)           /* Save GPR24 in stackframe */
451         mfspr   r22,SPRG2               /* Get GPR20 from SPRG2 */
452         stw     r22,GPR20(r1)           /* Save GPR20 in stackframe */
453         mfctr   r22             
454         stw     r22,_CTR(r1)    
455         mfspr   r22,XER 
456         stw     r22,_XER(r1)    
457         lbz     r22,PACAPROCENABLED(r20)/* Get soft enabled/disabled */
458         stw     r22,_SOFTE(r1)
459         stw     r0,GPR0(r1)     
460         SAVE_8GPRS(2, r1)       
461         SAVE_4GPRS(10, r1)      
462         blr
463         
464 ste_fault:
465         bl      set_kernel_segregs
466
467         mfspr   r3,SPRG1
468         li      r4,0
469         stb     r4,PACAPROCENABLED(r3)  /* Soft disable prevents going to */
470                                         /* do_pending_int on recursive fault */ 
471
472         lis     r3,ste_fault_count@ha
473         lwz     r4,ste_fault_count@l(r3)
474         addi    r4,r4,1
475         stw     r4,ste_fault_count@l(r3)
476
477         mfspr   r3,SPRG3                /* get thread */
478         addi    r3,r3,-THREAD           /* get 'current' */
479         lwz     r3,MM(r3)               /* get mm */
480         cmpi    0,r3,0                  /* if no mm */
481         beq     1f                      /* then use context 0 (kernel) */
482         lwz     r3,CONTEXT(r3)          /* get context */
483 1:      
484         /* set_context kills r0, r3, r4 and CTR */
485         bl      set_context
486         
487         lwz     r3,_SOFTE(r1)
488         cmpi    0,r3,0
489         beq     5f                      /* skip checks if restoring disabled */
490
491         CHECKANYINT(r4,r5,r6)           /* if pending interrupts, process them */
492         bne-    do_pending_int
493 5:
494         mfspr   r4,SPRG1
495         stb     r3,PACAPROCENABLED(r4)  /* Restore enabled/disabled */
496         
497         b       fault_exit
498         
499 /*
500  * This code finishes saving the registers to the exception frame
501  * and jumps to the appropriate handler for the exception, turning
502  * on address translation.
503  *
504  * At this point r0-r13, r20-r24, CCR, CTR, LINK, XER, DAR and DSISR
505  * are saved on a stack.  SRR0 is in r22, SRR1 is in r23
506  * r1 points to the stackframe, r1 points to the kernel stackframe
507  * We no longer have any dependency on data saved in the PACA, SRR0, SRR1
508  * DAR or DSISR.  We now copy the registers to the kernel stack (which
509  * might cause little faults).  Any little fault will be handled without
510  * saving state.  Thus when the little fault is completed, it will rfi
511  * back to the original faulting instruction.
512  */
513         .globl  transfer_to_handler
514 transfer_to_handler:
515
516         mfspr   r6,SPRG1
517         li      r7,0
518         stw     r7,PACAKSAVE(r6)        /* Force new frame for recursive fault */
519
520         /* Restore the regs used above -- parameters to syscall */
521         lwz     r6,GPR6(r1)
522         lwz     r7,GPR7(r1)
523
524         stw     r22,_NIP(r1)
525         stw     r23,_MSR(r1)
526         SAVE_4GPRS(14, r1)
527         SAVE_2GPRS(18, r1)
528         SAVE_4GPRS(25, r1)
529         SAVE_2GPRS(29, r1)
530         SAVE_GPR(31, r1)
531
532         andi.   r23,r23,MSR_PR
533         mfspr   r23,SPRG3               /* if from user, fix up THREAD.regs */
534         beq     2f
535         addi    r24,r1,STACK_FRAME_OVERHEAD
536         stw     r24,PT_REGS(r23)
537 2:      addi    r2,r23,-THREAD          /* set r2 to current */
538         li      r22,RESULT
539         stwcx.  r22,r22,r1              /* to clear the reservation */
540         li      r22,0
541         stw     r22,RESULT(r1)
542         mfspr   r23,SPRG1               /* Get Paca address */
543         stb     r20,PACAPROCENABLED(r23) /* soft enable or disabled */
544         mflr    r23
545         andi.   r24,r23,0x3f00          /* get vector offset */
546         stw     r24,TRAP(r1)
547         addi    r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
548         cmplw   0,r1,r2
549         cmplw   1,r1,r24
550         crand   1,1,4
551         bgt-    stack_ovf               /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
552         lwz     r24,0(r23)              /* virtual address of handler */
553         lwz     r23,4(r23)              /* where to go when done */
554         li      r20,MSR_KERNEL
555         ori     r20,r20,MSR_EE          /* Always hard enabled */
556         FIX_SRR1(r20,r22)
557         mtspr   SRR0,r24
558         mtspr   SRR1,r20
559         mtlr    r23
560         RFI                             /* jump to handler, enable MMU */
561
562 /*
563  * On kernel stack overflow, load up an initial stack pointer
564  * and call StackOverflow(regs), which should not return.
565  */
566 stack_ovf:
567         addi    r3,r1,STACK_FRAME_OVERHEAD
568         lis     r1,init_task_union@ha
569         addi    r1,r1,init_task_union@l
570         addi    r1,r1,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD
571         mfspr   r24,SPRG1
572         li      r20,0
573         stb     r20,PACAPROCENABLED(r24)        /* soft disable */
574         lis     r24,StackOverflow@ha
575         addi    r24,r24,StackOverflow@l
576         li      r20,MSR_KERNEL
577         ori     r20,r20,MSR_EE          /* Always hard enabled */
578         FIX_SRR1(r20,r22)
579         mtspr   SRR0,r24
580         mtspr   SRR1,r20
581         RFI
582
583 /*
584  * Disable FP for the task which had the FPU previously,
585  * and save its floating-point registers in its thread_struct.
586  * Enables the FPU for use in the kernel on return.
587  * On SMP we know the fpu is free, since we give it up every
588  * switch.  -- Cort
589  * Assume r20 points to PACA on entry
590  */
591 load_up_fpu:
592         mfmsr   r5
593         ori     r5,r5,MSR_FP
594         SYNC
595         MTMSRD(r5)                      /* enable use of fpu now */
596         isync
597 /*
598  * For SMP, we don't do lazy FPU switching because it just gets too
599  * horrendously complex, especially when a task switches from one CPU
600  * to another.  Instead we call giveup_fpu in switch_to.
601  */
602 #ifndef CONFIG_SMP
603         lis     r3,last_task_used_math@ha
604         lwz     r4,last_task_used_math@l(r3)
605         cmpi    0,r4,0
606         beq     1f
607         addi    r4,r4,THREAD            /* want last_task_used_math->thread */
608         SAVE_32FPRS(0, r4)
609         mffs    fr0
610         stfd    fr0,THREAD_FPSCR-4(r4)
611         lwz     r5,PT_REGS(r4)
612         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
613         li      r20,MSR_FP|MSR_FE0|MSR_FE1
614         andc    r4,r4,r20               /* disable FP for previous task */
615         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
616 1:
617 #endif /* CONFIG_SMP */
618         /* enable use of FP after return */
619         ori     r23,r23,MSR_FP|MSR_FE0|MSR_FE1
620         mfspr   r5,SPRG3                /* current task's THREAD (phys) */
621         lfd     fr0,THREAD_FPSCR-4(r5)
622         mtfsf   0xff,fr0
623         REST_32FPRS(0, r5)
624 #ifndef CONFIG_SMP
625         subi    r4,r5,THREAD
626         stw     r4,last_task_used_math@l(r3)
627 #endif /* CONFIG_SMP */
628         /* restore registers and return */
629         lwz     r3,_CCR(r21)
630         lwz     r4,_LINK(r21)
631         mtcrf   0xff,r3
632         mtlr    r4
633         REST_GPR(1, r21)
634         REST_4GPRS(3, r21)
635         /* we haven't used ctr or xer */
636         mtspr   SRR1,r23
637         mtspr   SRR0,r22
638
639         REST_GPR(20, r21)
640         REST_2GPRS(22, r21)
641         lwz     r21,GPR21(r21)
642         SYNC
643         RFI
644         
645 /*
646  * FP unavailable trap from kernel - print a message, but let
647  * the task use FP in the kernel until it returns to user mode.
648  */
649 KernelFP:
650         lwz     r3,_MSR(r1)
651         ori     r3,r3,MSR_FP
652         stw     r3,_MSR(r1)             /* enable use of FP after return */
653         lis     r3,86f@h
654         ori     r3,r3,86f@l
655         mr      r4,r2                   /* current */
656         lwz     r5,_NIP(r1)
657         bl      printk
658         b       ret_from_except
659 86:     .string "floating point used in kernel (task=%p, pc=%x)\n"
660         .align  4
661
662 /*
663  * giveup_fpu(tsk)
664  * Disable FP for the task given as the argument,
665  * and save the floating-point registers in its thread_struct.
666  * Enables the FPU for use in the kernel on return.
667  */
668         .globl  giveup_fpu
669 giveup_fpu:
670         mfmsr   r5
671         ori     r5,r5,MSR_FP
672         mtmsr   r5                      /* enable use of fpu now */
673         cmpi    0,r3,0
674         beqlr-                          /* if no previous owner, done */
675         addi    r3,r3,THREAD            /* want THREAD of task */
676         lwz     r5,PT_REGS(r3)
677         cmpi    0,r5,0
678         SAVE_32FPRS(0, r3)
679         mffs    fr0
680         stfd    fr0,THREAD_FPSCR-4(r3)
681         beq     1f
682         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
683         li      r3,MSR_FP|MSR_FE0|MSR_FE1
684         andc    r4,r4,r3                /* disable FP for previous task */
685         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
686 1:
687 #ifndef CONFIG_SMP
688         li      r5,0
689         lis     r4,last_task_used_math@ha
690         stw     r5,last_task_used_math@l(r4)
691 #endif /* CONFIG_SMP */
692         blr
693
694 #ifdef CONFIG_SMP 
695 secondary_start:
696         lis     r3,0,
697         mr      r4,r24
698         bl      identify_cpu
699         bl      call_setup_cpu          /* Call setup_cpu for this CPU */
700
701         /* get current */
702         HMT_MEDIUM                      /* Set thread priority to MEDIUM */
703         lis     r2,current_set@h
704         ori     r2,r2,current_set@l
705         slwi    r24,r24,2               /* get current_set[cpu#] */
706         lwzx    r2,r2,r24
707
708         /* stack */
709         addi    r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD
710         li      r0,0
711         stw     r0,0(r1)
712
713         /* load up the MMU */
714         bl      load_up_mmu
715
716         /* ptr to phys current thread */
717         addi    r4,r2,THREAD    /* phys address of our thread_struct */
718         rlwinm  r4,r4,0,0,31
719         mtspr   SPRG3,r4
720
721         /* Set up address of Paca in current thread */
722         lis     r23,xPaca@ha
723         addi    r23,r23,xPaca@l
724         /* r24 has CPU # * 4 at this point.  The Paca is 2048 bytes
725            long so multiply r24 by 512 to index into the array of Pacas */
726         slwi    r24,r24,9
727         add     r23,r23,r24
728         rlwinm  r23,r23,0,0,31
729         mtspr   SPRG1,r23
730
731         li      r3,0
732         stw     r3,PACAKSAVE(r23)       /* 0 => r1 has kernel sp */
733
734         stb     r3,PACAPROCENABLED(r23) /* Soft disabled */
735
736         /* enable MMU and jump to start_secondary */
737         
738         li      r4,MSR_KERNEL
739         ori     r4,r4,MSR_EE            /* Hard enabled */
740         lis     r3,start_secondary@h
741         ori     r3,r3,start_secondary@l
742         mtspr   SRR0,r3
743         FIX_SRR1(r4,r3)
744         mtspr   SRR1,r4
745         RFI
746 #endif /* CONFIG_SMP */
747
748 /*
749  * Load stuff into the MMU.  Intended to be called with
750  * IR=0 and DR=0.
751  */
752 load_up_mmu:
753         li      r0,16           /* load up segment register values */
754         mtctr   r0              /* for context 0 */
755         lis     r3,0x2000       /* Ku = 1, VSID = 0 */
756         li      r4,0
757 3:      mtsrin  r3,r4
758         addi    r3,r3,0x111     /* increment VSID */
759         addis   r4,r4,0x1000    /* address of next segment */
760         bdnz    3b
761         blr
762
763 /*
764  * This is where the main kernel code starts.
765  */
766 start_here:
767
768         /* ptr to current */
769
770         lis     r2,init_task_union@h
771         ori     r2,r2,init_task_union@l
772
773         /* Set up for using our exception vectors */
774
775         addi    r4,r2,THREAD    /* init task's THREAD */
776         rlwinm  r4,r4,0,0,31
777         mtspr   SPRG3,r4
778
779         /* Get address of Paca for processor 0 */
780         lis     r11,xPaca@ha
781         addi    r11,r11,xPaca@l
782         rlwinm  r11,r11,0,0,31
783         mtspr   SPRG1,r11
784
785         li      r3,0
786         stw     r3,PACAKSAVE(r11)       /* 0 => r1 has kernel sp */
787
788         stb     r3,PACAPROCENABLED(r11) /* Soft disabled */
789
790         addi    r1,r2,TASK_UNION_SIZE
791         li      r0,0
792         stwu    r0,-STACK_FRAME_OVERHEAD(r1)
793
794         /* fix klimit for system map */
795         lis     r6,embedded_sysmap_end@ha
796         lwz     r7,embedded_sysmap_end@l(r6)
797
798         cmpi    0,r7,0
799         beq     5f
800
801         lis     r6, KERNELBASE@h
802         add     r7,r7,r6
803         addi    r7,r7,4095
804         li      r6,0x0FFF
805         andc    r7,r7,r6
806
807         lis     r6,klimit@ha
808         stw     r7,klimit@l(r6)
809 5:      
810         
811 /*
812  * Decide what sort of machine this is and initialize the MMU.
813  */
814         bl      early_init      /* We have to do this with MMU on */
815
816         mr      r3,r31
817         mr      r4,r30
818         mr      r5,r29
819         mr      r6,r28
820         mr      r7,r27
821         li      r6,0            /* No cmdline parameters */
822         bl      platform_init
823         bl      MMU_init
824
825         bl      load_up_mmu
826
827         li      r4,MSR_KERNEL
828         ori     r4,r4,MSR_EE    /* Hard enabled */
829         FIX_SRR1(r4,r5)
830         lis     r3,start_kernel@h
831         ori     r3,r3,start_kernel@l
832         mtspr   SRR0,r3
833         mtspr   SRR1,r4
834         RFI                             /* ensure correct MSR and jump to
835                                            start_kernel */
836 hash_page:
837         mflr    r21                     /* Save LR in r21 */
838
839         /* 
840          * We hard enable here (but first soft disable) so that the hash_page
841          * code can spin on the hash_table_lock without problem on a shared
842          * processor
843          */
844         li      r0,0
845         stb     r0,PACAPROCENABLED(r20) /* Soft disable */
846
847         mfmsr   r0
848         ori     r0,r0,MSR_EE
849         mtmsr   r0                      /* Hard enable */
850
851         bl      create_hpte             /* add the hash table entry */
852         /*
853          * Now go back to hard disabled
854          */
855         mfmsr   r0
856         li      r4,0
857         ori     r4,r4,MSR_EE
858         andc    r0,r0,r4
859         mtmsr   r0                      /* Hard disable */
860
861         lwz     r0,_SOFTE(r1)
862         mtlr    r21                     /* restore LR */
863         mr      r21,r1                  /* restore r21 */
864
865         cmpi    0,r0,0                  /* See if we will soft enable in */
866                                         /* fault_exit */
867         beq     5f                      /* if not, skip checks */
868
869         CHECKANYINT(r4,r5,r6)           /* if pending interrupts, process them */
870         bne-    do_pending_int
871
872 5:      stb     r0,PACAPROCENABLED(r20) /* Restore soft enable/disable */
873
874         cmpi    0,r3,0                  /* check return code form create_hpte */
875         bnelr
876
877 /*
878  * htab_reloads counts the number of times we have to fault an
879  * HPTE into the hash table.  This should only happen after a
880  * fork (because fork does a flush_tlb_mm) or a vmalloc or ioremap.
881  * Where a page is faulted into a process's address space,
882  * update_mmu_cache gets called to put the HPTE into the hash table
883  * and those are counted as preloads rather than reloads.
884  */
885         lis     r2,htab_reloads@ha
886         lwz     r3,htab_reloads@l(r2)
887         addi    r3,r3,1
888         stw     r3,htab_reloads@l(r2)
889
890 fault_exit:
891         
892         lwz     r3,_CCR(r1)
893         lwz     r4,_LINK(r1)
894         lwz     r5,_CTR(r1)
895         lwz     r6,_XER(r1)
896
897         mtcrf   0xff,r3
898         mtlr    r4
899         mtctr   r5
900         mtspr   XER,r6
901
902         lwz     r0,GPR0(r1)
903         REST_8GPRS(2, r1)
904         REST_4GPRS(10, r1)
905         FIX_SRR1(r23,r20)
906         mtspr   SRR1,r23
907         mtspr   SRR0,r22
908         REST_4GPRS(20, r1)
909
910         lwz     r1,GPR1(r1)
911         RFI
912
913 /*
914  * Set up the segment registers for a new context.
915  *   context in r3
916  */
917 _GLOBAL(set_context)
918         mulli   r3,r3,897       /* multiply context by skew factor */
919         rlwinm  r3,r3,4,8,27    /* VSID = (context & 0xfffff) << 4 */
920         addis   r3,r3,0x6000    /* Set Ks, Ku bits */
921         li      r0,NUM_USER_SEGMENTS
922         mtctr   r0
923
924         li      r4,0
925 3:
926         mtsrin  r3,r4
927         addi    r3,r3,0x111     /* next VSID */
928         rlwinm  r3,r3,0,8,3     /* clear out any overflow from VSID field */
929         addis   r4,r4,0x1000    /* address of next segment */
930         bdnz    3b
931         isync
932
933 set_kernel_segregs:
934
935 /* 
936  * Reload the last four segment registers because they 
937  * might have been clobbered by the hypervisor if we
938  * are running on a shared processor
939  */
940         lis     r3,0x2000       /* Set Ku = 1 */
941         addi    r3,r3,0xCCC     /* Set VSID = CCC */
942         lis     r4,0xC000       /* Set SR = C */
943         li      r0,4            /* Load regs C, D, E and F */
944         mtctr   r0
945 4:      mtsrin  r3,r4
946         addi    r3,r3,0x111     /* increment VSID */
947         addis   r4,r4,0x1000    /* address of next segment */
948         bdnz    4b
949         isync
950
951         blr
952
953
954 /* Hypervisor call
955  *
956  * Invoke the iSeries hypervisor (PLIC) via the System Call instruction.
957  * Parameters are passed to this routine in registers r3 - r10 and are
958  * converted to 64-bit by combining registers. eg. r3 <- r3 
959  * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10
960  * 
961  * r3 contains the HV function to be called
962  * r5,r6 contain the first 64-bit operand
963  * r7,r8 contain the second 64-bit operand
964  * r9,r10 contain the third 64-bit operand
965  * caller's stack frame +8 contains the fourth 64-bit operand
966  * caller's stack frame +16 contains the fifth 64-bit operand
967  * caller's stack frame +24 contains the sixth 64-bit operand
968  * caller's stack frame +32 contains the seventh 64-bit operand
969  *
970  */
971
972 _GLOBAL(HvCall) 
973 _GLOBAL(HvCall0)
974 _GLOBAL(HvCall1)
975 _GLOBAL(HvCall2)
976 _GLOBAL(HvCall3)
977 _GLOBAL(HvCall4)
978 _GLOBAL(HvCall5)
979 _GLOBAL(HvCall6)
980 _GLOBAL(HvCall7)
981    /* 
982     * Stack a frame and save one reg so we can hang on to
983     * the old MSR
984     */
985    stwu   r1,-64(r1)
986    stw    r31,60(r1)
987
988    stw    r22,24(r1)
989    stw    r23,28(r1)
990    stw    r24,32(r1)
991    stw    r25,36(r1)
992    stw    r26,40(r1)
993    stw    r27,44(r1)
994    stw    r28,48(r1)
995    stw    r29,52(r1)
996
997    /*
998     * The hypervisor assumes CR fields 0-4 are volatile, but
999     * gcc assumes CR fields 2-7 are non-volatile.  
1000     * We must save and restore the CR here
1001     */
1002    mfcr   r31
1003    stw    r31,20(r1)
1004    
1005    /* Before we can convert to using 64-bit registers we must
1006     * soft disable external interrupts as the interrupt handlers
1007     * don't preserve the high half of the registers
1008     */
1009
1010    mfspr  r11,SPRG1             /* Get the Paca pointer */
1011    lbz    r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */
1012    li     r0,0
1013    stb    r0,PACAPROCENABLED(r11)  /* Soft disable */
1014
1015    /* Get parameters four through seven */
1016
1017    lwz    r22,72(r1)
1018    lwz    r23,76(r1)
1019    lwz    r24,80(r1)
1020    lwz    r25,84(r1)
1021    lwz    r26,88(r1)
1022    lwz    r27,92(r1)
1023    lwz    r28,96(r1)
1024    lwz    r29,100(r1)
1025    /* Now it is safe to operate on 64-bit registers
1026     * 
1027     * Format the operands into the 64-bit registers
1028     *
1029     */
1030    rldicr r5,r5,32,31           /* r5 = r5 << 32                */
1031    rldicl r6,r6,0,32            /* r6 = r6 & 0x00000000ffffffff */
1032    or     r4,r5,r6              /* r4 = r5 | r6                 */
1033    rldicr r7,r7,32,31           /* r7 = r7 << 32                */
1034    rldicl r8,r8,0,32            /* r8 = r8 & 0x00000000ffffffff */
1035    or     r5,r7,r8              /* r5 = r7 | r8                 */
1036    rldicr r9,r9,32,31           /* r9 = r9 << 32                */
1037    rldicl r10,r10,0,32          /* r10 = r10 & 0x00000000ffffffff */
1038    or     r6,r9,r10             /* r6 = r9 | r10                */
1039    rldicr r22,r22,32,31         /* r22 = r22 << 32              */
1040    rldicl r23,r23,0,32          /* r23 = r23 & 0x00000000ffffffff */
1041    or     r7,r22,r23            /* r7 = r22 | r23               */
1042    rldicr r24,r24,32,31         /* r24 = r24 << 32              */
1043    rldicl r25,r25,0,32          /* r25 = r25 & 0x00000000ffffffff */
1044    or     r8,r24,r25            /* r8 = r24 | r25               */
1045    rldicr r26,r26,32,31         /* r26 = r26 << 32              */
1046    rldicl r27,r27,0,32          /* r27 = r27 & 0x00000000ffffffff */
1047    or     r9,r26,r27            /* r9 = r26 | r27               */
1048    rldicr r28,r28,32,31         /* r28 = r28 << 32              */
1049    rldicl r29,r29,0,32          /* r29 = r29 & 0x00000000ffffffff */
1050    or     r10,r28,r29           /* r10 = r28 | r29              */
1051    
1052    /* 
1053     * Extract the hypervisor function call number from R3
1054     * and format it into the 64-bit R3.
1055     */
1056    rldicr r0,r3,32,15           /* r0 = (r3 << 32) & 0xffff000000000000 */
1057    rldicl r3,r3,0,48            /* r3 = r3 & 0x000000000000ffff */
1058    or     r3,r3,r0              /* r3 = r3 | r0                 */
1059    
1060    /*
1061     * r0 = 0xffffffffffffffff indicates a hypervisor call 
1062     */
1063    li     r0,-1                 /* r1 = 0xffffffffffffffff      */
1064    
1065    /* Invoke the hypervisor via the System Call instruction */
1066
1067    sc
1068   
1069    HMT_MEDIUM
1070   
1071    /* Return value in 64-bit R3
1072     * format it into R3 and R4
1073     */
1074    rldicl r4,r3,0,32            /* r4 = r3 & 0x00000000ffffffff */
1075    rldicl r3,r3,32,32           /* r3 = (r3 >> 32) & 0x00000000ffffffff */
1076
1077    /* We are now done with 64-bit registers it is safe to touch
1078     * the stack again.
1079     */
1080    lwz    r22,24(r1)
1081    lwz    r23,28(r1)
1082    lwz    r24,32(r1)
1083    lwz    r25,36(r1)
1084    lwz    r26,40(r1)
1085    lwz    r27,44(r1)
1086    lwz    r28,48(r1)
1087    lwz    r29,52(r1)
1088
1089    /* While we were running in the hypervisor, a decrementer or
1090     * external interrupt may have occured.  If we are about to
1091     * enable here, we must check for these and process them
1092     */
1093
1094    cmpi   0,r31,0               /* check if going to enable */
1095    beq    1f                    /* skip checks if staying disabled */
1096
1097    /* Save r3, r4 and LR */
1098    stw    r3,52(r1)
1099    stw    r4,48(r1)
1100    mflr   r3
1101    stw    r3,44(r1)
1102
1103    /* enable and check for decrementers/lpEvents */
1104    mr   r3,r31
1105    bl   __restore_flags
1106
1107    /* Restore r3, r4 and LR */
1108    lwz    r3,44(r1)
1109    mtlr   r3
1110    lwz    r3,52(r1)
1111    lwz    r4,48(r1)
1112
1113 1:
1114    /* 
1115     * Unstack the frame and restore r31 and the CR
1116     */
1117    lwz    r31,20(r1)
1118    mtcrf  0xff,r31 
1119    lwz    r31,60(r1)
1120    lwz    r1,0(r1)
1121     
1122    blr 
1123    
1124 /* Hypervisor call with return data
1125  *
1126  * Invoke the iSeries hypervisor (PLIC) via the System Call instruction.
1127  * The Hv function ID is passed in r3
1128  * The address of the return data structure is passed in r4
1129  * Parameters are passed to this routine in registers r5 - r10 and are
1130  * converted to 64-bit by combining registers. eg. r3 <- r3 
1131  * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10
1132  * 
1133  * r3 contains the HV function to be called
1134  * r4 contains the address of the return data structure
1135  * r5,r6 contain the first 64-bit operand
1136  * r7,r8 contain the second 64-bit operand
1137  * r9,r10 contain the third 64-bit operand
1138  * caller's stack frame +8 contains the fourth 64-bit operand
1139  * caller's stack frame +16 contains the fifth 64-bit operand
1140  * caller's stack frame +24 contains the sixth 64-bit operand
1141  * caller's stack frame +32 contains the seventh 64-bit operand
1142  *
1143  */
1144
1145 _GLOBAL(HvCallRet16) 
1146 _GLOBAL(HvCall0Ret16)
1147 _GLOBAL(HvCall1Ret16)
1148 _GLOBAL(HvCall2Ret16)
1149 _GLOBAL(HvCall3Ret16)
1150 _GLOBAL(HvCall4Ret16)
1151 _GLOBAL(HvCall5Ret16)
1152 _GLOBAL(HvCall6Ret16)
1153 _GLOBAL(HvCall7Ret16)
1154
1155    /*
1156     * Stack a frame and save some regs
1157     */
1158    stwu   r1,-64(r1)
1159    stw    r31,60(r1)
1160    stw    r30,56(r1)
1161
1162    stw    r22,24(r1)
1163    stw    r23,28(r1)
1164    stw    r24,32(r1)
1165    stw    r25,36(r1)
1166    stw    r26,40(r1)
1167    stw    r27,44(r1)
1168    stw    r28,48(r1)
1169    stw    r29,52(r1)
1170
1171    mr     r30,r4                /* Save return data address */
1172
1173    /*
1174     * The hypervisor assumes CR fields 0-4 are volatile, but
1175     * gcc assumes CR fields 2-7 are non-volatile.  
1176     * We must save and restore the CR here
1177     */
1178    mfcr   r31
1179    stw    r31,20(r1)
1180
1181    /* Before we can convert to using 64-bit registers we must
1182     * soft disable external interrupts as the interrupt handlers
1183     * don't preserve the high half of the registers
1184     */
1185
1186    mfspr  r11,SPRG1             /* Get the Paca pointer */
1187    lbz    r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */
1188    li     r0,0
1189    stb    r0,PACAPROCENABLED(r11)  /* Soft disable */
1190
1191    /* Get parameters four through seven */
1192
1193    lwz    r22,76(r1)
1194    lwz    r23,80(r1)
1195    lwz    r24,84(r1)
1196    lwz    r25,88(r1)
1197    lwz    r26,92(r1)
1198    lwz    r27,96(r1)
1199    lwz    r28,100(r1)
1200    lwz    r29,104(r1)
1201
1202    /* Now it is safe to operate on 64-bit registers
1203     *
1204     */
1205     
1206    /* 
1207     * Format the operands into the 64-bit registers
1208     */
1209
1210    rldicr r5,r5,32,31           /* r5 = r5 << 32                */
1211    rldicl r6,r6,0,32            /* r6 = r6 & 0x00000000ffffffff */
1212    or     r4,r5,r6              /* r4 = r5 | r6                 */
1213    rldicr r7,r7,32,31           /* r7 = r7 << 32                */
1214    rldicl r8,r8,0,32            /* r8 = r8 & 0x00000000ffffffff */
1215    or     r5,r7,r8              /* r5 = r7 | r8                 */
1216    rldicr r9,r9,32,31           /* r9 = r9 << 32                */
1217    rldicl r10,r10,0,32          /* r10 = r10 & 0x00000000ffffffff */
1218    or     r6,r9,r10             /* r6 = r9 | r10                */
1219    rldicr r22,r22,32,31         /* r22 = r22 << 32              */
1220    rldicl r23,r23,0,32          /* r23 = r23 & 0x00000000ffffffff */
1221    or     r7,r22,r23            /* r7 = r22 | r23               */
1222    rldicr r24,r24,32,31         /* r24 = r24 << 32              */
1223    rldicl r25,r25,0,32          /* r25 = r25 & 0x00000000ffffffff */
1224    or     r8,r24,r25            /* r8 = r24 | r25               */
1225    rldicr r26,r26,32,31         /* r26 = r26 << 32              */
1226    rldicl r27,r27,0,32          /* r27 = r27 & 0x00000000ffffffff */
1227    or     r9,r26,r27            /* r9 = r26 | r27               */
1228    rldicr r28,r28,32,31         /* r28 = r28 << 32              */
1229    rldicl r29,r29,0,32          /* r29 = r29 & 0x00000000ffffffff */
1230    or     r10,r28,r29           /* r10 = r28 | r29              */
1231    /* 
1232     * Extract the hypervisor function call number from R3
1233     * and format it into the 64-bit R3.
1234     */
1235    rldicr r0,r3,32,15           /* r4 = (r3 << 32) & 0xffff000000000000 */
1236    rldicl r3,r3,0,48            /* r3 = r3 & 0x000000000000ffff */
1237    or     r3,r3,r0              /* r3 = r3 | r4                 */
1238    
1239    /*
1240     * r0 = 0xffffffffffffffff indicates a hypervisor call 
1241     */
1242    li     r0,-1                 /* r1 = 0xffffffffffffffff      */
1243    
1244    /* Invoke the hypervisor via the System Call instruction */
1245
1246    sc
1247   
1248    HMT_MEDIUM
1249   
1250    /* Return values in 64-bit R3, R4, R5 and R6
1251     * place R3 and R4 into data structure, R5 into R3,R4 
1252     */
1253    rldicl r6,r3,32,32           /* r6 = (r3 >> 32) & 0x00000000ffffffff */
1254    rldicl r7,r3,0,32            /* r7 = r3 & 0x00000000ffffffff */
1255    rldicl r8,r4,32,32           /* r8 = (r4 >> 32) & 0x00000000ffffffff */
1256    rldicl r9,r4,0,32            /* r9 = r4 & 0x00000000ffffffff */
1257        
1258    rldicl r4,r5,0,32            /* r4 = r5 & 0x00000000ffffffff */
1259    rldicl r3,r5,32,32           /* r3 = (r5 >> 32) & 0x00000000ffffffff */
1260
1261    /* We are now done with 64-bit registers it is safe to touch
1262     * the stack again.
1263     */
1264    stw    r6,0(r30)             /* Save returned data */
1265    stw    r7,4(r30)
1266    stw    r8,8(r30)
1267    stw    r9,12(r30)
1268
1269    lwz    r22,24(r1)
1270    lwz    r23,28(r1)
1271    lwz    r24,32(r1)
1272    lwz    r25,36(r1)
1273    lwz    r26,40(r1)
1274    lwz    r27,44(r1)
1275    lwz    r28,48(r1)
1276    lwz    r29,52(r1)
1277
1278    /* While we were running in the hypervisor, a decrementer or
1279     * external interrupt may have occured.  If we are about to
1280     * enable here, we must check for these and process them
1281     */
1282
1283    cmpi   0,r31,0               /* check if going to enable */
1284    beq    1f                    /* skip checks if staying disabled */
1285
1286    /* Save r3, r4 and LR */
1287    stw    r3,48(r1)
1288    stw    r4,44(r1)
1289    mflr   r3
1290    stw    r3,40(r1)
1291
1292    /* enable and check for decrementers/lpEvents */
1293    mr     r3,r31
1294    bl   __restore_flags
1295
1296    lwz    r3,40(r1)
1297    mtlr   r3
1298    lwz    r3,48(r1)
1299    lwz    r4,44(r1)
1300    
1301 1:
1302    /* 
1303     * Unstack the frame and restore r30, r31 and CR
1304     */
1305    lwz    r31,20(r1)
1306    mtcrf  0xff,r31 
1307    lwz    r30,56(r1)
1308    lwz    r31,60(r1)
1309    lwz    r1,0(r1)
1310    
1311    blr 
1312
1313
1314 /* Hypervisor call (use no stack)
1315  *
1316  * These functions must be called with interrupts soft disabled.
1317  * The caller is responsible for saving the non-volatile CR
1318  * The operands should already be formatted into the 64-bit registers
1319  *
1320  * Invoke the iSeries hypervisor (PLIC) via the System Call instruction.
1321  * 
1322  * r3 contains the HV function to be called
1323  * r4 contains the first 64-bit operand
1324  * r5 contains the second 64-bit operand
1325  * r6 contains the third 64-bit operand
1326  * r7 contains the fourth 64-bit operand
1327  * r8 contains the fifth 64-bit operand
1328  * r9 contains the sixth 64-bit operand
1329  * r10 contains the seventh 64-bit operand
1330  *
1331  * data is returned in 64-bit registers r3-r6
1332  *
1333  */
1334
1335 _GLOBAL(HvXCall) 
1336 _GLOBAL(HvXCall0)
1337 _GLOBAL(HvXCall1)
1338 _GLOBAL(HvXCall2)
1339 _GLOBAL(HvXCall3)
1340    /* 
1341     * Extract the hypervisor function call number from R3
1342     * and format it into the 64-bit R3.
1343     */
1344    rldicr r0,r3,32,15           /* r0 = (r3 << 32) & 0xffff000000000000 */
1345    rldicl r3,r3,0,48            /* r3 = r3 & 0x000000000000ffff */
1346    or     r3,r3,r0              /* r3 = r3 | r0                 */
1347    
1348    /*
1349     * r0 = 0xffffffffffffffff indicates a hypervisor call 
1350     */
1351    li     r0,-1                 /* r1 = 0xffffffffffffffff      */
1352    
1353    /* Invoke the hypervisor via the System Call instruction */
1354
1355    sc
1356    
1357    blr 
1358    
1359 _GLOBAL(__setup_cpu_power3)
1360         blr
1361 _GLOBAL(__setup_cpu_power4)
1362         blr
1363 _GLOBAL(__setup_cpu_generic)
1364         blr
1365
1366 _GLOBAL(iSeries_check_intr)
1367         mflr    r31
1368         lwz     r5,_SOFTE(r1)
1369         cmpi    0,r5,0  
1370         beqlr
1371         mfspr   r5,SPRG1
1372         lbz     r5,PACAPROCENABLED(r5)
1373         cmpi    0,r5,0  
1374         bnelr
1375         /* Check for lost decrementer interrupts.
1376          * (If decrementer popped while we were in the hypervisor)
1377          * (calls timer_interrupt if so)
1378          */
1379 3: CHECKDECR(r4,r5)
1380         /* Check for pending interrupts.  If no interrupts pending,
1381          * then CR0 = "eq" and r4 == 0 
1382          * (kills registers r5 and r6) 
1383          */
1384         beq+    1f
1385         addi    r3,r1,STACK_FRAME_OVERHEAD
1386         bl      timer_interrupt
1387 1:
1388         CHECKLPQUEUE(r4,r5,r6)  
1389         beq+    2f
1390         addi    r3,r1,STACK_FRAME_OVERHEAD
1391         bl      do_IRQ  
1392         b       3b  
1393
1394 2:      mtlr    r31
1395         blr
1396
1397 /*
1398  * Fake an interrupt from kernel mode.
1399  * This is used when enable_irq loses an interrupt.
1400  * We only fill in the stack frame minimally.
1401  */
1402 _GLOBAL(fake_interrupt)
1403         mflr    r0
1404         stw     r0,4(r1)
1405         stwu    r1,-INT_FRAME_SIZE(r1)
1406         stw     r0,_NIP(r1)
1407         stw     r0,_LINK(r1)
1408         mfmsr   r3
1409         stw     r3,_MSR(r1)
1410         li      r0,0x0fac
1411         stw     r0,TRAP(r1)
1412         addi    r3,r1,STACK_FRAME_OVERHEAD
1413         li      r4,1
1414         bl      do_IRQ
1415         addi    r1,r1,INT_FRAME_SIZE
1416         lwz     r0,4(r1)
1417
1418         mtlr    r0
1419         blr
1420
1421 /*
1422  * Fake a decrementer from kernel mode.
1423  * This is used when the decrementer pops in
1424  * the hypervisor.  We only fill in the stack
1425  * frame minimally
1426  */
1427 _GLOBAL(fake_decrementer)
1428         mflr    r0
1429         stw     r0,4(r1)
1430         stwu    r1,-INT_FRAME_SIZE(r1)
1431         stw     r0,_NIP(r1)
1432         stw     r0,_LINK(r1)
1433         mfmsr   r3
1434         stw     r3,_MSR(r1)
1435         li      r0,0x0fac
1436         stw     r0,TRAP(r1)
1437         addi    r3,r1,STACK_FRAME_OVERHEAD
1438         bl      timer_interrupt
1439         addi    r1,r1,INT_FRAME_SIZE
1440         lwz     r0,4(r1)
1441
1442         mtlr    r0
1443         blr
1444
1445 _GLOBAL(create_hpte)
1446         stwu    r1,-INT_FRAME_SIZE(r1)
1447         stw     r0,GPR0(r1)
1448         lwz     r0,0(r1)
1449         stw     r0,GPR1(r1)
1450         /* r3-r13 are caller saved  */
1451         stw     r2,GPR2(r1)
1452         SAVE_8GPRS(4, r1)
1453         SAVE_2GPRS(12, r1)
1454         SAVE_4GPRS(20,r1)
1455         mfspr   r20,XER
1456         mfctr   r22
1457         stw     r20,_XER(r1)
1458         stw     r22,_CTR(r1)
1459         mflr    r20             
1460         mfmsr   r22
1461         stw     r20,_NIP(r1)
1462         stw     r22,_MSR(r1)
1463         stw     r20,_LINK(r1)
1464         bl      iSeries_create_hpte
1465         lwz     r0,GPR0(r1)
1466         lwz     r2,GPR2(r1)
1467         REST_8GPRS(4, r1)
1468         REST_2GPRS(12, r1)
1469         lwz     r20,_NIP(r1)    
1470         lwz     r22,_XER(r1)
1471         mtlr    r20
1472         mtspr   XER,r22
1473         lwz     r20,_CTR(r1)
1474         mtctr   r20
1475         
1476         REST_4GPRS(20,r1)
1477         addi    r1,r1,INT_FRAME_SIZE
1478         blr
1479
1480 ###
1481 ### extern void abort(void)
1482 ###
1483 ### Invoke the hypervisor to kill the partition.          
1484 ### 
1485         
1486 _GLOBAL(abort)
1487
1488
1489 /*
1490  * We put a few things here that have to be page-aligned.
1491  * This stuff goes at the beginning of the data segment,
1492  * which is page-aligned.
1493  */
1494         .data
1495         .globl  sdata
1496 sdata:
1497
1498         .globl  empty_zero_page
1499 empty_zero_page:
1500         .space  4096
1501
1502         .globl  swapper_pg_dir
1503 swapper_pg_dir:
1504         .space  4096    
1505
1506 /*
1507  * This space gets a copy of optional info passed to us by the bootstrap
1508  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
1509  */     
1510         .globl  cmd_line
1511 cmd_line:
1512         .space  512