Import changeset
[linux-flexiantxendom0-3.2.10.git] / 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 "ppc_asm.h"
23
24 #if defined(CONFIG_4xx) || defined(CONFIG_8xx)
25 #define CACHE_LINE_SIZE         16
26 #define LG_CACHE_LINE_SIZE      4
27 #define MAX_COPY_PREFETCH       1
28 #elif !defined(CONFIG_PPC64BRIDGE)
29 #define CACHE_LINE_SIZE         32
30 #define LG_CACHE_LINE_SIZE      5
31 #define MAX_COPY_PREFETCH       4
32 #else
33 #define CACHE_LINE_SIZE         128
34 #define LG_CACHE_LINE_SIZE      7
35 #define MAX_COPY_PREFETCH       1
36 #endif /* CONFIG_4xx || CONFIG_8xx */
37
38         .text
39
40 /*
41  * Returns (address we're running at) - (address we were linked at)
42  * for use before the text and data are mapped to KERNELBASE.
43  */
44
45 _GLOBAL(reloc_offset)
46         mflr    r0
47         bl      1f
48 1:      mflr    r3
49         lis     r4,1b@ha
50         addi    r4,r4,1b@l
51         subf    r3,r4,r3
52         mtlr    r0
53         blr
54
55 /* void __no_use_save_flags(unsigned long *flags) */
56 _GLOBAL(__no_use_save_flags)
57         mfmsr   r4
58         stw     r4,0(r3)
59         blr
60
61 /* void __no_use_restore_flags(unsigned long flags) */  
62 _GLOBAL(__no_use_restore_flags)
63 /*
64  * Just set/clear the MSR_EE bit through restore/flags but do not
65  * change anything else.  This is needed by the RT system and makes
66  * sense anyway.
67  *    -- Cort
68  */
69         mfmsr   r4
70         /* Copy all except the MSR_EE bit from r4 (current MSR value)
71            to r3.  This is the sort of thing the rlwimi instruction is
72            designed for.  -- paulus. */
73         rlwimi  r3,r4,0,17,15
74          /* Check if things are setup the way we want _already_. */
75         cmpw    0,r3,r4
76         beqlr
77         /* are we enabling interrupts? */
78         rlwinm. r0,r3,0,16,16
79         beq     1f
80         /* if so, check if there are any lost interrupts */
81         lis     r7,ppc_n_lost_interrupts@ha
82         lwz     r7,ppc_n_lost_interrupts@l(r7)
83         cmpi    0,r7,0          /* lost interrupts to process first? */
84         bne-    do_lost_interrupts
85 1:      sync
86         mtmsr   r3
87         isync
88         blr
89         
90 _GLOBAL(__no_use_cli)
91         mfmsr   r0              /* Get current interrupt state */
92         rlwinm  r3,r0,16+1,32-1,31      /* Extract old value of 'EE' */
93         rlwinm  r0,r0,0,17,15   /* clear MSR_EE in r0 */
94         sync                    /* Some chip revs have problems here... */
95         mtmsr   r0              /* Update machine state */
96         blr                     /* Done */
97
98 _GLOBAL(__no_use_sti)
99         lis     r4,ppc_n_lost_interrupts@ha
100         lwz     r4,ppc_n_lost_interrupts@l(r4)
101         mfmsr   r3              /* Get current state */
102         ori     r3,r3,MSR_EE    /* Turn on 'EE' bit */
103         cmpi    0,r4,0          /* lost interrupts to process first? */
104         bne-    do_lost_interrupts
105         sync                    /* Some chip revs have problems here... */
106         mtmsr   r3              /* Update machine state */
107         blr
108
109 /*
110  * We were about to enable interrupts but we have to simulate
111  * some interrupts that were lost by enable_irq first.
112  */
113 _GLOBAL(do_lost_interrupts)
114         stwu    r1,-16(r1)
115         mflr    r0
116         stw     r0,20(r1)
117         stw     r3,8(r1)
118 1:      bl      fake_interrupt
119         lis     r4,ppc_n_lost_interrupts@ha
120         lwz     r4,ppc_n_lost_interrupts@l(r4)
121         cmpi    0,r4,0
122         bne-    1b
123         lwz     r3,8(r1)
124         sync
125         mtmsr   r3
126         lwz     r0,20(r1)
127         mtlr    r0
128         addi    r1,r1,16
129         blr
130
131
132 /*
133  * complement mask on the msr then "or" some values on.
134  *     _nmask_and_or_msr(nmask, value_to_or)
135  */
136         _GLOBAL(_nmask_and_or_msr)
137         mfmsr   r0              /* Get current msr */
138         andc    r0,r0,r3        /* And off the bits set in r3 (first parm) */
139         or      r0,r0,r4                /* Or on the bits in r4 (second parm) */
140         sync                    /* Some chip revs have problems here... */
141         mtmsr   r0              /* Update machine state */
142         blr                     /* Done */
143
144
145 /*
146  * Flush MMU TLB
147  */
148 _GLOBAL(_tlbia)
149 #if defined(CONFIG_SMP)
150         mfmsr   r10
151         sync
152         rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
153         mtmsr   r0
154         SYNC
155         lis     r9,hash_table_lock@h
156         ori     r9,r9,hash_table_lock@l
157         lwz     r8,PROCESSOR(r2)
158         oris    r8,r8,10
159 10:     lwarx   r7,0,r9
160         cmpi    0,r7,0
161         bne-    10b
162         stwcx.  r8,0,r9
163         bne-    10b
164         eieio
165 #endif /* CONFIG_SMP */
166         sync
167         tlbia
168         sync
169 #ifdef CONFIG_SMP
170         tlbsync
171         sync
172         li      r0,0
173         stw     r0,0(r9)                /* clear hash_table_lock */
174         mtmsr   r10
175         SYNC
176 #endif
177         blr     
178
179 /*
180  * Flush MMU TLB for a particular address
181  */
182 _GLOBAL(_tlbie)
183 #if defined(CONFIG_SMP)
184         mfmsr   r10
185         sync
186         rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
187         mtmsr   r0
188         SYNC
189         lis     r9,hash_table_lock@h
190         ori     r9,r9,hash_table_lock@l
191         lwz     r8,PROCESSOR(r2)
192         oris    r8,r8,11
193 10:     lwarx   r7,0,r9
194         cmpi    0,r7,0
195         bne-    10b
196         stwcx.  r8,0,r9
197         bne-    10b
198         eieio
199 #endif /* CONFIG_SMP */
200         tlbie   r3
201         sync
202 #ifdef CONFIG_SMP
203         tlbsync
204         sync
205         li      r0,0
206         stw     r0,0(r9)                /* clear hash_table_lock */
207         mtmsr   r10
208         SYNC
209 #endif
210         blr
211
212 /*
213  * Flush instruction cache.
214  * This is a no-op on the 601.
215  */
216 _GLOBAL(flush_instruction_cache)
217 #ifdef CONFIG_8xx
218         isync
219         lis     r5, IDC_INVALL@h
220         mtspr   IC_CST, r5
221 #else
222         mfspr   r3,PVR
223         rlwinm  r3,r3,16,16,31
224         cmpi    0,r3,1
225         beqlr                   /* for 601, do nothing */
226         /* 603/604 processor - use invalidate-all bit in HID0 */
227         mfspr   r3,HID0
228         ori     r3,r3,HID0_ICFI
229         mtspr   HID0,r3
230 #endif /* CONFIG_8xx */
231         SYNC
232         blr
233
234 /*
235  * Write any modified data cache blocks out to memory
236  * and invalidate the corresponding instruction cache blocks.
237  * This is a no-op on the 601.
238  *
239  * flush_icache_range(unsigned long start, unsigned long stop)
240  */
241 _GLOBAL(flush_icache_range)
242         mfspr   r5,PVR
243         rlwinm  r5,r5,16,16,31
244         cmpi    0,r5,1
245         beqlr                           /* for 601, do nothing */
246         li      r5,CACHE_LINE_SIZE-1
247         andc    r3,r3,r5
248         subf    r4,r3,r4
249         add     r4,r4,r5
250         srwi.   r4,r4,LG_CACHE_LINE_SIZE
251         beqlr
252         mtctr   r4
253         mr      r6,r3
254 1:      dcbst   0,r3
255         addi    r3,r3,CACHE_LINE_SIZE
256         bdnz    1b
257         sync                            /* wait for dcbst's to get to ram */
258         mtctr   r4
259 2:      icbi    0,r6
260         addi    r6,r6,CACHE_LINE_SIZE
261         bdnz    2b
262         sync
263         isync
264         blr
265
266 /*
267  * Like above, but only do the D-cache.
268  *
269  * flush_dcache_range(unsigned long start, unsigned long stop)
270  */
271 _GLOBAL(flush_dcache_range)
272        li      r5,CACHE_LINE_SIZE-1
273        andc    r3,r3,r5
274        subf    r4,r3,r4
275        add     r4,r4,r5
276        srwi.   r4,r4,LG_CACHE_LINE_SIZE
277        beqlr
278        mtctr   r4
279
280 1:     dcbst   0,r3
281        addi    r3,r3,CACHE_LINE_SIZE
282        bdnz    1b
283        sync                            /* wait for dcbst's to get to ram */
284        blr
285
286 /*
287  * Flush a particular page from the data cache to RAM.
288  * Note: this is necessary because the instruction cache does *not*
289  * snoop from the data cache.
290  * This is a no-op on the 601 which has a unified cache.
291  *
292  *      void __flush_page_to_ram(void *page)
293  */
294 _GLOBAL(__flush_page_to_ram)
295         mfspr   r5,PVR
296         rlwinm  r5,r5,16,16,31
297         cmpi    0,r5,1
298         beqlr                           /* for 601, do nothing */
299         rlwinm  r3,r3,0,0,19            /* Get page base address */
300         li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
301         mtctr   r4
302         mr      r6,r3
303 0:      dcbst   0,r3                    /* Write line to ram */
304         addi    r3,r3,CACHE_LINE_SIZE
305         bdnz    0b
306         sync
307         mtctr   r4
308 1:      icbi    0,r6
309         addi    r6,r6,CACHE_LINE_SIZE
310         bdnz    1b
311         sync
312         isync
313         blr
314
315 /*
316  * Flush a particular page from the instruction cache.
317  * Note: this is necessary because the instruction cache does *not*
318  * snoop from the data cache.
319  * This is a no-op on the 601 which has a unified cache.
320  *
321  *      void __flush_icache_page(void *page)
322  */
323 _GLOBAL(__flush_icache_page)
324         mfspr   r5,PVR
325         rlwinm  r5,r5,16,16,31
326         cmpi    0,r5,1
327         beqlr                           /* for 601, do nothing */
328         li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
329         mtctr   r4
330 1:      icbi    0,r3
331         addi    r3,r3,CACHE_LINE_SIZE
332         bdnz    1b
333         sync
334         isync
335         blr
336         
337 /*
338  * Clear a page using the dcbz instruction, which doesn't cause any
339  * memory traffic (except to write out any cache lines which get
340  * displaced).  This only works on cacheable memory.
341  */
342 _GLOBAL(clear_page)
343         li      r0,4096/CACHE_LINE_SIZE
344         mtctr   r0
345 #ifdef CONFIG_8xx
346         li      r4, 0
347 1:      stw     r4, 0(r3)
348         stw     r4, 4(r3)
349         stw     r4, 8(r3)
350         stw     r4, 12(r3)
351 #else
352 1:      dcbz    0,r3
353 #endif
354         addi    r3,r3,CACHE_LINE_SIZE
355         bdnz    1b
356         blr
357
358 /*
359  * Copy a whole page.  We use the dcbz instruction on the destination
360  * to reduce memory traffic (it eliminates the unnecessary reads of
361  * the destination into cache).  This requires that the destination
362  * is cacheable.
363  */
364 #define COPY_16_BYTES           \
365         lwz     r6,4(r4);       \
366         lwz     r7,8(r4);       \
367         lwz     r8,12(r4);      \
368         lwzu    r9,16(r4);      \
369         stw     r6,4(r3);       \
370         stw     r7,8(r3);       \
371         stw     r8,12(r3);      \
372         stwu    r9,16(r3)
373
374 _GLOBAL(copy_page)
375         addi    r3,r3,-4
376         addi    r4,r4,-4
377         li      r5,4
378
379 #ifndef CONFIG_8xx
380 #if MAX_COPY_PREFETCH > 1
381         li      r0,MAX_COPY_PREFETCH
382         li      r11,4
383         mtctr   r0
384 11:     dcbt    r11,r4
385         addi    r11,r11,CACHE_LINE_SIZE
386         bdnz    11b
387 #else /* MAX_COPY_PREFETCH == 1 */
388         dcbt    r5,r4
389         li      r11,CACHE_LINE_SIZE+4
390 #endif /* MAX_COPY_PREFETCH */
391 #endif /* CONFIG_8xx */
392
393         li      r0,4096/CACHE_LINE_SIZE
394         mtctr   r0
395 1:
396 #ifndef CONFIG_8xx
397         dcbt    r11,r4
398         dcbz    r5,r3
399 #endif
400         COPY_16_BYTES
401 #if CACHE_LINE_SIZE >= 32
402         COPY_16_BYTES
403 #if CACHE_LINE_SIZE >= 64
404         COPY_16_BYTES
405         COPY_16_BYTES
406 #if CACHE_LINE_SIZE >= 128
407         COPY_16_BYTES
408         COPY_16_BYTES
409         COPY_16_BYTES
410         COPY_16_BYTES
411 #endif
412 #endif
413 #endif
414         bdnz    1b
415         blr
416
417 /*
418  * Atomic [test&set] exchange
419  *
420  *      unsigned long xchg_u32(void *ptr, unsigned long val)
421  * Changes the memory location '*ptr' to be val and returns
422  * the previous value stored there.
423  */
424 _GLOBAL(xchg_u32)
425         mr      r5,r3           /* Save pointer */
426 10:     lwarx   r3,0,r5         /* Fetch old value & reserve */
427         stwcx.  r4,0,r5         /* Update with new value */
428         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
429         blr
430
431 /*
432  * Try to acquire a spinlock.
433  * Only does the stwcx. if the load returned 0 - the Programming
434  * Environments Manual suggests not doing unnecessary stcwx.'s
435  * since they may inhibit forward progress by other CPUs in getting
436  * a lock.
437  */
438 _GLOBAL(__spin_trylock)
439         mr      r4,r3
440         eieio                   /* prevent reordering of stores */
441         li      r5,-1
442         lwarx   r3,0,r4         /* fetch old value, establish reservation */
443         cmpwi   0,r3,0          /* is it 0? */
444         bnelr-                  /* return failure if not */
445         stwcx.  r5,0,r4         /* try to update with new value */
446         bne-    1f              /* if we failed */
447         eieio                   /* prevent reordering of stores */
448         blr
449 1:      li      r3,1            /* return non-zero for failure */
450         blr
451
452 /*
453  * Atomic add/sub/inc/dec operations
454  *
455  * void atomic_add(int c, int *v)
456  * void atomic_sub(int c, int *v)
457  * void atomic_inc(int *v)
458  * void atomic_dec(int *v)
459  * int atomic_dec_and_test(int *v)
460  * int atomic_inc_return(int *v)
461  * int atomic_dec_return(int *v)
462  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
463  * void atomic_set_mask(atomic_t mask, atomic_t *addr);
464  */
465 #if 0 /* now inline - paulus */
466 _GLOBAL(atomic_add)
467 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
468         add     r5,r5,r3        /* Perform 'add' operation */
469         stwcx.  r5,0,r4         /* Update with new value */
470         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
471         blr
472 _GLOBAL(atomic_add_return)
473 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
474         add     r5,r5,r3        /* Perform 'add' operation */
475         stwcx.  r5,0,r4         /* Update with new value */
476         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
477         mr      r3,r5
478         blr
479 _GLOBAL(atomic_sub)
480 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
481         sub     r5,r5,r3        /* Perform 'add' operation */
482         stwcx.  r5,0,r4         /* Update with new value */
483         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
484         blr
485 _GLOBAL(atomic_inc)
486 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
487         addi    r5,r5,1         /* Perform 'add' operation */
488         stwcx.  r5,0,r3         /* Update with new value */
489         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
490         blr
491 _GLOBAL(atomic_inc_return)
492 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
493         addi    r5,r5,1         /* Perform 'add' operation */
494         stwcx.  r5,0,r3         /* Update with new value */
495         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
496         mr      r3,r5           /* Return new value */
497         blr
498 _GLOBAL(atomic_dec)
499 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
500         subi    r5,r5,1         /* Perform 'add' operation */
501         stwcx.  r5,0,r3         /* Update with new value */
502         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
503         blr
504 _GLOBAL(atomic_dec_return)
505 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
506         subi    r5,r5,1         /* Perform 'add' operation */
507         stwcx.  r5,0,r3         /* Update with new value */
508         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
509         mr      r3,r5           /* Return new value */
510         blr
511 _GLOBAL(atomic_dec_and_test)
512 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
513         subi    r5,r5,1         /* Perform 'add' operation */
514         stwcx.  r5,0,r3         /* Update with new value */
515         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
516         cntlzw  r3,r5
517         srwi    r3,r3,5
518         blr
519 #endif /* 0 */
520 _GLOBAL(atomic_clear_mask)
521 10:     lwarx   r5,0,r4
522         andc    r5,r5,r3
523         stwcx.  r5,0,r4
524         bne-    10b
525         blr
526 _GLOBAL(atomic_set_mask)
527 10:     lwarx   r5,0,r4
528         or      r5,r5,r3
529         stwcx.  r5,0,r4
530         bne-    10b
531         blr
532
533 /*
534  * I/O string operations
535  *
536  * insb(port, buf, len)
537  * outsb(port, buf, len)
538  * insw(port, buf, len)
539  * outsw(port, buf, len)
540  * insl(port, buf, len)
541  * outsl(port, buf, len)
542  * insw_ns(port, buf, len)
543  * outsw_ns(port, buf, len)
544  * insl_ns(port, buf, len)
545  * outsl_ns(port, buf, len)
546  *
547  * The *_ns versions don't do byte-swapping.
548  */
549 _GLOBAL(_insb)
550         cmpwi   0,r5,0
551         mtctr   r5
552         subi    r4,r4,1
553         blelr-
554 00:     lbz     r5,0(r3)
555         eieio
556         stbu    r5,1(r4)
557         bdnz    00b
558         blr
559
560 _GLOBAL(_outsb)
561         cmpwi   0,r5,0
562         mtctr   r5
563         subi    r4,r4,1
564         blelr-
565 00:     lbzu    r5,1(r4)
566         stb     r5,0(r3)
567         eieio
568         bdnz    00b
569         blr     
570
571 _GLOBAL(_insw)
572         cmpwi   0,r5,0
573         mtctr   r5
574         subi    r4,r4,2
575         blelr-
576 00:     lhbrx   r5,0,r3
577         eieio
578         sthu    r5,2(r4)
579         bdnz    00b
580         blr
581
582 _GLOBAL(_outsw)
583         cmpwi   0,r5,0
584         mtctr   r5
585         subi    r4,r4,2
586         blelr-
587 00:     lhzu    r5,2(r4)
588         eieio
589         sthbrx  r5,0,r3 
590         bdnz    00b
591         blr     
592
593 _GLOBAL(_insl)
594         cmpwi   0,r5,0
595         mtctr   r5
596         subi    r4,r4,4
597         blelr-
598 00:     lwbrx   r5,0,r3
599         eieio
600         stwu    r5,4(r4)
601         bdnz    00b
602         blr
603
604 _GLOBAL(_outsl)
605         cmpwi   0,r5,0
606         mtctr   r5
607         subi    r4,r4,4
608         blelr-
609 00:     lwzu    r5,4(r4)
610         stwbrx  r5,0,r3
611         eieio
612         bdnz    00b
613         blr     
614
615 _GLOBAL(ide_insw)
616 _GLOBAL(_insw_ns)
617         cmpwi   0,r5,0
618         mtctr   r5
619         subi    r4,r4,2
620         blelr-
621 00:     lhz     r5,0(r3)
622         eieio
623         sthu    r5,2(r4)
624         bdnz    00b
625         blr
626
627 _GLOBAL(ide_outsw)
628 _GLOBAL(_outsw_ns)
629         cmpwi   0,r5,0
630         mtctr   r5
631         subi    r4,r4,2
632         blelr-
633 00:     lhzu    r5,2(r4)
634         sth     r5,0(r3)
635         eieio
636         bdnz    00b
637         blr     
638
639 _GLOBAL(_insl_ns)
640         cmpwi   0,r5,0
641         mtctr   r5
642         subi    r4,r4,4
643         blelr-
644 00:     lwz     r5,0(r3)
645         eieio
646         stwu    r5,4(r4)
647         bdnz    00b
648         blr
649
650 _GLOBAL(_outsl_ns)
651         cmpwi   0,r5,0
652         mtctr   r5
653         subi    r4,r4,4
654         blelr-
655 00:     lwzu    r5,4(r4)
656         stw     r5,0(r3)
657         eieio
658         bdnz    00b
659         blr     
660
661 /*
662  * Extended precision shifts.
663  * 
664  * Updated to be valid for shift counts from 0 to 63 inclusive.
665  * -- Gabriel
666  *
667  * R3/R4 has 64 bit value
668  * R5    has shift count
669  * result in R3/R4
670  *
671  *  ashrdi3: arithmetic right shift (sign propagation)      
672  *  lshrdi3: logical right shift        
673  *  ashldi3: left shift
674  */
675 _GLOBAL(__ashrdi3)
676         subfic  r6,r5,32        
677         srw     r4,r4,r5        # LSW = count > 31 ? 0 : LSW >> count
678         addi    r7,r5,32        # could be xori, or addi with -32
679         slw     r6,r3,r6        # t1 = count > 31 ? 0 : MSW << (32-count)
680         rlwinm  r8,r7,0,32      # t3 = (count < 32) ? 32 : 0
681         sraw    r7,r3,r7        # t2 = MSW >> (count-32)
682         or      r4,r4,r6        # LSW |= t1
683         slw     r7,r7,r8        # t2 = (count < 32) ? 0 : t2
684         sraw    r3,r3,r5        # MSW = MSW >> count
685         or      r4,r4,r7        # LSW |= t2
686         blr
687
688 _GLOBAL(__ashldi3)
689         subfic  r6,r5,32        
690         slw     r3,r3,r5        # MSW = count > 31 ? 0 : MSW << count
691         addi    r7,r5,32        # could be xori, or addi with -32
692         srw     r6,r4,r6        # t1 = count > 31 ? 0 : LSW >> (32-count)
693         slw     r7,r4,r7        # t2 = count < 32 ? 0 : LSW << (count-32)
694         or      r3,r3,r6        # MSW |= t1
695         slw     r4,r4,r5        # LSW = LSW << count
696         or      r3,r3,r7        # MSW |= t2
697         blr
698
699 _GLOBAL(__lshrdi3)
700         subfic  r6,r5,32        
701         srw     r4,r4,r5        # LSW = count > 31 ? 0 : LSW >> count
702         addi    r7,r5,32        # could be xori, or addi with -32
703         slw     r6,r3,r6        # t1 = count > 31 ? 0 : MSW << (32-count)
704         srw     r7,r3,r7        # t2 = count < 32 ? 0 : MSW >> (count-32)
705         or      r4,r4,r6        # LSW |= t1
706         srw     r3,r3,r5        # MSW = MSW >> count
707         or      r4,r4,r7        # LSW |= t2 
708         blr
709
710 _GLOBAL(abs)
711         srawi   r4,r3,31
712         xor     r3,r3,r4
713         sub     r3,r3,r4
714         blr
715
716 _GLOBAL(_get_SP)
717         mr      r3,r1           /* Close enough */
718         blr
719
720 _GLOBAL(_get_THRM1)
721         mfspr   r3,THRM1
722         blr
723
724 _GLOBAL(_get_THRM2)
725         mfspr   r3,THRM2
726         blr
727
728 _GLOBAL(_get_THRM3)
729         mfspr   r3,THRM3
730         blr
731                 
732 _GLOBAL(_set_THRM1)
733         mtspr   THRM1,r3
734         blr
735
736 _GLOBAL(_set_THRM2)
737         mtspr   THRM2,r3
738         blr
739
740 _GLOBAL(_set_THRM3)
741         mtspr   THRM3,r3
742         blr
743         
744 _GLOBAL(_get_PVR)
745         mfspr   r3,PVR
746         blr
747
748 #ifdef CONFIG_8xx
749 _GLOBAL(_get_IMMR)
750         mfspr   r3, 638
751         blr
752 #endif
753         
754 _GLOBAL(_get_HID0)
755         mfspr   r3,HID0
756         blr
757
758 _GLOBAL(_get_ICTC)
759         mfspr   r3,ICTC
760         blr
761
762 _GLOBAL(_set_ICTC)
763         mtspr   ICTC,r3
764         blr
765
766         
767 /*
768         L2CR functions
769         Copyright Â© 1997-1998 by PowerLogix R & D, Inc.
770         
771         This program is free software; you can redistribute it and/or modify
772         it under the terms of the GNU General Public License as published by
773         the Free Software Foundation; either version 2 of the License, or
774         (at your option) any later version.
775         
776         This program is distributed in the hope that it will be useful,
777         but WITHOUT ANY WARRANTY; without even the implied warranty of
778         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
779         GNU General Public License for more details.
780         
781         You should have received a copy of the GNU General Public License
782         along with this program; if not, write to the Free Software
783         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
784 */
785 /*
786         Thur, Dec. 12, 1998.
787         - First public release, contributed by PowerLogix.
788         
789         Author: Terry Greeniaus (tgree@phys.ualberta.ca)
790         Please e-mail updates to this file to me, thanks!
791 */
792 /* Usage:
793         
794         When setting the L2CR register, you must do a few special
795         things.  If you are enabling the cache, you must perform a
796         global invalidate.  If you are disabling the cache, you must
797         flush the cache contents first.  This routine takes care of
798         doing these things.  When first enabling the cache, make sure
799         you pass in the L2CR you want, as well as passing in the
800         global invalidate bit set.  A global invalidate will only be
801         performed if the L2I bit is set in applyThis.  When enabling
802         the cache, you should also set the L2E bit in applyThis.  If
803         you want to modify the L2CR contents after the cache has been
804         enabled, the recommended procedure is to first call
805         __setL2CR(0) to disable the cache and then call it again with
806         the new values for L2CR.  Examples:
807
808         _setL2CR(0)             - disables the cache
809         _setL2CR(0xB3A04000)    - enables my G3 upgrade card:
810                                 - L2E set to turn on the cache
811                                 - L2SIZ set to 1MB
812                                 - L2CLK set to 1:1
813                                 - L2RAM set to pipelined synchronous late-write
814                                 - L2I set to perform a global invalidation
815                                 - L2OH set to 0.5 nS
816                                 - L2DF set because this upgrade card
817                                   requires it
818
819         A similar call should work for your card.  You need to know
820         the correct setting for your card and then place them in the
821         fields I have outlined above.  Other fields support optional
822         features, such as L2DO which caches only data, or L2TS which
823         causes cache pushes from the L1 cache to go to the L2 cache
824         instead of to main memory.
825 */
826
827 _GLOBAL(_set_L2CR)
828         /* Make sure this is a 750 chip */
829         mfspr   r4,PVR
830         rlwinm  r4,r4,16,16,31
831         cmplwi  r4,0x0008
832         beq     thisIs750
833         cmplwi  r4,0x000c
834         beq thisIs750
835         li      r3,-1
836         blr
837         
838 thisIs750:
839         /* Get the current enable bit of the L2CR into r4 */
840         mfspr   r4,L2CR
841         mfmsr   r7
842         
843         /* See if we want to perform a global inval this time. */
844         rlwinm  r6,r3,0,10,10   /* r6 contains the new invalidate bit */
845         rlwinm. r5,r3,0,0,0     /* r5 contains the new enable bit */
846         rlwinm  r3,r3,0,11,9    /* Turn off the invalidate bit */
847         rlwimi  r3,r4,0,0,0     /* Keep the enable bit the same as it was. */
848         bne     dontDisableCache /* Only disable the cache if L2CRApply
849                                     has the enable bit off */
850
851 disableCache:
852         /* Disable the cache.  First, we turn off interrupts.
853            An interrupt while we are flushing the cache could bring
854            in data which may not get properly flushed. */
855         rlwinm  r4,r7,0,17,15   /* Turn off EE bit */
856         sync
857         mtmsr   r4
858         sync
859         
860 /*
861         Now, read the first 2MB of memory to put new data in the cache.
862         (Actually we only need the size of the L2 cache plus the size
863         of the L1 cache, but 2MB will cover everything just to be safe).
864 */
865         lis     r4,0x0001
866         mtctr   r4
867         lis     r4,KERNELBASE@h
868 1:      lwzx    r0,r0,r4
869         addi    r4,r4,0x0020            /* Go to start of next cache line */
870         bdnz    1b
871         
872         /* Now, flush the first 2MB of memory */
873         lis     r4,0x0001
874         mtctr   r4
875         lis     r4,KERNELBASE@h
876         sync
877 2:      dcbf    r0,r4
878         addi    r4,r4,0x0020    /* Go to start of next cache line */
879         bdnz    2b
880         
881         /* Turn off the L2CR enable bit. */
882         rlwinm  r3,r3,0,1,31
883         
884 dontDisableCache:
885         /* Set up the L2CR configuration bits */
886         sync
887         mtspr   L2CR,r3
888         sync
889
890         /* Reenable interrupts if necessary. */
891         mtmsr   r7
892         sync
893         
894         cmplwi  r6,0
895         beq     noInval
896         
897         /* Perform a global invalidation */
898         oris    r3,r3,0x0020
899         sync
900         mtspr   L2CR,r3
901         sync
902
903         /* Wait for the invalidation to complete */
904 3:      mfspr   r3,L2CR
905         rlwinm. r4,r3,0,31,31
906         bne     3b
907         
908         rlwinm  r3,r3,0,11,9            /* Turn off the L2I bit */
909         sync
910         mtspr   L2CR,r3
911         sync
912         
913 noInval:
914         /* See if we need to enable the cache */
915         cmplwi  r5,0
916         beqlr
917
918         /* Enable the cache */
919         oris    r3,r3,0x8000
920         mtspr   L2CR,r3
921         sync
922         blr
923
924 _GLOBAL(_get_L2CR)
925         /* Make sure this is a 750 chip */
926         mfspr   r3,PVR
927         rlwinm  r3,r3,16,16,31
928         cmplwi  r3,0x0008
929         beq     1f
930         cmplwi  r3,0x000c
931         li      r3,0
932         bnelr
933 1:      
934         /* Return the L2CR contents */
935         mfspr   r3,L2CR
936         blr
937
938 /* --- End of PowerLogix code ---
939  */
940
941 /*
942 _GLOBAL(_get_L2CR)
943         mfspr   r3,L2CR
944         blr
945
946 _GLOBAL(_set_L2CR)
947         mtspr   L2CR,r3
948         blr
949                 
950 */
951
952 /*
953  * These are used in the alignment trap handler when emulating
954  * single-precision loads and stores.
955  * We restore and save the fpscr so the task gets the same result
956  * and exceptions as if the cpu had performed the load or store.
957  */
958
959 #if defined(CONFIG_4xx)
960 _GLOBAL(cvt_fd)
961         lfs     0,0(r3)
962         stfd    0,0(r4)
963         blr
964
965 _GLOBAL(cvt_df)
966         lfd     0,0(r3)
967         stfs    0,0(r4)
968         blr
969 #else
970 _GLOBAL(cvt_fd)
971         lfd     0,-4(r5)        /* load up fpscr value */
972         mtfsf   0xff,0
973         lfs     0,0(r3)
974         stfd    0,0(r4)
975         mffs    0               /* save new fpscr value */
976         stfd    0,-4(r5)
977         blr
978
979 _GLOBAL(cvt_df)
980         lfd     0,-4(r5)        /* load up fpscr value */
981         mtfsf   0xff,0
982         lfd     0,0(r3)
983         stfs    0,0(r4)
984         mffs    0               /* save new fpscr value */
985         stfd    0,-4(r5)
986         blr
987 #endif
988
989 _GLOBAL(__clear_msr_me)
990         mfmsr   r0                      /* Get current interrupt state */
991         lis     r3,0
992         ori     r3,r3,MSR_ME
993         andc    r0,r0,r3                /* Clears bit in (r4) */
994         sync                            /* Some chip revs have problems here */
995         mtmsr   r0                      /* Update machine state */
996         blr
997
998 /*
999  * Create a kernel thread
1000  *   kernel_thread(fn, arg, flags)
1001  */
1002 _GLOBAL(kernel_thread)
1003         mr      r6,r3           /* function */
1004         ori     r3,r5,CLONE_VM  /* flags */
1005         li      r0,__NR_clone
1006         sc
1007         cmpi    0,r3,0          /* parent or child? */
1008         bnelr                   /* return if parent */
1009         li      r0,0            /* clear out p->thread.regs */
1010         stw     r0,THREAD+PT_REGS(r2)   /* since we don't have user ctx */
1011         mtlr    r6              /* fn addr in lr */
1012         mr      r3,r4           /* load arg and call fn */
1013         blrl
1014         li      r0,__NR_exit    /* exit after child exits */
1015         li      r3,0
1016         sc
1017
1018 /*
1019  * This routine is just here to keep GCC happy - sigh...
1020  */     
1021 _GLOBAL(__main)
1022         blr
1023
1024 #define SYSCALL(name) \
1025 _GLOBAL(name) \
1026         li      r0,__NR_##name; \
1027         sc; \
1028         bnslr; \
1029         lis     r4,errno@ha; \
1030         stw     r3,errno@l(r4); \
1031         li      r3,-1; \
1032         blr
1033
1034 #define __NR__exit __NR_exit
1035
1036 SYSCALL(sync)
1037 SYSCALL(setsid)
1038 SYSCALL(write)
1039 SYSCALL(dup)
1040 SYSCALL(execve)
1041 SYSCALL(open)
1042 SYSCALL(close)
1043 SYSCALL(waitpid)
1044 SYSCALL(fork)
1045 SYSCALL(delete_module)
1046 SYSCALL(_exit)
1047 SYSCALL(lseek)
1048 SYSCALL(read)
1049
1050 /* Why isn't this a) automatic, b) written in 'C'? */   
1051         .data
1052         .align 4
1053 _GLOBAL(sys_call_table)
1054         .long sys_ni_syscall    /* 0  -  old "setup()" system call */
1055         .long sys_exit
1056         .long sys_fork
1057         .long sys_read
1058         .long sys_write
1059         .long sys_open          /* 5 */
1060         .long sys_close
1061         .long sys_waitpid
1062         .long sys_creat
1063         .long sys_link
1064         .long sys_unlink        /* 10 */
1065         .long sys_execve
1066         .long sys_chdir
1067         .long sys_time
1068         .long sys_mknod
1069         .long sys_chmod         /* 15 */
1070         .long sys_lchown
1071         .long sys_ni_syscall                    /* old break syscall holder */
1072         .long sys_stat
1073         .long sys_lseek
1074         .long sys_getpid        /* 20 */
1075         .long sys_mount
1076         .long sys_oldumount
1077         .long sys_setuid
1078         .long sys_getuid
1079         .long sys_stime         /* 25 */
1080         .long sys_ptrace
1081         .long sys_alarm
1082         .long sys_fstat
1083         .long sys_pause
1084         .long sys_utime         /* 30 */
1085         .long sys_ni_syscall                    /* old stty syscall holder */
1086         .long sys_ni_syscall                    /* old gtty syscall holder */
1087         .long sys_access
1088         .long sys_nice
1089         .long sys_ni_syscall    /* 35 */        /* old ftime syscall holder */
1090         .long sys_sync
1091         .long sys_kill
1092         .long sys_rename
1093         .long sys_mkdir
1094         .long sys_rmdir         /* 40 */
1095         .long sys_dup
1096         .long sys_pipe
1097         .long sys_times
1098         .long sys_ni_syscall                    /* old prof syscall holder */
1099         .long sys_brk           /* 45 */
1100         .long sys_setgid
1101         .long sys_getgid
1102         .long sys_signal
1103         .long sys_geteuid
1104         .long sys_getegid       /* 50 */
1105         .long sys_acct
1106         .long sys_umount                        /* recycled never used phys() */
1107         .long sys_ni_syscall                    /* old lock syscall holder */
1108         .long sys_ioctl
1109         .long sys_fcntl         /* 55 */
1110         .long sys_ni_syscall                    /* old mpx syscall holder */
1111         .long sys_setpgid
1112         .long sys_ni_syscall                    /* old ulimit syscall holder */
1113         .long sys_olduname
1114         .long sys_umask         /* 60 */
1115         .long sys_chroot
1116         .long sys_ustat
1117         .long sys_dup2
1118         .long sys_getppid
1119         .long sys_getpgrp       /* 65 */
1120         .long sys_setsid
1121         .long sys_sigaction
1122         .long sys_sgetmask
1123         .long sys_ssetmask
1124         .long sys_setreuid      /* 70 */
1125         .long sys_setregid
1126         .long sys_sigsuspend
1127         .long sys_sigpending
1128         .long sys_sethostname
1129         .long sys_setrlimit     /* 75 */
1130         .long sys_old_getrlimit
1131         .long sys_getrusage
1132         .long sys_gettimeofday
1133         .long sys_settimeofday
1134         .long sys_getgroups     /* 80 */
1135         .long sys_setgroups
1136         .long ppc_select
1137         .long sys_symlink
1138         .long sys_lstat
1139         .long sys_readlink      /* 85 */
1140         .long sys_uselib
1141         .long sys_swapon
1142         .long sys_reboot
1143         .long old_readdir
1144         .long sys_mmap          /* 90 */
1145         .long sys_munmap
1146         .long sys_truncate
1147         .long sys_ftruncate
1148         .long sys_fchmod
1149         .long sys_fchown        /* 95 */
1150         .long sys_getpriority
1151         .long sys_setpriority
1152         .long sys_ni_syscall                    /* old profil syscall holder */
1153         .long sys_statfs
1154         .long sys_fstatfs       /* 100 */
1155         .long sys_ioperm
1156         .long sys_socketcall
1157         .long sys_syslog
1158         .long sys_setitimer
1159         .long sys_getitimer     /* 105 */
1160         .long sys_newstat
1161         .long sys_newlstat
1162         .long sys_newfstat
1163         .long sys_uname
1164         .long sys_iopl          /* 110 */
1165         .long sys_vhangup
1166         .long sys_ni_syscall    /* old 'idle' syscall */
1167         .long sys_vm86
1168         .long sys_wait4
1169         .long sys_swapoff       /* 115 */
1170         .long sys_sysinfo
1171         .long sys_ipc
1172         .long sys_fsync
1173         .long sys_sigreturn
1174         .long sys_clone         /* 120 */
1175         .long sys_setdomainname
1176         .long sys_newuname
1177         .long sys_modify_ldt
1178         .long sys_adjtimex
1179         .long sys_mprotect      /* 125 */
1180         .long sys_sigprocmask
1181         .long sys_create_module
1182         .long sys_init_module
1183         .long sys_delete_module
1184         .long sys_get_kernel_syms       /* 130 */
1185         .long sys_quotactl
1186         .long sys_getpgid
1187         .long sys_fchdir
1188         .long sys_bdflush
1189         .long sys_sysfs         /* 135 */
1190         .long sys_personality
1191         .long sys_ni_syscall    /* for afs_syscall */
1192         .long sys_setfsuid
1193         .long sys_setfsgid
1194         .long sys_llseek        /* 140 */
1195         .long sys_getdents
1196         .long ppc_select
1197         .long sys_flock
1198         .long sys_msync
1199         .long sys_readv         /* 145 */
1200         .long sys_writev
1201         .long sys_getsid
1202         .long sys_fdatasync
1203         .long sys_sysctl
1204         .long sys_mlock         /* 150 */
1205         .long sys_munlock
1206         .long sys_mlockall
1207         .long sys_munlockall
1208         .long sys_sched_setparam
1209         .long sys_sched_getparam        /* 155 */
1210         .long sys_sched_setscheduler
1211         .long sys_sched_getscheduler
1212         .long sys_sched_yield
1213         .long sys_sched_get_priority_max
1214         .long sys_sched_get_priority_min  /* 160 */
1215         .long sys_sched_rr_get_interval
1216         .long sys_nanosleep
1217         .long sys_mremap
1218         .long sys_setresuid
1219         .long sys_getresuid     /* 165 */
1220         .long sys_query_module
1221         .long sys_poll
1222         .long sys_nfsservctl
1223         .long sys_setresgid
1224         .long sys_getresgid     /* 170 */
1225         .long sys_prctl
1226         .long sys_rt_sigreturn
1227         .long sys_rt_sigaction
1228         .long sys_rt_sigprocmask        
1229         .long sys_rt_sigpending /* 175 */
1230         .long sys_rt_sigtimedwait
1231         .long sys_rt_sigqueueinfo
1232         .long sys_rt_sigsuspend
1233         .long sys_pread
1234         .long sys_pwrite        /* 180 */
1235         .long sys_chown
1236         .long sys_getcwd
1237         .long sys_capget
1238         .long sys_capset
1239         .long sys_sigaltstack   /* 185 */
1240         .long sys_sendfile
1241         .long sys_ni_syscall            /* streams1 */
1242         .long sys_ni_syscall            /* streams2 */
1243         .long sys_vfork
1244         .long sys_getrlimit     /* 190 */
1245         .long sys_ni_syscall            /* 191 */       /* Unused */
1246         .long sys_ni_syscall            /* 192 - reserved - mmap2 */
1247         .long sys_ni_syscall            /* 193 - reserved - truncate64 */
1248         .long sys_ni_syscall            /* 194 - reserved - ftruncate64 */
1249         .long sys_ni_syscall            /* 195 - reserved - stat64 */
1250         .long sys_ni_syscall            /* 196 - reserved - lstat64 */
1251         .long sys_ni_syscall            /* 197 - reserved - fstat64 */
1252         .long sys_pciconfig_read        /* 198 */
1253         .long sys_pciconfig_write       /* 199 */
1254         .long sys_pciconfig_iobase      /* 200 */
1255         .long sys_ni_syscall            /* 201 - reserved - MacOnLinux - new */
1256         .long sys_getdents64            /* 202 */
1257         .rept NR_syscalls-(.-sys_call_table)/4
1258                 .long sys_ni_syscall
1259         .endr