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