Import 2.3.18pre1
[davej-history.git] / arch / ppc / kernel / misc.S
blobc4bed05e90fd0753c13531718cfabe7e367640f2
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  */
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 "ppc_asm.h"
23 #ifndef CONFIG_8xx
24 CACHE_LINE_SIZE = 32
25 LG_CACHE_LINE_SIZE = 5
26 #else
27 CACHE_LINE_SIZE = 16
28 LG_CACHE_LINE_SIZE = 4
29 #endif /* CONFIG_8xx */
31         .text
34  * Returns (address we're running at) - (address we were linked at)
35  * for use before the text and data are mapped to KERNELBASE.
36  */
38 _GLOBAL(reloc_offset)
39         mflr    r0
40         bl      1f
41 1:      mflr    r3
42         lis     r4,1b@ha
43         addi    r4,r4,1b@l
44         subf    r3,r4,r3
45         mtlr    r0
46         blr
48 _GLOBAL(__cli)
49         mfmsr   r0              /* Get current interrupt state */
50         rlwinm  r3,r0,16+1,32-1,31      /* Extract old value of 'EE' */
51         li      r4,0            /* Need [unsigned] value of MSR_EE */
52         ori     r4,r4,MSR_EE    /* Set to turn off bit */
53         andc    r0,r0,r4        /* Clears bit in (r4) */
54         sync                    /* Some chip revs have problems here... */
55         mtmsr   r0              /* Update machine state */
56         blr                     /* Done */
58 _GLOBAL(__sti)
59         lis     r4,ppc_n_lost_interrupts@ha
60         lwz     r4,ppc_n_lost_interrupts@l(r4)
61         mfmsr   r3              /* Get current state */
62         ori     r3,r3,MSR_EE    /* Turn on 'EE' bit */
63         cmpi    0,r4,0          /* lost interrupts to process first? */
64         bne-    do_lost_interrupts
65         sync                    /* Some chip revs have problems here... */
66         mtmsr   r3              /* Update machine state */
67         blr
70  * We were about to enable interrupts but we have to simulate
71  * some interrupts that were lost by enable_irq first.
72  */
73         .globl do_lost_interrupts
74 do_lost_interrupts:
75         stwu    r1,-16(r1)
76         mflr    r0
77         stw     r0,20(r1)
78         stw     r3,8(r1)
79 1:      bl      fake_interrupt
80         lis     r4,ppc_n_lost_interrupts@ha
81         lwz     r4,ppc_n_lost_interrupts@l(r4)
82         cmpi    0,r4,0
83         bne-    1b
84         lwz     r3,8(r1)
85         sync
86         mtmsr   r3
87         lwz     r0,20(r1)
88         mtlr    r0
89         addi    r1,r1,16
90         blr
94  * complement mask on the msr then "or" some values on.
95  *     _nmask_and_or_msr(nmask, value_to_or)
96  */
97         _GLOBAL(_nmask_and_or_msr)
98         mfmsr   r0              /* Get current msr */
99         andc    r0,r0,r3        /* And off the bits set in r3 (first parm) */
100         or      r0,r0,r4                /* Or on the bits in r4 (second parm) */
101         sync                    /* Some chip revs have problems here... */
102         mtmsr   r0              /* Update machine state */
103         blr                     /* Done */
107  * Flush MMU TLB
108  */
109 _GLOBAL(_tlbia)
110         sync
111         tlbia
112         sync
113 #ifdef __SMP__
114         tlbsync
115         sync
116 #endif
117         blr     
120  * Flush MMU TLB for a particular address
121  */
122 _GLOBAL(_tlbie)
123         tlbie   r3
124         sync
125 #ifdef __SMP__
126         tlbsync
127         sync
128 #endif
129         blr
132  * Flush instruction cache.
133  * This is a no-op on the 601.
134  */
135 _GLOBAL(flush_instruction_cache)
136         mfspr   r3,PVR
137         rlwinm  r3,r3,16,16,31
138         cmpi    0,r3,1
139         beqlr                   /* for 601, do nothing */
140         /* 603/604 processor - use invalidate-all bit in HID0 */
141         mfspr   r3,HID0
142         ori     r3,r3,HID0_ICFI
143         mtspr   HID0,r3
144         SYNC
145         blr
148  * Write any modified data cache blocks out to memory
149  * and invalidate the corresponding instruction cache blocks.
150  * This is a no-op on the 601.
152  * flush_icache_range(unsigned long start, unsigned long stop)
153  */
154 _GLOBAL(flush_icache_range)
155         mfspr   r5,PVR
156         rlwinm  r5,r5,16,16,31
157         cmpi    0,r5,1
158         beqlr                           /* for 601, do nothing */
159         li      r5,CACHE_LINE_SIZE-1
160         andc    r3,r3,r5
161         subf    r4,r3,r4
162         add     r4,r4,r5
163         srwi.   r4,r4,LG_CACHE_LINE_SIZE
164         beqlr
165         mtctr   r4
166         mr      r6,r3
167 1:      dcbst   0,r3
168         addi    r3,r3,CACHE_LINE_SIZE
169         bdnz    1b
170         sync                            /* wait for dcbst's to get to ram */
171         mtctr   r4
172 2:      icbi    0,r6
173         addi    r6,r6,CACHE_LINE_SIZE
174         bdnz    2b
175         sync
176         isync
177         blr
180  * Like above, but only do the D-cache.
182  * flush_dcache_range(unsigned long start, unsigned long stop)
183  */
184 _GLOBAL(flush_dcache_range)
185        li      r5,CACHE_LINE_SIZE-1
186        andc    r3,r3,r5
187        subf    r4,r3,r4
188        add     r4,r4,r5
189        srwi.   r4,r4,LG_CACHE_LINE_SIZE
190        beqlr
191        mtctr   r4
193 1:     dcbst   0,r3
194        addi    r3,r3,CACHE_LINE_SIZE
195        bdnz    1b
196        sync                            /* wait for dcbst's to get to ram */
197        blr
200  * Flush a particular page from the DATA cache
201  * Note: this is necessary because the instruction cache does *not*
202  * snoop from the data cache.
203  * This is a no-op on the 601 which has a unified cache.
205  *      void flush_page_to_ram(void *page)
206  */
207 _GLOBAL(flush_page_to_ram)
208         mfspr   r5,PVR
209         rlwinm  r5,r5,16,16,31
210         cmpi    0,r5,1
211         beqlr                           /* for 601, do nothing */
212         li      r4,0x0FFF
213         andc    r3,r3,r4                /* Get page base address */
214         li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
215         mtctr   r4
216         mr      r6,r3
217 0:      dcbst   0,r3                    /* Write line to ram */
218         addi    r3,r3,CACHE_LINE_SIZE
219         bdnz    0b
220         sync
221         mtctr   r4
222 1:      icbi    0,r6
223         addi    r6,r6,CACHE_LINE_SIZE
224         bdnz    1b
225         sync
226         isync
227         blr
230  * Clear a page using the dcbz instruction, which doesn't cause any
231  * memory traffic (except to write out any cache lines which get
232  * displaced).  This only works on cacheable memory.
233  */
234 _GLOBAL(clear_page)
235         li      r0,4096/CACHE_LINE_SIZE
236         mtctr   r0
237 1:      dcbz    0,r3
238         addi    r3,r3,CACHE_LINE_SIZE
239         bdnz    1b
240         blr
243  * Atomic [test&set] exchange
245  *      unsigned long xchg_u32(void *ptr, unsigned long val)
246  * Changes the memory location '*ptr' to be val and returns
247  * the previous value stored there.
248  */
249 _GLOBAL(xchg_u32)
250         mr      r5,r3           /* Save pointer */
251 10:     lwarx   r3,0,r5         /* Fetch old value & reserve */
252         stwcx.  r4,0,r5         /* Update with new value */
253         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
254         blr
257  * Try to acquire a spinlock.
258  * Only does the stwcx. if the load returned 0 - the Programming
259  * Environments Manual suggests not doing unnecessary stcwx.'s
260  * since they may inhibit forward progress by other CPUs in getting
261  * a lock.
262  */
263 _GLOBAL(__spin_trylock)
264         mr      r4,r3
265         eieio                   /* prevent reordering of stores */
266         li      r5,-1
267         lwarx   r3,0,r4         /* fetch old value, establish reservation */
268         cmpwi   0,r3,0          /* is it 0? */
269         bnelr-                  /* return failure if not */
270         stwcx.  r5,0,r4         /* try to update with new value */
271         bne-    1f              /* if we failed */
272         eieio                   /* prevent reordering of stores */
273         blr
274 1:      li      r3,1            /* return non-zero for failure */
275         blr
278  * Atomic add/sub/inc/dec operations
280  * void atomic_add(int c, int *v)
281  * void atomic_sub(int c, int *v)
282  * void atomic_inc(int *v)
283  * void atomic_dec(int *v)
284  * int atomic_dec_and_test(int *v)
285  * int atomic_inc_return(int *v)
286  * int atomic_dec_return(int *v)
287  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
288  * void atomic_set_mask(atomic_t mask, atomic_t *addr);
289  */
290 _GLOBAL(atomic_add)
291 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
292         add     r5,r5,r3        /* Perform 'add' operation */
293         stwcx.  r5,0,r4         /* Update with new value */
294         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
295         blr
296 _GLOBAL(atomic_add_return)
297 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
298         add     r5,r5,r3        /* Perform 'add' operation */
299         stwcx.  r5,0,r4         /* Update with new value */
300         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
301         mr      r3,r5
302         blr
303 _GLOBAL(atomic_sub)
304 10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
305         sub     r5,r5,r3        /* Perform 'add' operation */
306         stwcx.  r5,0,r4         /* Update with new value */
307         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
308         blr
309 _GLOBAL(atomic_inc)
310 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
311         addi    r5,r5,1         /* Perform 'add' operation */
312         stwcx.  r5,0,r3         /* Update with new value */
313         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
314         blr
315 _GLOBAL(atomic_inc_return)
316 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
317         addi    r5,r5,1         /* Perform 'add' operation */
318         stwcx.  r5,0,r3         /* Update with new value */
319         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
320         mr      r3,r5           /* Return new value */
321         blr
322 _GLOBAL(atomic_dec)
323 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
324         subi    r5,r5,1         /* Perform 'add' operation */
325         stwcx.  r5,0,r3         /* Update with new value */
326         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
327         blr
328 _GLOBAL(atomic_dec_return)
329 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
330         subi    r5,r5,1         /* Perform 'add' operation */
331         stwcx.  r5,0,r3         /* Update with new value */
332         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
333         mr      r3,r5           /* Return new value */
334         blr
335 _GLOBAL(atomic_dec_and_test)
336 10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
337         subi    r5,r5,1         /* Perform 'add' operation */
338         stwcx.  r5,0,r3         /* Update with new value */
339         bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
340         cmpi    0,r5,0          /* Return 'true' IFF 0 */
341         li      r3,1
342         beqlr
343         li      r3,0
344         blr
345 _GLOBAL(atomic_clear_mask)
346 10:     lwarx   r5,0,r4
347         andc    r5,r5,r3
348         stwcx.  r5,0,r4
349         bne-    10b
350         blr
351 _GLOBAL(atomic_set_mask)
352 10:     lwarx   r5,0,r4
353         or      r5,r5,r3
354         stwcx.  r5,0,r4
355         bne-    10b
356         blr
359  * I/O string operations
361  * insb(port, buf, len)
362  * outsb(port, buf, len)
363  * insw(port, buf, len)
364  * outsw(port, buf, len)
365  * insl(port, buf, len)
366  * outsl(port, buf, len)
367  * insw_ns(port, buf, len)
368  * outsw_ns(port, buf, len)
369  * insl_ns(port, buf, len)
370  * outsl_ns(port, buf, len)
372  * The *_ns versions don't do byte-swapping.
373  */
374 _GLOBAL(_insb)
375         mtctr   r5
376         subi    r4,r4,1
377 00:     lbz     r5,0(r3)
378         eieio
379         stbu    r5,1(r4)
380         bdnz    00b
381         blr
383 _GLOBAL(_outsb)
384         mtctr   r5
385         subi    r4,r4,1
386 00:     lbzu    r5,1(r4)
387         stb     r5,0(r3)
388         eieio
389         bdnz    00b
390         blr     
392 _GLOBAL(_insw)
393         mtctr   r5
394         subi    r4,r4,2
395 00:     lhbrx   r5,0,r3
396         eieio
397         sthu    r5,2(r4)
398         bdnz    00b
399         blr
401 _GLOBAL(_outsw)
402         mtctr   r5
403         subi    r4,r4,2
404 00:     lhzu    r5,2(r4)
405         eieio
406         sthbrx  r5,0,r3 
407         bdnz    00b
408         blr     
410 _GLOBAL(_insl)
411         mtctr   r5
412         subi    r4,r4,4
413 00:     lwbrx   r5,0,r3
414         eieio
415         stwu    r5,4(r4)
416         bdnz    00b
417         blr
419 _GLOBAL(_outsl)
420         mtctr   r5
421         subi    r4,r4,4
422 00:     lwzu    r5,4(r4)
423         stwbrx  r5,0,r3
424         eieio
425         bdnz    00b
426         blr     
428 _GLOBAL(ide_insw)
429 _GLOBAL(_insw_ns)
430         mtctr   r5
431         subi    r4,r4,2
432 00:     lhz     r5,0(r3)
433         eieio
434         sthu    r5,2(r4)
435         bdnz    00b
436         blr
438 _GLOBAL(ide_outsw)
439 _GLOBAL(_outsw_ns)
440         mtctr   r5
441         subi    r4,r4,2
442 00:     lhzu    r5,2(r4)
443         sth     r5,0(r3)
444         eieio
445         bdnz    00b
446         blr     
448 _GLOBAL(_insl_ns)
449         mtctr   r5
450         subi    r4,r4,4
451 00:     lwz     r5,0(r3)
452         eieio
453         stwu    r5,4(r4)
454         bdnz    00b
455         blr
457 _GLOBAL(_outsl_ns)
458         mtctr   r5
459         subi    r4,r4,4
460 00:     lwzu    r5,4(r4)
461         stw     r5,0(r3)
462         eieio
463         bdnz    00b
464         blr     
467  * Extended precision shifts
469  * R3/R4 has 64 bit value
470  * R5    has shift count
471  * result in R3/R4
473  *  ashrdi3:     XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
474  *  ashldi3:     XXXYYY/ZZZAAA -> YYYZZZ/AAA000
475  */
476 _GLOBAL(__ashrdi3)
477         li      r6,32
478         sub     r6,r6,r5
479         slw     r7,r3,r6        /* isolate YYY */
480         srw     r4,r4,r5        /* isolate ZZZ */
481         or      r4,r4,r7        /* YYYZZZ */
482         sraw    r3,r3,r5        /* SSSXXX */
483         blr
484         
485 _GLOBAL(__ashldi3)
486         li      r6,32
487         sub     r6,r6,r5
488         srw     r7,r4,r6        /* isolate ZZZ */
489         slw     r4,r4,r5        /* AAA000 */
490         slw     r3,r3,r5        /* YYY--- */
491         or      r3,r3,r7        /* YYYZZZ */
492         blr
494 _GLOBAL(abs)
495         cmpi    0,r3,0
496         bge     10f
497         neg     r3,r3
498 10:     blr
500 _GLOBAL(_get_SP)
501         mr      r3,r1           /* Close enough */
502         blr
504 _GLOBAL(_get_THRM1)
505         mfspr   r3,THRM1
506         blr
508 _GLOBAL(_get_THRM2)
509         mfspr   r3,THRM2
510         blr
512 _GLOBAL(_get_THRM3)
513         mfspr   r3,THRM3
514         blr
515                 
516 _GLOBAL(_set_THRM1)
517         mtspr   THRM1,r3
518         blr
520 _GLOBAL(_set_THRM2)
521         mtspr   THRM2,r3
522         blr
524 _GLOBAL(_set_THRM3)
525         mtspr   THRM3,r3
526         blr
527         
528 _GLOBAL(_get_PVR)
529         mfspr   r3,PVR
530         blr
532         L2CR functions
533         Copyright Â© 1997-1998 by PowerLogix R & D, Inc.
534         
535         This program is free software; you can redistribute it and/or modify
536         it under the terms of the GNU General Public License as published by
537         the Free Software Foundation; either version 2 of the License, or
538         (at your option) any later version.
539         
540         This program is distributed in the hope that it will be useful,
541         but WITHOUT ANY WARRANTY; without even the implied warranty of
542         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
543         GNU General Public License for more details.
544         
545         You should have received a copy of the GNU General Public License
546         along with this program; if not, write to the Free Software
547         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
550         Thur, Dec. 12, 1998.
551         - First public release, contributed by PowerLogix.
552         
553         Author: Terry Greeniaus (tgree@phys.ualberta.ca)
554         Please e-mail updates to this file to me, thanks!
557 _GLOBAL(_set_L2CR)
558         /* Usage:
559         
560                 When setting the L2CR register, you must do a few special things.  If you are enabling the
561                 cache, you must perform a global invalidate.  If you are disabling the cache, you must
562                 flush the cache contents first.  This routine takes care of doing these things.  When first
563                 enabling the cache, make sure you pass in the L2CR you want, as well as passing in the
564                 global invalidate bit set.  A global invalidate will only be performed if the L2I bit is set
565                 in applyThis.  When enabling the cache, you should also set the L2E bit in applyThis.  If you
566                 want to modify the L2CR contents after the cache has been enabled, the recommended
567                 procedure is to first call __setL2CR(0) to disable the cache and then call it again with
568                 the new values for L2CR.  Examples:
569         
570                         _setL2CR(0)                     -       disables the cache
571                         _setL2CR(0xB3A04000)            -       enables my G3 upgrade card:
572                                                         -       L2E set to turn on the cache
573                                                         -       L2SIZ set to 1MB
574                                                         -       L2CLK set to 1:1
575                                                         -       L2RAM set to pipelined syncronous late-write
576                                                         -       L2I set to perform a global invalidation
577                                                         -       L2OH set to 0.5 nS
578                                                         -       L2DF set because this upgrade card requires it
579         
580                 A similar call should work for your card.  You need to know the correct setting for your
581                 card and then place them in the fields I have outlined above.  Other fields support optional
582                 features, such as L2DO which caches only data, or L2TS which causes cache pushes from
583                 the L1 cache to go to the L2 cache instead of to main memory.
584         */
585         
586         /* Make sure this is a 750 chip */
587         mfspr   r4,PVR
588         rlwinm  r4,r4,16,16,31
589         cmplwi  r4,0x0008
590         beq     thisIs750
591         li      r3,-1
592         blr
593         
594 thisIs750:
595         /* Get the current enable bit of the L2CR into r4 */
596         mfspr   r4,L2CR
597         rlwinm  r4,r4,0,0,0
598         
599         /* See if we want to perform a global inval this time. */
600         rlwinm  r6,r3,0,10,10           /* r6 contains the new invalidate bit */
601         rlwinm. r5,r3,0,0,0             /* r5 contains the new enable bit */
602         rlwinm  r3,r3,0,11,9            /* Turn off the invalidate bit */
603         rlwinm  r3,r3,0,1,31            /* Turn off the enable bit */
604         or      r3,r3,r4                /* Keep the enable bit the same as it was for now. */
605         bne     dontDisableCache        /* Only disable the cache if L2CRApply has the enable bit off */
607 disableCache:
608         /* Disable the cache.  First, we turn off data relocation. */
609         mfmsr   r7
610         rlwinm  r4,r7,0,28,26           /* Turn off DR bit */
611         rlwinm  r4,r4,0,17,15           /* Turn off EE bit - an external exception while we are flushing
612                                            the cache is fatal (comment this line and see!) */
613         sync
614         mtmsr   r4
615         sync
616         
617         /*
618                 Now, read the first 2MB of memory to put new data in the cache.
619                 (Actually we only need the size of the L2 cache plus
620                 the size of the L1 cache, but 2MB will cover everything just to be safe).
621         */
622         lis     r4,0x0001
623         mtctr   r4
624         li      r4,0
625 loadLoop:
626         lwzx    r0,r0,r4
627         addi    r4,r4,0x0020            /* Go to start of next cache line */
628         bdnz    loadLoop
629         
630         /* Now, flush the first 2MB of memory */
631         lis     r4,0x0001
632         mtctr   r4
633         li      r4,0
634         sync
635 flushLoop:
636         dcbf    r0,r4
637         addi    r4,r4,0x0020    /* Go to start of next cache line */
638         bdnz    flushLoop
639         
640         /* Turn off the L2CR enable bit. */
641         rlwinm  r3,r3,0,1,31
642         
643         /* Reenable data relocation. */
644         sync
645         mtmsr   r7
646         sync
647         
648 dontDisableCache:
649         /* Set up the L2CR configuration bits */
650         sync
651         mtspr   L2CR,r3
652         sync
653         cmplwi  r6,0
654         beq     noInval
655         
656         /* Perform a global invalidation */
657         oris    r3,r3,0x0020
658         sync
659         mtspr   1017,r3
660         sync
661 invalCompleteLoop:                      /* Wait for the invalidation to complete */
662         mfspr   r3,1017
663         rlwinm. r4,r3,0,31,31
664         bne     invalCompleteLoop
665         
666         rlwinm  r3,r3,0,11,9;           /* Turn off the L2I bit */
667         sync
668         mtspr   L2CR,r3
669         sync
670         
671 noInval:
672         /* See if we need to enable the cache */
673         cmplwi  r5,0
674         beqlr
675         
676 enableCache:
677         /* Enable the cache */
678         oris    r3,r3,0x8000
679         mtspr   L2CR,r3
680         sync
681         blr
683 _GLOBAL(_get_L2CR)
684         /* Make sure this is a 750 chip */
685         mfspr   r3,PVR
686         rlwinm  r3,r3,16,16,31
687         cmplwi  r3,0x0008
688         li      r3,0
689         bnelr
690         
691         /* Return the L2CR contents */
692         mfspr   r3,L2CR
693         blr
695 /* --- End of PowerLogix code ---
696  */
699 _GLOBAL(_get_L2CR)
700         mfspr   r3,L2CR
701         blr
703 _GLOBAL(_set_L2CR)
704         mtspr   L2CR,r3
705         blr
706                 
710  * These are used in the alignment trap handler when emulating
711  * single-precision loads and stores.
712  * We restore and save the fpscr so the task gets the same result
713  * and exceptions as if the cpu had performed the load or store.
714  */
715 _GLOBAL(cvt_fd)
716 cvt_fd:
717         lfd     0,-4(r5)        /* load up fpscr value */
718         mtfsf   0xff,0
719         lfs     0,0(r3)
720         stfd    0,0(r4)
721         mffs    0               /* save new fpscr value */
722         stfd    0,-4(r5)
723         blr
725 _GLOBAL(cvt_df)
726 cvt_df:
727         lfd     0,-4(r5)        /* load up fpscr value */
728         mtfsf   0xff,0
729         lfd     0,0(r3)
730         stfs    0,0(r4)
731         mffs    0               /* save new fpscr value */
732         stfd    0,-4(r5)
733         blr
735         .globl  __clear_msr_me
736 __clear_msr_me:
737         mfmsr   r0                      /* Get current interrupt state */
738         lis     r3,0
739         ori     r3,r3,MSR_ME
740         andc    r0,r0,r3                /* Clears bit in (r4) */
741         sync                            /* Some chip revs have problems here */
742         mtmsr   r0                      /* Update machine state */
743         blr
746  * Create a kernel thread
747  *   kernel_thread(fn, arg, flags)
748  */
749 _GLOBAL(kernel_thread)
750         mr      r6,r3           /* function */
751         ori     r3,r5,CLONE_VM  /* flags */
752         li      r0,__NR_clone
753         sc
754         cmpi    0,r3,0          /* parent or child? */
755         bnelr                   /* return if parent */
756         li      r0,0            /* clear out p->thread.regs */
757         stw     r0,THREAD+PT_REGS(r2)   /* since we don't have user ctx */
758         mtlr    r6              /* fn addr in lr */
759         mr      r3,r4           /* load arg and call fn */
760         blrl
761         li      r0,__NR_exit    /* exit after child exits */
762         li      r3,0
763         sc
766  * This routine is just here to keep GCC happy - sigh...
767  */     
768 _GLOBAL(__main)
769         blr
771 #define SYSCALL(name) \
772 _GLOBAL(name) \
773         li      r0,__NR_##name; \
774         sc; \
775         bnslr; \
776         lis     r4,errno@ha; \
777         stw     r3,errno@l(r4); \
778         li      r3,-1; \
779         blr
781 #define __NR__exit __NR_exit
783 SYSCALL(sync)
784 SYSCALL(setsid)
785 SYSCALL(write)
786 SYSCALL(dup)
787 SYSCALL(execve)
788 SYSCALL(open)
789 SYSCALL(close)
790 SYSCALL(waitpid)
791 SYSCALL(fork)
792 SYSCALL(delete_module)
793 SYSCALL(_exit)
794 SYSCALL(lseek)
795 SYSCALL(read)
797 /* Why isn't this a) automatic, b) written in 'C'? */   
798         .data
799         .align 4
800         .globl  sys_call_table
801 sys_call_table:
802         .long sys_ni_syscall    /* 0  -  old "setup()" system call */
803         .long sys_exit
804         .long sys_fork
805         .long sys_read
806         .long sys_write
807         .long sys_open          /* 5 */
808         .long sys_close
809         .long sys_waitpid
810         .long sys_creat
811         .long sys_link
812         .long sys_unlink        /* 10 */
813         .long sys_execve
814         .long sys_chdir
815         .long sys_time
816         .long sys_mknod
817         .long sys_chmod         /* 15 */
818         .long sys_lchown
819         .long sys_ni_syscall                    /* old break syscall holder */
820         .long sys_stat
821         .long sys_lseek
822         .long sys_getpid        /* 20 */
823         .long sys_mount
824         .long sys_oldumount
825         .long sys_setuid
826         .long sys_getuid
827         .long sys_stime         /* 25 */
828         .long sys_ptrace
829         .long sys_alarm
830         .long sys_fstat
831         .long sys_pause
832         .long sys_utime         /* 30 */
833         .long sys_ni_syscall                    /* old stty syscall holder */
834         .long sys_ni_syscall                    /* old gtty syscall holder */
835         .long sys_access
836         .long sys_nice
837         .long sys_ni_syscall    /* 35 */        /* old ftime syscall holder */
838         .long sys_sync
839         .long sys_kill
840         .long sys_rename
841         .long sys_mkdir
842         .long sys_rmdir         /* 40 */
843         .long sys_dup
844         .long sys_pipe
845         .long sys_times
846         .long sys_ni_syscall                    /* old prof syscall holder */
847         .long sys_brk           /* 45 */
848         .long sys_setgid
849         .long sys_getgid
850         .long sys_signal
851         .long sys_geteuid
852         .long sys_getegid       /* 50 */
853         .long sys_acct
854         .long sys_umount                        /* recycled never used phys() */
855         .long sys_ni_syscall                    /* old lock syscall holder */
856         .long sys_ioctl
857         .long sys_fcntl         /* 55 */
858         .long sys_ni_syscall                    /* old mpx syscall holder */
859         .long sys_setpgid
860         .long sys_ni_syscall                    /* old ulimit syscall holder */
861         .long sys_olduname
862         .long sys_umask         /* 60 */
863         .long sys_chroot
864         .long sys_ustat
865         .long sys_dup2
866         .long sys_getppid
867         .long sys_getpgrp       /* 65 */
868         .long sys_setsid
869         .long sys_sigaction
870         .long sys_sgetmask
871         .long sys_ssetmask
872         .long sys_setreuid      /* 70 */
873         .long sys_setregid
874         .long sys_sigsuspend
875         .long sys_sigpending
876         .long sys_sethostname
877         .long sys_setrlimit     /* 75 */
878         .long sys_getrlimit
879         .long sys_getrusage
880         .long sys_gettimeofday
881         .long sys_settimeofday
882         .long sys_getgroups     /* 80 */
883         .long sys_setgroups
884         .long ppc_select
885         .long sys_symlink
886         .long sys_lstat
887         .long sys_readlink      /* 85 */
888         .long sys_uselib
889         .long sys_swapon
890         .long sys_reboot
891         .long old_readdir
892         .long sys_mmap          /* 90 */
893         .long sys_munmap
894         .long sys_truncate
895         .long sys_ftruncate
896         .long sys_fchmod
897         .long sys_fchown        /* 95 */
898         .long sys_getpriority
899         .long sys_setpriority
900         .long sys_ni_syscall                    /* old profil syscall holder */
901         .long sys_statfs
902         .long sys_fstatfs       /* 100 */
903         .long sys_ioperm
904         .long sys_socketcall
905         .long sys_syslog
906         .long sys_setitimer
907         .long sys_getitimer     /* 105 */
908         .long sys_newstat
909         .long sys_newlstat
910         .long sys_newfstat
911         .long sys_uname
912         .long sys_iopl          /* 110 */
913         .long sys_vhangup
914         .long sys_ni_syscall    /* old 'idle' syscall */
915         .long sys_vm86
916         .long sys_wait4
917         .long sys_swapoff       /* 115 */
918         .long sys_sysinfo
919         .long sys_ipc
920         .long sys_fsync
921         .long sys_sigreturn
922         .long sys_clone         /* 120 */
923         .long sys_setdomainname
924         .long sys_newuname
925         .long sys_modify_ldt
926         .long sys_adjtimex
927         .long sys_mprotect      /* 125 */
928         .long sys_sigprocmask
929         .long sys_create_module
930         .long sys_init_module
931         .long sys_delete_module
932         .long sys_get_kernel_syms       /* 130 */
933         .long sys_quotactl
934         .long sys_getpgid
935         .long sys_fchdir
936         .long sys_bdflush
937         .long sys_sysfs         /* 135 */
938         .long sys_personality
939         .long sys_ni_syscall    /* for afs_syscall */
940         .long sys_setfsuid
941         .long sys_setfsgid
942         .long sys_llseek        /* 140 */
943         .long sys_getdents
944         .long ppc_select
945         .long sys_flock
946         .long sys_msync
947         .long sys_readv         /* 145 */
948         .long sys_writev
949         .long sys_getsid
950         .long sys_fdatasync
951         .long sys_sysctl
952         .long sys_mlock         /* 150 */
953         .long sys_munlock
954         .long sys_mlockall
955         .long sys_munlockall
956         .long sys_sched_setparam
957         .long sys_sched_getparam        /* 155 */
958         .long sys_sched_setscheduler
959         .long sys_sched_getscheduler
960         .long sys_sched_yield
961         .long sys_sched_get_priority_max
962         .long sys_sched_get_priority_min  /* 160 */
963         .long sys_sched_rr_get_interval
964         .long sys_nanosleep
965         .long sys_mremap
966         .long sys_setresuid
967         .long sys_getresuid     /* 165 */
968         .long sys_query_module
969         .long sys_poll
970 #ifdef CONFIG_NFSD      
971         .long sys_nfsservctl
972 #else
973         .long sys_ni_syscall
974 #endif          
975         .long sys_setresgid
976         .long sys_getresgid     /* 170 */
977         .long sys_prctl
978         .long sys_rt_sigreturn
979         .long sys_rt_sigaction
980         .long sys_rt_sigprocmask        
981         .long sys_rt_sigpending /* 175 */
982         .long sys_rt_sigtimedwait
983         .long sys_rt_sigqueueinfo
984         .long sys_rt_sigsuspend
985         .long sys_pread
986         .long sys_pwrite        /* 180 */
987         .long sys_chown
988         .long sys_getcwd
989         .long sys_capget
990         .long sys_capset
991         .long sys_sigaltstack   /* 185 */
992         .long sys_sendfile
993         .long sys_ni_syscall            /* streams1 */
994         .long sys_ni_syscall            /* streams2 */
995         .long sys_vfork
996         .space (NR_syscalls-183)*4