[PATCH] powerpc: Fix handling of fpscr on 64-bit
[linux-2.6] / arch / ppc / kernel / misc.S
1 /*
2  * This file contains miscellaneous low-level functions.
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6  * and Paul Mackerras.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version
11  * 2 of the License, or (at your option) any later version.
12  *
13  */
14
15 #include <linux/config.h>
16 #include <linux/sys.h>
17 #include <asm/unistd.h>
18 #include <asm/errno.h>
19 #include <asm/processor.h>
20 #include <asm/page.h>
21 #include <asm/cache.h>
22 #include <asm/cputable.h>
23 #include <asm/mmu.h>
24 #include <asm/ppc_asm.h>
25 #include <asm/thread_info.h>
26 #include <asm/asm-offsets.h>
27
28         .text
29
30         .align  5
31 _GLOBAL(__delay)
32         cmpwi   0,r3,0
33         mtctr   r3
34         beqlr
35 1:      bdnz    1b
36         blr
37
38 /*
39  * Returns (address we're running at) - (address we were linked at)
40  * for use before the text and data are mapped to KERNELBASE.
41  */
42 _GLOBAL(reloc_offset)
43         mflr    r0
44         bl      1f
45 1:      mflr    r3
46         lis     r4,1b@ha
47         addi    r4,r4,1b@l
48         subf    r3,r4,r3
49         mtlr    r0
50         blr
51
52 /*
53  * add_reloc_offset(x) returns x + reloc_offset().
54  */
55 _GLOBAL(add_reloc_offset)
56         mflr    r0
57         bl      1f
58 1:      mflr    r5
59         lis     r4,1b@ha
60         addi    r4,r4,1b@l
61         subf    r5,r4,r5
62         add     r3,r3,r5
63         mtlr    r0
64         blr
65
66 /*
67  * sub_reloc_offset(x) returns x - reloc_offset().
68  */
69 _GLOBAL(sub_reloc_offset)
70         mflr    r0
71         bl      1f
72 1:      mflr    r5
73         lis     r4,1b@ha
74         addi    r4,r4,1b@l
75         subf    r5,r4,r5
76         subf    r3,r5,r3
77         mtlr    r0
78         blr
79
80 /*
81  * reloc_got2 runs through the .got2 section adding an offset
82  * to each entry.
83  */
84 _GLOBAL(reloc_got2)
85         mflr    r11
86         lis     r7,__got2_start@ha
87         addi    r7,r7,__got2_start@l
88         lis     r8,__got2_end@ha
89         addi    r8,r8,__got2_end@l
90         subf    r8,r7,r8
91         srwi.   r8,r8,2
92         beqlr
93         mtctr   r8
94         bl      1f
95 1:      mflr    r0
96         lis     r4,1b@ha
97         addi    r4,r4,1b@l
98         subf    r0,r4,r0
99         add     r7,r0,r7
100 2:      lwz     r0,0(r7)
101         add     r0,r0,r3
102         stw     r0,0(r7)
103         addi    r7,r7,4
104         bdnz    2b
105         mtlr    r11
106         blr
107
108 /*
109  * identify_cpu,
110  * called with r3 = data offset and r4 = CPU number
111  * doesn't change r3
112  */
113 _GLOBAL(identify_cpu)
114         addis   r8,r3,cpu_specs@ha
115         addi    r8,r8,cpu_specs@l
116         mfpvr   r7
117 1:
118         lwz     r5,CPU_SPEC_PVR_MASK(r8)
119         and     r5,r5,r7
120         lwz     r6,CPU_SPEC_PVR_VALUE(r8)
121         cmplw   0,r6,r5
122         beq     1f
123         addi    r8,r8,CPU_SPEC_ENTRY_SIZE
124         b       1b
125 1:
126         addis   r6,r3,cur_cpu_spec@ha
127         addi    r6,r6,cur_cpu_spec@l
128         sub     r8,r8,r3
129         stw     r8,0(r6)
130         blr
131
132 /*
133  * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
134  * and writes nop's over sections of code that don't apply for this cpu.
135  * r3 = data offset (not changed)
136  */
137 _GLOBAL(do_cpu_ftr_fixups)
138         /* Get CPU 0 features */
139         addis   r6,r3,cur_cpu_spec@ha
140         addi    r6,r6,cur_cpu_spec@l
141         lwz     r4,0(r6)
142         add     r4,r4,r3
143         lwz     r4,CPU_SPEC_FEATURES(r4)
144
145         /* Get the fixup table */
146         addis   r6,r3,__start___ftr_fixup@ha
147         addi    r6,r6,__start___ftr_fixup@l
148         addis   r7,r3,__stop___ftr_fixup@ha
149         addi    r7,r7,__stop___ftr_fixup@l
150
151         /* Do the fixup */
152 1:      cmplw   0,r6,r7
153         bgelr
154         addi    r6,r6,16
155         lwz     r8,-16(r6)      /* mask */
156         and     r8,r8,r4
157         lwz     r9,-12(r6)      /* value */
158         cmplw   0,r8,r9
159         beq     1b
160         lwz     r8,-8(r6)       /* section begin */
161         lwz     r9,-4(r6)       /* section end */
162         subf.   r9,r8,r9
163         beq     1b
164         /* write nops over the section of code */
165         /* todo: if large section, add a branch at the start of it */
166         srwi    r9,r9,2
167         mtctr   r9
168         add     r8,r8,r3
169         lis     r0,0x60000000@h /* nop */
170 3:      stw     r0,0(r8)
171         andi.   r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
172         beq     2f
173         dcbst   0,r8            /* suboptimal, but simpler */
174         sync
175         icbi    0,r8
176 2:      addi    r8,r8,4
177         bdnz    3b
178         sync                    /* additional sync needed on g4 */
179         isync
180         b       1b
181
182 /*
183  * call_setup_cpu - call the setup_cpu function for this cpu
184  * r3 = data offset, r24 = cpu number
185  *
186  * Setup function is called with:
187  *   r3 = data offset
188  *   r4 = ptr to CPU spec (relocated)
189  */
190 _GLOBAL(call_setup_cpu)
191         addis   r4,r3,cur_cpu_spec@ha
192         addi    r4,r4,cur_cpu_spec@l
193         lwz     r4,0(r4)
194         add     r4,r4,r3
195         lwz     r5,CPU_SPEC_SETUP(r4)
196         cmpi    0,r5,0
197         add     r5,r5,r3
198         beqlr
199         mtctr   r5
200         bctr
201
202 #if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
203
204 /* This gets called by via-pmu.c to switch the PLL selection
205  * on 750fx CPU. This function should really be moved to some
206  * other place (as most of the cpufreq code in via-pmu
207  */
208 _GLOBAL(low_choose_750fx_pll)
209         /* Clear MSR:EE */
210         mfmsr   r7
211         rlwinm  r0,r7,0,17,15
212         mtmsr   r0
213
214         /* If switching to PLL1, disable HID0:BTIC */
215         cmplwi  cr0,r3,0
216         beq     1f
217         mfspr   r5,SPRN_HID0
218         rlwinm  r5,r5,0,27,25
219         sync
220         mtspr   SPRN_HID0,r5
221         isync
222         sync
223
224 1:
225         /* Calc new HID1 value */
226         mfspr   r4,SPRN_HID1    /* Build a HID1:PS bit from parameter */
227         rlwinm  r5,r3,16,15,15  /* Clear out HID1:PS from value read */
228         rlwinm  r4,r4,0,16,14   /* Could have I used rlwimi here ? */
229         or      r4,r4,r5
230         mtspr   SPRN_HID1,r4
231
232         /* Store new HID1 image */
233         rlwinm  r6,r1,0,0,18
234         lwz     r6,TI_CPU(r6)
235         slwi    r6,r6,2
236         addis   r6,r6,nap_save_hid1@ha
237         stw     r4,nap_save_hid1@l(r6)
238
239         /* If switching to PLL0, enable HID0:BTIC */
240         cmplwi  cr0,r3,0
241         bne     1f
242         mfspr   r5,SPRN_HID0
243         ori     r5,r5,HID0_BTIC
244         sync
245         mtspr   SPRN_HID0,r5
246         isync
247         sync
248
249 1:
250         /* Return */
251         mtmsr   r7
252         blr
253
254 _GLOBAL(low_choose_7447a_dfs)
255         /* Clear MSR:EE */
256         mfmsr   r7
257         rlwinm  r0,r7,0,17,15
258         mtmsr   r0
259         
260         /* Calc new HID1 value */
261         mfspr   r4,SPRN_HID1
262         insrwi  r4,r3,1,9       /* insert parameter into bit 9 */
263         sync
264         mtspr   SPRN_HID1,r4
265         sync
266         isync
267
268         /* Return */
269         mtmsr   r7
270         blr
271
272 #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
273
274 /*
275  * complement mask on the msr then "or" some values on.
276  *     _nmask_and_or_msr(nmask, value_to_or)
277  */
278 _GLOBAL(_nmask_and_or_msr)
279         mfmsr   r0              /* Get current msr */
280         andc    r0,r0,r3        /* And off the bits set in r3 (first parm) */
281         or      r0,r0,r4        /* Or on the bits in r4 (second parm) */
282         SYNC                    /* Some chip revs have problems here... */
283         mtmsr   r0              /* Update machine state */
284         isync
285         blr                     /* Done */
286
287
288 /*
289  * Flush MMU TLB
290  */
291 _GLOBAL(_tlbia)
292 #if defined(CONFIG_40x)
293         sync                    /* Flush to memory before changing mapping */
294         tlbia
295         isync                   /* Flush shadow TLB */
296 #elif defined(CONFIG_44x)
297         li      r3,0
298         sync
299
300         /* Load high watermark */
301         lis     r4,tlb_44x_hwater@ha
302         lwz     r5,tlb_44x_hwater@l(r4)
303
304 1:      tlbwe   r3,r3,PPC44x_TLB_PAGEID
305         addi    r3,r3,1
306         cmpw    0,r3,r5
307         ble     1b
308
309         isync
310 #elif defined(CONFIG_FSL_BOOKE)
311         /* Invalidate all entries in TLB0 */
312         li      r3, 0x04
313         tlbivax 0,3
314         /* Invalidate all entries in TLB1 */
315         li      r3, 0x0c
316         tlbivax 0,3
317         /* Invalidate all entries in TLB2 */
318         li      r3, 0x14
319         tlbivax 0,3
320         /* Invalidate all entries in TLB3 */
321         li      r3, 0x1c
322         tlbivax 0,3
323         msync
324 #ifdef CONFIG_SMP
325         tlbsync
326 #endif /* CONFIG_SMP */
327 #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
328 #if defined(CONFIG_SMP)
329         rlwinm  r8,r1,0,0,18
330         lwz     r8,TI_CPU(r8)
331         oris    r8,r8,10
332         mfmsr   r10
333         SYNC
334         rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
335         rlwinm  r0,r0,0,28,26           /* clear DR */
336         mtmsr   r0
337         SYNC_601
338         isync
339         lis     r9,mmu_hash_lock@h
340         ori     r9,r9,mmu_hash_lock@l
341         tophys(r9,r9)
342 10:     lwarx   r7,0,r9
343         cmpwi   0,r7,0
344         bne-    10b
345         stwcx.  r8,0,r9
346         bne-    10b
347         sync
348         tlbia
349         sync
350         TLBSYNC
351         li      r0,0
352         stw     r0,0(r9)                /* clear mmu_hash_lock */
353         mtmsr   r10
354         SYNC_601
355         isync
356 #else /* CONFIG_SMP */
357         sync
358         tlbia
359         sync
360 #endif /* CONFIG_SMP */
361 #endif /* ! defined(CONFIG_40x) */
362         blr
363
364 /*
365  * Flush MMU TLB for a particular address
366  */
367 _GLOBAL(_tlbie)
368 #if defined(CONFIG_40x)
369         tlbsx.  r3, 0, r3
370         bne     10f
371         sync
372         /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
373          * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
374          * the TLB entry. */
375         tlbwe   r3, r3, TLB_TAG
376         isync
377 10:
378 #elif defined(CONFIG_44x)
379         mfspr   r4,SPRN_MMUCR
380         mfspr   r5,SPRN_PID                     /* Get PID */
381         rlwimi  r4,r5,0,24,31                   /* Set TID */
382         mtspr   SPRN_MMUCR,r4
383
384         tlbsx.  r3, 0, r3
385         bne     10f
386         sync
387         /* There are only 64 TLB entries, so r3 < 64,
388          * which means bit 22, is clear.  Since 22 is
389          * the V bit in the TLB_PAGEID, loading this
390          * value will invalidate the TLB entry.
391          */
392         tlbwe   r3, r3, PPC44x_TLB_PAGEID
393         isync
394 10:
395 #elif defined(CONFIG_FSL_BOOKE)
396         rlwinm  r4, r3, 0, 0, 19
397         ori     r5, r4, 0x08    /* TLBSEL = 1 */
398         ori     r6, r4, 0x10    /* TLBSEL = 2 */
399         ori     r7, r4, 0x18    /* TLBSEL = 3 */
400         tlbivax 0, r4
401         tlbivax 0, r5
402         tlbivax 0, r6
403         tlbivax 0, r7
404         msync
405 #if defined(CONFIG_SMP)
406         tlbsync
407 #endif /* CONFIG_SMP */
408 #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
409 #if defined(CONFIG_SMP)
410         rlwinm  r8,r1,0,0,18
411         lwz     r8,TI_CPU(r8)
412         oris    r8,r8,11
413         mfmsr   r10
414         SYNC
415         rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
416         rlwinm  r0,r0,0,28,26           /* clear DR */
417         mtmsr   r0
418         SYNC_601
419         isync
420         lis     r9,mmu_hash_lock@h
421         ori     r9,r9,mmu_hash_lock@l
422         tophys(r9,r9)
423 10:     lwarx   r7,0,r9
424         cmpwi   0,r7,0
425         bne-    10b
426         stwcx.  r8,0,r9
427         bne-    10b
428         eieio
429         tlbie   r3
430         sync
431         TLBSYNC
432         li      r0,0
433         stw     r0,0(r9)                /* clear mmu_hash_lock */
434         mtmsr   r10
435         SYNC_601
436         isync
437 #else /* CONFIG_SMP */
438         tlbie   r3
439         sync
440 #endif /* CONFIG_SMP */
441 #endif /* ! CONFIG_40x */
442         blr
443
444 /*
445  * Flush instruction cache.
446  * This is a no-op on the 601.
447  */
448 _GLOBAL(flush_instruction_cache)
449 #if defined(CONFIG_8xx)
450         isync
451         lis     r5, IDC_INVALL@h
452         mtspr   SPRN_IC_CST, r5
453 #elif defined(CONFIG_4xx)
454 #ifdef CONFIG_403GCX
455         li      r3, 512
456         mtctr   r3
457         lis     r4, KERNELBASE@h
458 1:      iccci   0, r4
459         addi    r4, r4, 16
460         bdnz    1b
461 #else
462         lis     r3, KERNELBASE@h
463         iccci   0,r3
464 #endif
465 #elif CONFIG_FSL_BOOKE
466 BEGIN_FTR_SECTION
467         mfspr   r3,SPRN_L1CSR0
468         ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
469         /* msync; isync recommended here */
470         mtspr   SPRN_L1CSR0,r3
471         isync
472         blr
473 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
474         mfspr   r3,SPRN_L1CSR1
475         ori     r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
476         mtspr   SPRN_L1CSR1,r3
477 #else
478         mfspr   r3,SPRN_PVR
479         rlwinm  r3,r3,16,16,31
480         cmpwi   0,r3,1
481         beqlr                   /* for 601, do nothing */
482         /* 603/604 processor - use invalidate-all bit in HID0 */
483         mfspr   r3,SPRN_HID0
484         ori     r3,r3,HID0_ICFI
485         mtspr   SPRN_HID0,r3
486 #endif /* CONFIG_8xx/4xx */
487         isync
488         blr
489
490 /*
491  * Write any modified data cache blocks out to memory
492  * and invalidate the corresponding instruction cache blocks.
493  * This is a no-op on the 601.
494  *
495  * flush_icache_range(unsigned long start, unsigned long stop)
496  */
497 _GLOBAL(flush_icache_range)
498 BEGIN_FTR_SECTION
499         blr                             /* for 601, do nothing */
500 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
501         li      r5,L1_CACHE_BYTES-1
502         andc    r3,r3,r5
503         subf    r4,r3,r4
504         add     r4,r4,r5
505         srwi.   r4,r4,L1_CACHE_SHIFT
506         beqlr
507         mtctr   r4
508         mr      r6,r3
509 1:      dcbst   0,r3
510         addi    r3,r3,L1_CACHE_BYTES
511         bdnz    1b
512         sync                            /* wait for dcbst's to get to ram */
513         mtctr   r4
514 2:      icbi    0,r6
515         addi    r6,r6,L1_CACHE_BYTES
516         bdnz    2b
517         sync                            /* additional sync needed on g4 */
518         isync
519         blr
520 /*
521  * Write any modified data cache blocks out to memory.
522  * Does not invalidate the corresponding cache lines (especially for
523  * any corresponding instruction cache).
524  *
525  * clean_dcache_range(unsigned long start, unsigned long stop)
526  */
527 _GLOBAL(clean_dcache_range)
528         li      r5,L1_CACHE_BYTES-1
529         andc    r3,r3,r5
530         subf    r4,r3,r4
531         add     r4,r4,r5
532         srwi.   r4,r4,L1_CACHE_SHIFT
533         beqlr
534         mtctr   r4
535
536 1:      dcbst   0,r3
537         addi    r3,r3,L1_CACHE_BYTES
538         bdnz    1b
539         sync                            /* wait for dcbst's to get to ram */
540         blr
541
542 /*
543  * Write any modified data cache blocks out to memory and invalidate them.
544  * Does not invalidate the corresponding instruction cache blocks.
545  *
546  * flush_dcache_range(unsigned long start, unsigned long stop)
547  */
548 _GLOBAL(flush_dcache_range)
549         li      r5,L1_CACHE_BYTES-1
550         andc    r3,r3,r5
551         subf    r4,r3,r4
552         add     r4,r4,r5
553         srwi.   r4,r4,L1_CACHE_SHIFT
554         beqlr
555         mtctr   r4
556
557 1:      dcbf    0,r3
558         addi    r3,r3,L1_CACHE_BYTES
559         bdnz    1b
560         sync                            /* wait for dcbst's to get to ram */
561         blr
562
563 /*
564  * Like above, but invalidate the D-cache.  This is used by the 8xx
565  * to invalidate the cache so the PPC core doesn't get stale data
566  * from the CPM (no cache snooping here :-).
567  *
568  * invalidate_dcache_range(unsigned long start, unsigned long stop)
569  */
570 _GLOBAL(invalidate_dcache_range)
571         li      r5,L1_CACHE_BYTES-1
572         andc    r3,r3,r5
573         subf    r4,r3,r4
574         add     r4,r4,r5
575         srwi.   r4,r4,L1_CACHE_SHIFT
576         beqlr
577         mtctr   r4
578
579 1:      dcbi    0,r3
580         addi    r3,r3,L1_CACHE_BYTES
581         bdnz    1b
582         sync                            /* wait for dcbi's to get to ram */
583         blr
584
585 #ifdef CONFIG_NOT_COHERENT_CACHE
586 /*
587  * 40x cores have 8K or 16K dcache and 32 byte line size.
588  * 44x has a 32K dcache and 32 byte line size.
589  * 8xx has 1, 2, 4, 8K variants.
590  * For now, cover the worst case of the 44x.
591  * Must be called with external interrupts disabled.
592  */
593 #define CACHE_NWAYS     64
594 #define CACHE_NLINES    16
595
596 _GLOBAL(flush_dcache_all)
597         li      r4, (2 * CACHE_NWAYS * CACHE_NLINES)
598         mtctr   r4
599         lis     r5, KERNELBASE@h
600 1:      lwz     r3, 0(r5)               /* Load one word from every line */
601         addi    r5, r5, L1_CACHE_BYTES
602         bdnz    1b
603         blr
604 #endif /* CONFIG_NOT_COHERENT_CACHE */
605
606 /*
607  * Flush a particular page from the data cache to RAM.
608  * Note: this is necessary because the instruction cache does *not*
609  * snoop from the data cache.
610  * This is a no-op on the 601 which has a unified cache.
611  *
612  *      void __flush_dcache_icache(void *page)
613  */
614 _GLOBAL(__flush_dcache_icache)
615 BEGIN_FTR_SECTION
616         blr                                     /* for 601, do nothing */
617 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
618         rlwinm  r3,r3,0,0,19                    /* Get page base address */
619         li      r4,4096/L1_CACHE_BYTES  /* Number of lines in a page */
620         mtctr   r4
621         mr      r6,r3
622 0:      dcbst   0,r3                            /* Write line to ram */
623         addi    r3,r3,L1_CACHE_BYTES
624         bdnz    0b
625         sync
626         mtctr   r4
627 1:      icbi    0,r6
628         addi    r6,r6,L1_CACHE_BYTES
629         bdnz    1b
630         sync
631         isync
632         blr
633
634 /*
635  * Flush a particular page from the data cache to RAM, identified
636  * by its physical address.  We turn off the MMU so we can just use
637  * the physical address (this may be a highmem page without a kernel
638  * mapping).
639  *
640  *      void __flush_dcache_icache_phys(unsigned long physaddr)
641  */
642 _GLOBAL(__flush_dcache_icache_phys)
643 BEGIN_FTR_SECTION
644         blr                                     /* for 601, do nothing */
645 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
646         mfmsr   r10
647         rlwinm  r0,r10,0,28,26                  /* clear DR */
648         mtmsr   r0
649         isync
650         rlwinm  r3,r3,0,0,19                    /* Get page base address */
651         li      r4,4096/L1_CACHE_BYTES  /* Number of lines in a page */
652         mtctr   r4
653         mr      r6,r3
654 0:      dcbst   0,r3                            /* Write line to ram */
655         addi    r3,r3,L1_CACHE_BYTES
656         bdnz    0b
657         sync
658         mtctr   r4
659 1:      icbi    0,r6
660         addi    r6,r6,L1_CACHE_BYTES
661         bdnz    1b
662         sync
663         mtmsr   r10                             /* restore DR */
664         isync
665         blr
666
667 /*
668  * Clear pages using the dcbz instruction, which doesn't cause any
669  * memory traffic (except to write out any cache lines which get
670  * displaced).  This only works on cacheable memory.
671  *
672  * void clear_pages(void *page, int order) ;
673  */
674 _GLOBAL(clear_pages)
675         li      r0,4096/L1_CACHE_BYTES
676         slw     r0,r0,r4
677         mtctr   r0
678 #ifdef CONFIG_8xx
679         li      r4, 0
680 1:      stw     r4, 0(r3)
681         stw     r4, 4(r3)
682         stw     r4, 8(r3)
683         stw     r4, 12(r3)
684 #else
685 1:      dcbz    0,r3
686 #endif
687         addi    r3,r3,L1_CACHE_BYTES
688         bdnz    1b
689         blr
690
691 /*
692  * Copy a whole page.  We use the dcbz instruction on the destination
693  * to reduce memory traffic (it eliminates the unnecessary reads of
694  * the destination into cache).  This requires that the destination
695  * is cacheable.
696  */
697 #define COPY_16_BYTES           \
698         lwz     r6,4(r4);       \
699         lwz     r7,8(r4);       \
700         lwz     r8,12(r4);      \
701         lwzu    r9,16(r4);      \
702         stw     r6,4(r3);       \
703         stw     r7,8(r3);       \
704         stw     r8,12(r3);      \
705         stwu    r9,16(r3)
706
707 _GLOBAL(copy_page)
708         addi    r3,r3,-4
709         addi    r4,r4,-4
710
711 #ifdef CONFIG_8xx
712         /* don't use prefetch on 8xx */
713         li      r0,4096/L1_CACHE_BYTES
714         mtctr   r0
715 1:      COPY_16_BYTES
716         bdnz    1b
717         blr
718
719 #else   /* not 8xx, we can prefetch */
720         li      r5,4
721
722 #if MAX_COPY_PREFETCH > 1
723         li      r0,MAX_COPY_PREFETCH
724         li      r11,4
725         mtctr   r0
726 11:     dcbt    r11,r4
727         addi    r11,r11,L1_CACHE_BYTES
728         bdnz    11b
729 #else /* MAX_COPY_PREFETCH == 1 */
730         dcbt    r5,r4
731         li      r11,L1_CACHE_BYTES+4
732 #endif /* MAX_COPY_PREFETCH */
733         li      r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
734         crclr   4*cr0+eq
735 2:
736         mtctr   r0
737 1:
738         dcbt    r11,r4
739         dcbz    r5,r3
740         COPY_16_BYTES
741 #if L1_CACHE_BYTES >= 32
742         COPY_16_BYTES
743 #if L1_CACHE_BYTES >= 64
744         COPY_16_BYTES
745         COPY_16_BYTES
746 #if L1_CACHE_BYTES >= 128
747         COPY_16_BYTES
748         COPY_16_BYTES
749         COPY_16_BYTES
750         COPY_16_BYTES
751 #endif
752 #endif
753 #endif
754         bdnz    1b
755         beqlr
756         crnot   4*cr0+eq,4*cr0+eq
757         li      r0,MAX_COPY_PREFETCH
758         li      r11,4
759         b       2b
760 #endif  /* CONFIG_8xx */
761
762 /*
763  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
764  * void atomic_set_mask(atomic_t mask, atomic_t *addr);
765  */
766 _GLOBAL(atomic_clear_mask)
767 10:     lwarx   r5,0,r4
768         andc    r5,r5,r3
769         PPC405_ERR77(0,r4)
770         stwcx.  r5,0,r4
771         bne-    10b
772         blr
773 _GLOBAL(atomic_set_mask)
774 10:     lwarx   r5,0,r4
775         or      r5,r5,r3
776         PPC405_ERR77(0,r4)
777         stwcx.  r5,0,r4
778         bne-    10b
779         blr
780
781 /*
782  * I/O string operations
783  *
784  * insb(port, buf, len)
785  * outsb(port, buf, len)
786  * insw(port, buf, len)
787  * outsw(port, buf, len)
788  * insl(port, buf, len)
789  * outsl(port, buf, len)
790  * insw_ns(port, buf, len)
791  * outsw_ns(port, buf, len)
792  * insl_ns(port, buf, len)
793  * outsl_ns(port, buf, len)
794  *
795  * The *_ns versions don't do byte-swapping.
796  */
797 _GLOBAL(_insb)
798         cmpwi   0,r5,0
799         mtctr   r5
800         subi    r4,r4,1
801         blelr-
802 00:     lbz     r5,0(r3)
803         eieio
804         stbu    r5,1(r4)
805         bdnz    00b
806         blr
807
808 _GLOBAL(_outsb)
809         cmpwi   0,r5,0
810         mtctr   r5
811         subi    r4,r4,1
812         blelr-
813 00:     lbzu    r5,1(r4)
814         stb     r5,0(r3)
815         eieio
816         bdnz    00b
817         blr
818
819 _GLOBAL(_insw)
820         cmpwi   0,r5,0
821         mtctr   r5
822         subi    r4,r4,2
823         blelr-
824 00:     lhbrx   r5,0,r3
825         eieio
826         sthu    r5,2(r4)
827         bdnz    00b
828         blr
829
830 _GLOBAL(_outsw)
831         cmpwi   0,r5,0
832         mtctr   r5
833         subi    r4,r4,2
834         blelr-
835 00:     lhzu    r5,2(r4)
836         eieio
837         sthbrx  r5,0,r3
838         bdnz    00b
839         blr
840
841 _GLOBAL(_insl)
842         cmpwi   0,r5,0
843         mtctr   r5
844         subi    r4,r4,4
845         blelr-
846 00:     lwbrx   r5,0,r3
847         eieio
848         stwu    r5,4(r4)
849         bdnz    00b
850         blr
851
852 _GLOBAL(_outsl)
853         cmpwi   0,r5,0
854         mtctr   r5
855         subi    r4,r4,4
856         blelr-
857 00:     lwzu    r5,4(r4)
858         stwbrx  r5,0,r3
859         eieio
860         bdnz    00b
861         blr
862
863 _GLOBAL(__ide_mm_insw)
864 _GLOBAL(_insw_ns)
865         cmpwi   0,r5,0
866         mtctr   r5
867         subi    r4,r4,2
868         blelr-
869 00:     lhz     r5,0(r3)
870         eieio
871         sthu    r5,2(r4)
872         bdnz    00b
873         blr
874
875 _GLOBAL(__ide_mm_outsw)
876 _GLOBAL(_outsw_ns)
877         cmpwi   0,r5,0
878         mtctr   r5
879         subi    r4,r4,2
880         blelr-
881 00:     lhzu    r5,2(r4)
882         sth     r5,0(r3)
883         eieio
884         bdnz    00b
885         blr
886
887 _GLOBAL(__ide_mm_insl)
888 _GLOBAL(_insl_ns)
889         cmpwi   0,r5,0
890         mtctr   r5
891         subi    r4,r4,4
892         blelr-
893 00:     lwz     r5,0(r3)
894         eieio
895         stwu    r5,4(r4)
896         bdnz    00b
897         blr
898
899 _GLOBAL(__ide_mm_outsl)
900 _GLOBAL(_outsl_ns)
901         cmpwi   0,r5,0
902         mtctr   r5
903         subi    r4,r4,4
904         blelr-
905 00:     lwzu    r5,4(r4)
906         stw     r5,0(r3)
907         eieio
908         bdnz    00b
909         blr
910
911 /*
912  * Extended precision shifts.
913  *
914  * Updated to be valid for shift counts from 0 to 63 inclusive.
915  * -- Gabriel
916  *
917  * R3/R4 has 64 bit value
918  * R5    has shift count
919  * result in R3/R4
920  *
921  *  ashrdi3: arithmetic right shift (sign propagation)  
922  *  lshrdi3: logical right shift
923  *  ashldi3: left shift
924  */
925 _GLOBAL(__ashrdi3)
926         subfic  r6,r5,32
927         srw     r4,r4,r5        # LSW = count > 31 ? 0 : LSW >> count
928         addi    r7,r5,32        # could be xori, or addi with -32
929         slw     r6,r3,r6        # t1 = count > 31 ? 0 : MSW << (32-count)
930         rlwinm  r8,r7,0,32      # t3 = (count < 32) ? 32 : 0
931         sraw    r7,r3,r7        # t2 = MSW >> (count-32)
932         or      r4,r4,r6        # LSW |= t1
933         slw     r7,r7,r8        # t2 = (count < 32) ? 0 : t2
934         sraw    r3,r3,r5        # MSW = MSW >> count
935         or      r4,r4,r7        # LSW |= t2
936         blr
937
938 _GLOBAL(__ashldi3)
939         subfic  r6,r5,32
940         slw     r3,r3,r5        # MSW = count > 31 ? 0 : MSW << count
941         addi    r7,r5,32        # could be xori, or addi with -32
942         srw     r6,r4,r6        # t1 = count > 31 ? 0 : LSW >> (32-count)
943         slw     r7,r4,r7        # t2 = count < 32 ? 0 : LSW << (count-32)
944         or      r3,r3,r6        # MSW |= t1
945         slw     r4,r4,r5        # LSW = LSW << count
946         or      r3,r3,r7        # MSW |= t2
947         blr
948
949 _GLOBAL(__lshrdi3)
950         subfic  r6,r5,32
951         srw     r4,r4,r5        # LSW = count > 31 ? 0 : LSW >> count
952         addi    r7,r5,32        # could be xori, or addi with -32
953         slw     r6,r3,r6        # t1 = count > 31 ? 0 : MSW << (32-count)
954         srw     r7,r3,r7        # t2 = count < 32 ? 0 : MSW >> (count-32)
955         or      r4,r4,r6        # LSW |= t1
956         srw     r3,r3,r5        # MSW = MSW >> count
957         or      r4,r4,r7        # LSW |= t2
958         blr
959
960 _GLOBAL(abs)
961         srawi   r4,r3,31
962         xor     r3,r3,r4
963         sub     r3,r3,r4
964         blr
965
966 _GLOBAL(_get_SP)
967         mr      r3,r1           /* Close enough */
968         blr
969
970 /*
971  * Create a kernel thread
972  *   kernel_thread(fn, arg, flags)
973  */
974 _GLOBAL(kernel_thread)
975         stwu    r1,-16(r1)
976         stw     r30,8(r1)
977         stw     r31,12(r1)
978         mr      r30,r3          /* function */
979         mr      r31,r4          /* argument */
980         ori     r3,r5,CLONE_VM  /* flags */
981         oris    r3,r3,CLONE_UNTRACED>>16
982         li      r4,0            /* new sp (unused) */
983         li      r0,__NR_clone
984         sc
985         cmpwi   0,r3,0          /* parent or child? */
986         bne     1f              /* return if parent */
987         li      r0,0            /* make top-level stack frame */
988         stwu    r0,-16(r1)
989         mtlr    r30             /* fn addr in lr */
990         mr      r3,r31          /* load arg and call fn */
991         PPC440EP_ERR42
992         blrl
993         li      r0,__NR_exit    /* exit if function returns */
994         li      r3,0
995         sc
996 1:      lwz     r30,8(r1)
997         lwz     r31,12(r1)
998         addi    r1,r1,16
999         blr
1000
1001 /*
1002  * This routine is just here to keep GCC happy - sigh...
1003  */
1004 _GLOBAL(__main)
1005         blr
1006
1007 #define SYSCALL(name) \
1008 _GLOBAL(name) \
1009         li      r0,__NR_##name; \
1010         sc; \
1011         bnslr; \
1012         lis     r4,errno@ha; \
1013         stw     r3,errno@l(r4); \
1014         li      r3,-1; \
1015         blr
1016
1017 SYSCALL(execve)
1018
1019 /* Why isn't this a) automatic, b) written in 'C'? */
1020         .data
1021         .align 4
1022 _GLOBAL(sys_call_table)
1023         .long sys_restart_syscall /* 0 */
1024         .long sys_exit
1025         .long ppc_fork
1026         .long sys_read
1027         .long sys_write
1028         .long sys_open          /* 5 */
1029         .long sys_close
1030         .long sys_waitpid
1031         .long sys_creat
1032         .long sys_link
1033         .long sys_unlink        /* 10 */
1034         .long sys_execve
1035         .long sys_chdir
1036         .long sys_time
1037         .long sys_mknod
1038         .long sys_chmod         /* 15 */
1039         .long sys_lchown
1040         .long sys_ni_syscall                    /* old break syscall holder */
1041         .long sys_stat
1042         .long sys_lseek
1043         .long sys_getpid        /* 20 */
1044         .long sys_mount
1045         .long sys_oldumount
1046         .long sys_setuid
1047         .long sys_getuid
1048         .long sys_stime         /* 25 */
1049         .long sys_ptrace
1050         .long sys_alarm
1051         .long sys_fstat
1052         .long sys_pause
1053         .long sys_utime         /* 30 */
1054         .long sys_ni_syscall                    /* old stty syscall holder */
1055         .long sys_ni_syscall                    /* old gtty syscall holder */
1056         .long sys_access
1057         .long sys_nice
1058         .long sys_ni_syscall    /* 35 */        /* old ftime syscall holder */
1059         .long sys_sync
1060         .long sys_kill
1061         .long sys_rename
1062         .long sys_mkdir
1063         .long sys_rmdir         /* 40 */
1064         .long sys_dup
1065         .long sys_pipe
1066         .long sys_times
1067         .long sys_ni_syscall                    /* old prof syscall holder */
1068         .long sys_brk           /* 45 */
1069         .long sys_setgid
1070         .long sys_getgid
1071         .long sys_signal
1072         .long sys_geteuid
1073         .long sys_getegid       /* 50 */
1074         .long sys_acct
1075         .long sys_umount                        /* recycled never used phys() */
1076         .long sys_ni_syscall                    /* old lock syscall holder */
1077         .long sys_ioctl
1078         .long sys_fcntl         /* 55 */
1079         .long sys_ni_syscall                    /* old mpx syscall holder */
1080         .long sys_setpgid
1081         .long sys_ni_syscall                    /* old ulimit syscall holder */
1082         .long sys_olduname
1083         .long sys_umask         /* 60 */
1084         .long sys_chroot
1085         .long sys_ustat
1086         .long sys_dup2
1087         .long sys_getppid
1088         .long sys_getpgrp       /* 65 */
1089         .long sys_setsid
1090         .long sys_sigaction
1091         .long sys_sgetmask
1092         .long sys_ssetmask
1093         .long sys_setreuid      /* 70 */
1094         .long sys_setregid
1095         .long ppc_sigsuspend
1096         .long sys_sigpending
1097         .long sys_sethostname
1098         .long sys_setrlimit     /* 75 */
1099         .long sys_old_getrlimit
1100         .long sys_getrusage
1101         .long sys_gettimeofday
1102         .long sys_settimeofday
1103         .long sys_getgroups     /* 80 */
1104         .long sys_setgroups
1105         .long ppc_select
1106         .long sys_symlink
1107         .long sys_lstat
1108         .long sys_readlink      /* 85 */
1109         .long sys_uselib
1110         .long sys_swapon
1111         .long sys_reboot
1112         .long old_readdir
1113         .long sys_mmap          /* 90 */
1114         .long sys_munmap
1115         .long sys_truncate
1116         .long sys_ftruncate
1117         .long sys_fchmod
1118         .long sys_fchown        /* 95 */
1119         .long sys_getpriority
1120         .long sys_setpriority
1121         .long sys_ni_syscall                    /* old profil syscall holder */
1122         .long sys_statfs
1123         .long sys_fstatfs       /* 100 */
1124         .long sys_ni_syscall
1125         .long sys_socketcall
1126         .long sys_syslog
1127         .long sys_setitimer
1128         .long sys_getitimer     /* 105 */
1129         .long sys_newstat
1130         .long sys_newlstat
1131         .long sys_newfstat
1132         .long sys_uname
1133         .long sys_ni_syscall    /* 110 */
1134         .long sys_vhangup
1135         .long sys_ni_syscall    /* old 'idle' syscall */
1136         .long sys_ni_syscall
1137         .long sys_wait4
1138         .long sys_swapoff       /* 115 */
1139         .long sys_sysinfo
1140         .long sys_ipc
1141         .long sys_fsync
1142         .long sys_sigreturn
1143         .long ppc_clone         /* 120 */
1144         .long sys_setdomainname
1145         .long sys_newuname
1146         .long sys_ni_syscall
1147         .long sys_adjtimex
1148         .long sys_mprotect      /* 125 */
1149         .long sys_sigprocmask
1150         .long sys_ni_syscall    /* old sys_create_module */
1151         .long sys_init_module
1152         .long sys_delete_module
1153         .long sys_ni_syscall    /* old sys_get_kernel_syms */   /* 130 */
1154         .long sys_quotactl
1155         .long sys_getpgid
1156         .long sys_fchdir
1157         .long sys_bdflush
1158         .long sys_sysfs         /* 135 */
1159         .long sys_personality
1160         .long sys_ni_syscall    /* for afs_syscall */
1161         .long sys_setfsuid
1162         .long sys_setfsgid
1163         .long sys_llseek        /* 140 */
1164         .long sys_getdents
1165         .long ppc_select
1166         .long sys_flock
1167         .long sys_msync
1168         .long sys_readv         /* 145 */
1169         .long sys_writev
1170         .long sys_getsid
1171         .long sys_fdatasync
1172         .long sys_sysctl
1173         .long sys_mlock         /* 150 */
1174         .long sys_munlock
1175         .long sys_mlockall
1176         .long sys_munlockall
1177         .long sys_sched_setparam
1178         .long sys_sched_getparam        /* 155 */
1179         .long sys_sched_setscheduler
1180         .long sys_sched_getscheduler
1181         .long sys_sched_yield
1182         .long sys_sched_get_priority_max
1183         .long sys_sched_get_priority_min  /* 160 */
1184         .long sys_sched_rr_get_interval
1185         .long sys_nanosleep
1186         .long sys_mremap
1187         .long sys_setresuid
1188         .long sys_getresuid     /* 165 */
1189         .long sys_ni_syscall            /* old sys_query_module */
1190         .long sys_poll
1191         .long sys_nfsservctl
1192         .long sys_setresgid
1193         .long sys_getresgid     /* 170 */
1194         .long sys_prctl
1195         .long sys_rt_sigreturn
1196         .long sys_rt_sigaction
1197         .long sys_rt_sigprocmask
1198         .long sys_rt_sigpending /* 175 */
1199         .long sys_rt_sigtimedwait
1200         .long sys_rt_sigqueueinfo
1201         .long ppc_rt_sigsuspend
1202         .long sys_pread64
1203         .long sys_pwrite64      /* 180 */
1204         .long sys_chown
1205         .long sys_getcwd
1206         .long sys_capget
1207         .long sys_capset
1208         .long sys_sigaltstack   /* 185 */
1209         .long sys_sendfile
1210         .long sys_ni_syscall            /* streams1 */
1211         .long sys_ni_syscall            /* streams2 */
1212         .long ppc_vfork
1213         .long sys_getrlimit     /* 190 */
1214         .long sys_readahead
1215         .long sys_mmap2
1216         .long sys_truncate64
1217         .long sys_ftruncate64
1218         .long sys_stat64        /* 195 */
1219         .long sys_lstat64
1220         .long sys_fstat64
1221         .long sys_pciconfig_read
1222         .long sys_pciconfig_write
1223         .long sys_pciconfig_iobase      /* 200 */
1224         .long sys_ni_syscall            /* 201 - reserved - MacOnLinux - new */
1225         .long sys_getdents64
1226         .long sys_pivot_root
1227         .long sys_fcntl64
1228         .long sys_madvise       /* 205 */
1229         .long sys_mincore
1230         .long sys_gettid
1231         .long sys_tkill
1232         .long sys_setxattr
1233         .long sys_lsetxattr     /* 210 */
1234         .long sys_fsetxattr
1235         .long sys_getxattr
1236         .long sys_lgetxattr
1237         .long sys_fgetxattr
1238         .long sys_listxattr     /* 215 */
1239         .long sys_llistxattr
1240         .long sys_flistxattr
1241         .long sys_removexattr
1242         .long sys_lremovexattr
1243         .long sys_fremovexattr  /* 220 */
1244         .long sys_futex
1245         .long sys_sched_setaffinity
1246         .long sys_sched_getaffinity
1247         .long sys_ni_syscall
1248         .long sys_ni_syscall    /* 225 - reserved for Tux */
1249         .long sys_sendfile64
1250         .long sys_io_setup
1251         .long sys_io_destroy
1252         .long sys_io_getevents
1253         .long sys_io_submit     /* 230 */
1254         .long sys_io_cancel
1255         .long sys_set_tid_address
1256         .long sys_fadvise64
1257         .long sys_exit_group
1258         .long sys_lookup_dcookie /* 235 */
1259         .long sys_epoll_create
1260         .long sys_epoll_ctl
1261         .long sys_epoll_wait
1262         .long sys_remap_file_pages
1263         .long sys_timer_create  /* 240 */
1264         .long sys_timer_settime
1265         .long sys_timer_gettime
1266         .long sys_timer_getoverrun
1267         .long sys_timer_delete
1268         .long sys_clock_settime /* 245 */
1269         .long sys_clock_gettime
1270         .long sys_clock_getres
1271         .long sys_clock_nanosleep
1272         .long ppc_swapcontext
1273         .long sys_tgkill        /* 250 */
1274         .long sys_utimes
1275         .long sys_statfs64
1276         .long sys_fstatfs64
1277         .long ppc_fadvise64_64
1278         .long sys_ni_syscall            /* 255 - rtas (used on ppc64) */
1279         .long sys_debug_setcontext
1280         .long sys_ni_syscall            /* 257 reserved for vserver */
1281         .long sys_ni_syscall            /* 258 reserved for new sys_remap_file_pages */
1282         .long sys_ni_syscall            /* 259 reserved for new sys_mbind */
1283         .long sys_ni_syscall            /* 260 reserved for new sys_get_mempolicy */
1284         .long sys_ni_syscall            /* 261 reserved for new sys_set_mempolicy */
1285         .long sys_mq_open
1286         .long sys_mq_unlink
1287         .long sys_mq_timedsend
1288         .long sys_mq_timedreceive       /* 265 */
1289         .long sys_mq_notify
1290         .long sys_mq_getsetattr
1291         .long sys_kexec_load
1292         .long sys_add_key
1293         .long sys_request_key           /* 270 */
1294         .long sys_keyctl
1295         .long sys_waitid
1296         .long sys_ioprio_set
1297         .long sys_ioprio_get
1298         .long sys_inotify_init          /* 275 */
1299         .long sys_inotify_add_watch
1300         .long sys_inotify_rm_watch