Annotation of kernel/machdep/ppc/fpu.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991  
                     27:  *              All Rights Reserved 
                     28:  *  
                     29:  * Permission to use, copy, modify, and distribute this software and 
                     30:  * its documentation for any purpose and without fee is hereby granted, 
                     31:  * provided that the above copyright notice appears in all copies and 
                     32:  * that both the copyright notice and this permission notice appear in 
                     33:  * supporting documentation. 
                     34:  *  
                     35:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
                     36:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
                     37:  * FOR A PARTICULAR PURPOSE. 
                     38:  *  
                     39:  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
                     40:  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
                     41:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
                     42:  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
                     43:  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
                     44:  */
                     45: /*
                     46:  * MKLINUX-1.0DR2
                     47:  */
                     48: 
                     49: #include <cpus.h>
                     50: #include <assym.h>
                     51: #include <debug.h>
                     52: #include <ppc/asm.h>
                     53: #include <ppc/proc_reg.h>
                     54: #include <mach/ppc/vm_param.h>
                     55: 
                     56:        
                     57:        .text
                     58: /*
                     59:  * void fpu_save(void)
                     60:  *
                     61:  * Called when there's an exception or when get_state is called 
                     62:  * for the FPU state. Puts a copy of the current thread's state
                     63:  * into the PCB pointed to by fpu_pcb, and leaves the FPU enabled.
                     64:  *
                     65:  * video_scroll.s assumes that ARG0-5 won't be trampled on, and
                     66:  * that fpu_save doesn't need a frame, otherwise it would need
                     67:  * a frame itself. Why not oblige!
                     68:  *
                     69:  * NOTE:       This routine is meant for kernel Floating Point
                     70:  *     use.  It is called to flush the current context to the correct
                     71:  *     pcb and leaves with MSR_FP on so the kernel can use the FPU.
                     72:  *
                     73:  *     IT IS THE CALLERS RESPONSIBILITY TO TURN THE FPU OFF AFTER USE!!!
                     74:  *
                     75:  *     The function fpu_disable is used to accomplish this from C language
                     76:  *     programs or is can be done at the end of an assembly routine.
                     77:  */
                     78: 
                     79: ENTRY(fpu_save, TAG_NO_FRAME_USED)
                     80:        /*
                     81:         * Turn the FPU back on (should this be a separate routine?)
                     82:         */
                     83:        mfmsr   r0
                     84:        andi.   r0,     r0,     MASK(MSR_FP)
                     85:        bne     .L_fpu_save_no_owner
                     86: 
                     87:        mfmsr   r0
                     88:        ori     r0,     r0,     MASK(MSR_FP)    /* bit is in low-order 16 */
                     89:        mtmsr   r0
                     90:        isync
                     91: 
                     92:        mfsprg  ARG7,   0       /* HACK - need to get around r2 problem */
                     93: 
                     94:        lwz     ARG6,   PP_FPU_PCB(ARG7)
                     95:        
                     96:        /*
                     97:         * See if any thread owns the FPU. If not, we can skip the state save.
                     98:         */
                     99:        cmpwi   CR0,    ARG6,   0
                    100:        beq-    CR0,    .L_fpu_save_no_owner
                    101: 
                    102:        /*
                    103:         * Save the current FPU state into the PCB of the thread that owns it.
                    104:         */
                    105:         stfd    f0,   PCB_FS_F0(ARG6)
                    106:         stfd    f1,   PCB_FS_F1(ARG6)
                    107:         stfd    f2,   PCB_FS_F2(ARG6)
                    108:         stfd    f3,   PCB_FS_F3(ARG6)
                    109:         stfd    f4,   PCB_FS_F4(ARG6)
                    110:         stfd    f5,   PCB_FS_F5(ARG6)
                    111:         stfd    f6,   PCB_FS_F6(ARG6)
                    112:         stfd    f7,   PCB_FS_F7(ARG6)
                    113:                mffs    f0                      /* fpscr in f0 low 32 bits*/
                    114:         stfd    f8,   PCB_FS_F8(ARG6)
                    115:         stfd    f9,   PCB_FS_F9(ARG6)
                    116:         stfd    f10,  PCB_FS_F10(ARG6)
                    117:         stfd    f11,  PCB_FS_F11(ARG6)
                    118:         stfd    f12,  PCB_FS_F12(ARG6)
                    119:         stfd    f13,  PCB_FS_F13(ARG6)
                    120:         stfd    f14,  PCB_FS_F14(ARG6)
                    121:         stfd    f15,  PCB_FS_F15(ARG6)
                    122:                 stfd    f0,  PCB_FS_FPSCR(ARG6)        /* Store junk 32 bits+fpscr */
                    123:         stfd    f16,  PCB_FS_F16(ARG6)
                    124:         stfd    f17,  PCB_FS_F17(ARG6)
                    125:         stfd    f18,  PCB_FS_F18(ARG6)
                    126:         stfd    f19,  PCB_FS_F19(ARG6)
                    127:         stfd    f20,  PCB_FS_F20(ARG6)
                    128:         stfd    f21,  PCB_FS_F21(ARG6)
                    129:         stfd    f22,  PCB_FS_F22(ARG6)
                    130:         stfd    f23,  PCB_FS_F23(ARG6)
                    131:         stfd    f24,  PCB_FS_F24(ARG6)
                    132:         stfd    f25,  PCB_FS_F25(ARG6)
                    133:         stfd    f26,  PCB_FS_F26(ARG6)
                    134:         stfd    f27,  PCB_FS_F27(ARG6)
                    135:         stfd    f28,  PCB_FS_F28(ARG6)
                    136:         stfd    f29,  PCB_FS_F29(ARG6)
                    137:         stfd    f30,  PCB_FS_F30(ARG6)
                    138:         stfd    f31,  PCB_FS_F31(ARG6)
                    139: 
                    140:        /* Mark the FPU as having no owner now */
                    141:        li      r0,     0
                    142:        stw     r0,     PP_FPU_PCB(ARG7)
                    143: 
                    144:        /*
                    145:         * Turn off the FPU for the old owner
                    146:         */
                    147:        lwz     r0,     SS_SRR1(ARG6)
                    148:        rlwinm  r0,     r0,     0,      MSR_FP_BIT+1,   MSR_FP_BIT-1
                    149:        stw     r0,     SS_SRR1(ARG6)
                    150:        
                    151: .L_fpu_save_no_owner:
                    152:        blr
                    153: 
                    154: 
                    155: ENTRY(fpu_save_thread, TAG_NO_FRAME_USED)
                    156: 
                    157:        /*
                    158:         * Turn the FPU back on (should this be a separate routine?)
                    159:         */
                    160: 
                    161:        mfmsr   r0
                    162:        ori     r0,     r0,     MASK(MSR_FP)    /* bit is in low-order 16 */
                    163:        mtmsr   r0
                    164:        isync
                    165: 
                    166:        mfsprg  ARG7,   0       /* HACK - need to get around r2 problem */
                    167: 
                    168:        lwz     ARG6,   PP_FPU_PCB(ARG7)
                    169:        /*
                    170:         * See if any thread owns the FPU. If not, we can skip the state save.
                    171:         */
                    172:        cmpwi   CR0,    ARG6,   0
                    173:        beq-    CR0,    .L_fpu_save_thread_no_owner
                    174: 
                    175:        /*
                    176:         * Save the current FPU state into the PCB of the thread that owns it.
                    177:         */
                    178:         stfd    f0,   PCB_FS_F0(ARG6)
                    179:         stfd    f1,   PCB_FS_F1(ARG6)
                    180:         stfd    f2,   PCB_FS_F2(ARG6)
                    181:         stfd    f3,   PCB_FS_F3(ARG6)
                    182:         stfd    f4,   PCB_FS_F4(ARG6)
                    183:         stfd    f5,   PCB_FS_F5(ARG6)
                    184:         stfd    f6,   PCB_FS_F6(ARG6)
                    185:         stfd    f7,   PCB_FS_F7(ARG6)
                    186:                mffs    f0                      /* fpscr in f0 low 32 bits*/
                    187:         stfd    f8,   PCB_FS_F8(ARG6)
                    188:         stfd    f9,   PCB_FS_F9(ARG6)
                    189:         stfd    f10,  PCB_FS_F10(ARG6)
                    190:         stfd    f11,  PCB_FS_F11(ARG6)
                    191:         stfd    f12,  PCB_FS_F12(ARG6)
                    192:         stfd    f13,  PCB_FS_F13(ARG6)
                    193:         stfd    f14,  PCB_FS_F14(ARG6)
                    194:         stfd    f15,  PCB_FS_F15(ARG6)
                    195:                 stfd    f0,  PCB_FS_FPSCR(ARG6)        /* Store junk 32 bits+fpscr */
                    196:         stfd    f16,  PCB_FS_F16(ARG6)
                    197:         stfd    f17,  PCB_FS_F17(ARG6)
                    198:         stfd    f18,  PCB_FS_F18(ARG6)
                    199:         stfd    f19,  PCB_FS_F19(ARG6)
                    200:         stfd    f20,  PCB_FS_F20(ARG6)
                    201:         stfd    f21,  PCB_FS_F21(ARG6)
                    202:         stfd    f22,  PCB_FS_F22(ARG6)
                    203:         stfd    f23,  PCB_FS_F23(ARG6)
                    204:         stfd    f24,  PCB_FS_F24(ARG6)
                    205:         stfd    f25,  PCB_FS_F25(ARG6)
                    206:         stfd    f26,  PCB_FS_F26(ARG6)
                    207:         stfd    f27,  PCB_FS_F27(ARG6)
                    208:         stfd    f28,  PCB_FS_F28(ARG6)
                    209:         stfd    f29,  PCB_FS_F29(ARG6)
                    210:         stfd    f30,  PCB_FS_F30(ARG6)
                    211:         stfd    f31,  PCB_FS_F31(ARG6)
                    212: 
                    213:        /*
                    214:         * Turn off the FPU for the old owner
                    215:         */
                    216:        lwz     r0,     SS_SRR1(ARG6)
                    217:        rlwinm  r0,     r0,     0,      MSR_FP_BIT+1,   MSR_FP_BIT-1
                    218:        stw     r0,     SS_SRR1(ARG6)
                    219: 
                    220:        /* Store current PCB address in fpu_pcb to claim fpu for thread */
                    221:        lwz     ARG6,   PP_CPU_DATA(ARG7)
                    222:        lwz     ARG6,   CPU_ACTIVE_THREAD(ARG6)
                    223:        lwz     ARG6,   THREAD_PCB(ARG6)
                    224:        stw     ARG6,   PP_FPU_PCB(ARG7)
                    225:        
                    226: .L_fpu_save_thread_no_owner:
                    227:        blr
                    228: 
                    229: /*
                    230:  * fpu_restore()
                    231:  *
                    232:  * restore the current user thread Floating-Point context in the FPU and
                    233:  * set the FPU ownership to the current user thread.
                    234:  *
                    235:  * This code runs in virtual address mode with interrupts off.
                    236:  *
                    237:  */     
                    238: 
                    239:         .text
                    240: ENTRY(fpu_restore, TAG_NO_FRAME_USED) 
                    241: 
                    242:        mfsprg  r4, 0   /* load per_proc_info pointer */
                    243: 
                    244:        /* See if the current thread owns the FPU, if so, just return */
                    245:        lwz     r3, PP_FPU_PCB(r4)
                    246:  
                    247:        lwz     r5, PP_CPU_DATA(r4)
                    248:        lwz     r5, CPU_ACTIVE_THREAD(r5)
                    249:        lwz     r5, THREAD_PCB(r5)
                    250: 
                    251:        cmpw    cr0, r5, r3
                    252:        beq     cr0, .L_fpu_restore_ret
                    253: 
                    254:        /* Store current PCB address in fpu_pcb to claim fpu for thread */
                    255:        stw     r5, PP_FPU_PCB(r4)
                    256: 
                    257:        /* restore current user thread Floating-Point context */
                    258:        lfd     f31, PCB_FS_FPSCR(r5)   /* Load junk 32 bits+fpscr */
                    259:        lfd     f0, PCB_FS_F0(r5)
                    260:        lfd     f1, PCB_FS_F1(r5)
                    261:        lfd     f2, PCB_FS_F2(r5)
                    262:        lfd     f3, PCB_FS_F3(r5)
                    263:        lfd     f4, PCB_FS_F4(r5)
                    264:        lfd     f5, PCB_FS_F5(r5)
                    265:        lfd     f6, PCB_FS_F6(r5)
                    266:        lfd     f7, PCB_FS_F7(r5)
                    267:        mtfsf   0xff, f31               /* fpscr in f0 low 32 bits*/
                    268:        lfd     f8, PCB_FS_F8(r5)
                    269:        lfd     f9, PCB_FS_F9(r5)
                    270:        lfd     f10, PCB_FS_F10(r5)
                    271:        lfd     f11, PCB_FS_F11(r5)
                    272:        lfd     f12, PCB_FS_F12(r5)
                    273:        lfd     f13, PCB_FS_F13(r5)
                    274:        lfd     f14, PCB_FS_F14(r5)
                    275:        lfd     f15, PCB_FS_F15(r5)
                    276:        lfd     f16, PCB_FS_F16(r5)
                    277:        lfd     f17, PCB_FS_F17(r5)
                    278:        lfd     f18, PCB_FS_F18(r5)
                    279:        lfd     f19, PCB_FS_F19(r5)
                    280:        lfd     f20, PCB_FS_F20(r5)
                    281:        lfd     f21, PCB_FS_F21(r5)
                    282:        lfd     f22, PCB_FS_F22(r5)
                    283:        lfd     f23, PCB_FS_F23(r5)
                    284:        lfd     f24, PCB_FS_F24(r5)
                    285:        lfd     f25, PCB_FS_F25(r5)
                    286:        lfd     f26, PCB_FS_F26(r5)
                    287:        lfd     f27, PCB_FS_F27(r5)
                    288:        lfd     f28, PCB_FS_F28(r5)
                    289:        lfd     f29, PCB_FS_F29(r5)
                    290:        lfd     f30, PCB_FS_F30(r5)
                    291:        lfd     f31, PCB_FS_F31(r5)
                    292: 
                    293:        /* Turn back on the FPU in the current user thread saved context */
                    294:        lwz     r4, SS_SRR1(r5)
                    295:        ori     r4, r4, MASK(MSR_FP)    /* bit is in low-order 16 */
                    296:        stw     r4, SS_SRR1(r5)
                    297: 
                    298: .L_fpu_restore_ret:
                    299:        blr
                    300: 
                    301: 
                    302: /*
                    303:  * fpu_switch()
                    304:  *
                    305:  * Jumped to by the floating-point unavailable exception handler to
                    306:  * switch fpu context in a lazy manner.
                    307:  *
                    308:  * This code is run in virtual address mode with interrupts off.
                    309:  * It is assumed that the pcb in question is in memory
                    310:  *
                    311:  * Upon exit, the code returns to the users context with the MSR_FP for the
                    312:  * previous FPU owner disabled.
                    313:  *
                    314:  * ENTRY:      VM switched ON
                    315:  *             Interrupts  OFF
                    316:  *              original r1-3 saved in sprg1-3
                    317:  *              original srr0 and srr1 saved in per_proc_info structure
                    318:  *              original cr            saved in per_proc_info structure
                    319:  *              exception type         saved in per_proc_info structure
                    320:  *              r1 = scratch
                    321:  *              r2 = virt addr of per_proc_info
                    322:  *             r3 = exception type (one of EXC_...)
                    323:  *
                    324:  * r1 is used as a temporary register throught this code, not as a stack
                    325:  * pointer.
                    326:  * 
                    327:  */
                    328: 
                    329:        .text
                    330: ENTRY(fpu_switch, TAG_NO_FRAME_USED)
                    331: 
                    332: #if DEBUG
                    333:        lwz     r3,     PP_SAVE_SRR1(r2)
                    334:        andi.   r1,     r3,     MASK(MSR_PR)
                    335:        bne+    .L_fpu_switch_user
                    336:        bl      EXT(fpu_panic)
                    337: .L_fpu_switch_user:
                    338: #endif /* DEBUG */
                    339: 
                    340:        /*
                    341:         * Turn the FPU back on
                    342:         */
                    343:        mfmsr   r3
                    344:        ori     r3,     r3,     MASK(MSR_FP)    /* bit is in low-order 16 */
                    345:        mtmsr   r3
                    346:        isync
                    347: 
                    348:        /* See if the current thread owns the FPU, if so, just return */
                    349:        lwz     r3,     PP_FPU_PCB(r2)
                    350: 
                    351:        lwz     r1,     PP_CPU_DATA(r2)
                    352:        lwz     r1,     CPU_ACTIVE_THREAD(r1)
                    353:        lwz     r1,     THREAD_PCB(r1)
                    354: 
                    355:        cmpw    CR0,    r1,     r3      /* If we own FPU, just return */
                    356:        beq     CR0,    .L_fpu_switch_return
                    357:        cmpwi   CR1,    r3,     0       /* If no owner, skip save */
                    358:        beq     CR1,    .L_fpu_switch_load_state
                    359: 
                    360: /*
                    361:  * Identical code to that of fpu_save but is inlined
                    362:  * to avoid creating a stack frame etc.
                    363:  */
                    364:         stfd    f0,   PCB_FS_F0(r3)
                    365:         stfd    f1,   PCB_FS_F1(r3)
                    366:         stfd    f2,   PCB_FS_F2(r3)
                    367:         stfd    f3,   PCB_FS_F3(r3)
                    368:         stfd    f4,   PCB_FS_F4(r3)
                    369:         stfd    f5,   PCB_FS_F5(r3)
                    370:         stfd    f6,   PCB_FS_F6(r3)
                    371:         stfd    f7,   PCB_FS_F7(r3)
                    372:                 mffs    f0                     /* fpscr in f0 low 32 bits*/
                    373:         stfd    f8,   PCB_FS_F8(r3)
                    374:         stfd    f9,   PCB_FS_F9(r3)
                    375:         stfd    f10,  PCB_FS_F10(r3)
                    376:         stfd    f11,  PCB_FS_F11(r3)
                    377:         stfd    f12,  PCB_FS_F12(r3)
                    378:         stfd    f13,  PCB_FS_F13(r3)
                    379:         stfd    f14,  PCB_FS_F14(r3)
                    380:         stfd    f15,  PCB_FS_F15(r3)
                    381:                 stfd    f0,  PCB_FS_FPSCR(r3)  /* Store junk 32 bits+fpscr */
                    382:         stfd    f16,  PCB_FS_F16(r3)
                    383:         stfd    f17,  PCB_FS_F17(r3)
                    384:         stfd    f18,  PCB_FS_F18(r3)
                    385:         stfd    f19,  PCB_FS_F19(r3)
                    386:         stfd    f20,  PCB_FS_F20(r3)
                    387:         stfd    f21,  PCB_FS_F21(r3)
                    388:         stfd    f22,  PCB_FS_F22(r3)
                    389:         stfd    f23,  PCB_FS_F23(r3)
                    390:         stfd    f24,  PCB_FS_F24(r3)
                    391:         stfd    f25,  PCB_FS_F25(r3)
                    392:         stfd    f26,  PCB_FS_F26(r3)
                    393:         stfd    f27,  PCB_FS_F27(r3)
                    394:         stfd    f28,  PCB_FS_F28(r3)
                    395:         stfd    f29,  PCB_FS_F29(r3)
                    396:         stfd    f30,  PCB_FS_F30(r3)
                    397:         stfd    f31,  PCB_FS_F31(r3)
                    398: 
                    399:        stw     r0,     SS_R0(r1)
                    400:        /*
                    401:         * Turn off the FPU for the old owner
                    402:         */
                    403:        lwz     r0,     SS_SRR1(r3)
                    404:        rlwinm  r0,     r0,     0,      MSR_FP_BIT+1,   MSR_FP_BIT-1
                    405:        stw     r0,     SS_SRR1(r3)
                    406: 
                    407:        lwz     r0,     SS_R0(r1)
                    408:        
                    409:        /* Now load in the current threads state */
                    410: 
                    411: .L_fpu_switch_load_state:      
                    412: 
                    413:        /* Store current PCB address in fpu_pcb to claim fpu for thread */
                    414:        stw     r1,     PP_FPU_PCB(r2)
                    415: 
                    416:            lfd    f31,  PCB_FS_FPSCR(r1)       /* Load junk 32 bits+fpscr */
                    417:         lfd     f0,   PCB_FS_F0(r1)
                    418:         lfd     f1,   PCB_FS_F1(r1)
                    419:         lfd     f2,   PCB_FS_F2(r1)
                    420:         lfd     f3,   PCB_FS_F3(r1)
                    421:         lfd     f4,   PCB_FS_F4(r1)
                    422:         lfd     f5,   PCB_FS_F5(r1)
                    423:         lfd     f6,   PCB_FS_F6(r1)
                    424:         lfd     f7,   PCB_FS_F7(r1)
                    425:             mtfsf      0xff,   f31             /* fpscr in f0 low 32 bits*/
                    426:         lfd     f8,   PCB_FS_F8(r1)
                    427:         lfd     f9,   PCB_FS_F9(r1)
                    428:         lfd     f10,  PCB_FS_F10(r1)
                    429:         lfd     f11,  PCB_FS_F11(r1)
                    430:         lfd     f12,  PCB_FS_F12(r1)
                    431:         lfd     f13,  PCB_FS_F13(r1)
                    432:         lfd     f14,  PCB_FS_F14(r1)
                    433:         lfd     f15,  PCB_FS_F15(r1)
                    434:         lfd     f16,  PCB_FS_F16(r1)
                    435:         lfd     f17,  PCB_FS_F17(r1)
                    436:         lfd     f18,  PCB_FS_F18(r1)
                    437:         lfd     f19,  PCB_FS_F19(r1)
                    438:         lfd     f20,  PCB_FS_F20(r1)
                    439:         lfd     f21,  PCB_FS_F21(r1)
                    440:         lfd     f22,  PCB_FS_F22(r1)
                    441:         lfd     f23,  PCB_FS_F23(r1)
                    442:         lfd     f24,  PCB_FS_F24(r1)
                    443:         lfd     f25,  PCB_FS_F25(r1)
                    444:         lfd     f26,  PCB_FS_F26(r1)
                    445:         lfd     f27,  PCB_FS_F27(r1)
                    446:         lfd     f28,  PCB_FS_F28(r1)
                    447:         lfd     f29,  PCB_FS_F29(r1)
                    448:         lfd     f30,  PCB_FS_F30(r1)
                    449:         lfd     f31,  PCB_FS_F31(r1)
                    450: 
                    451: .L_fpu_switch_return:
                    452: 
                    453:        /* the trampoline code takes r1-r3 from sprg1-3, and uses r1-3
                    454:         * as arguments */
                    455: 
                    456:        /* Prepare to rfi to the exception exit routine, which is
                    457:         * in physical address space */
                    458: 
                    459:        addis   r3,     0,      ha16(EXT(exception_exit))
                    460:        addi    r3,     r3,     lo16(EXT(exception_exit))
                    461:        lwz     r3,     0(r3)
                    462:        mtsrr0  r3
                    463:        li      r3,     MSR_VM_OFF
                    464:        mtsrr1  r3
                    465:        
                    466: 
                    467:        lwz     r1,     PCB_SR0(r1)             /* restore current sr0 */
                    468: 
                    469:        lwz     r3,     PP_SAVE_CR(r2)
                    470:        mtcrf   0xFF,r3
                    471:        lwz     r3,     PP_SAVE_SRR1(r2)
                    472:        lwz     r2,     PP_SAVE_SRR0(r2)
                    473:        /* Enable floating point for the thread we're returning to */
                    474:        ori     r3,     r3,     MASK(MSR_FP)    /* bit is in low-order 16 */
                    475:        
                    476:        /* Return to the trapped context */
                    477:        rfi
                    478: 
                    479: /*
                    480:  * void fpu_disable(void)
                    481:  *
                    482:  * disable the fpu in the current msr
                    483:  *
                    484:  */
                    485: 
                    486: ENTRY(fpu_disable, TAG_NO_FRAME_USED)
                    487: 
                    488:        /* See if the current thread owns the FPU, if so, just return */
                    489:        mfsprg  r2,     0               /* HACK - need to get around r2 problem */
                    490:        lwz     r0,     PP_FPU_PCB(r2)
                    491:        cmpwi   CR1,    r0,     0       /* If no owner, skip save */
                    492:        bne     CR1,    .L_fpu_disable_not
                    493: 
                    494:        mfmsr   r0
                    495:        rlwinm  r0,     r0,     0,      MSR_FP_BIT+1,   MSR_FP_BIT-1
                    496:        mtmsr   r0
                    497:        isync
                    498: .L_fpu_disable_not:
                    499:        blr
                    500: 
                    501: ENTRY(fpu_disable_thread, TAG_NO_FRAME_USED)
                    502: 
                    503:        /* Mark the FPU as having no owner now */
                    504:        mfsprg  r2,     0               /* HACK - need to get around r2 problem */
                    505: 
                    506:        lwz     r0,     PP_FPU_PCB(r2)
                    507:        lwz     r3,     PP_CPU_DATA(r2)
                    508:        lwz     r3,     CPU_ACTIVE_THREAD(r3)
                    509:        lwz     r3,     THREAD_PCB(r3)
                    510: 
                    511:        cmpw    CR0,    r0,     r3      /* If we own FPU, disown it */
                    512:        bne     CR0,    .L_thread_not_own
                    513: 
                    514:        li      r0,     0
                    515:        stw     r0,     PP_FPU_PCB(r2)
                    516: .L_thread_not_own:
                    517: 
                    518:        mfmsr   r0
                    519:        rlwinm  r0,     r0,     0,      MSR_FP_BIT+1,   MSR_FP_BIT-1
                    520:        mtmsr   r0
                    521:        isync
                    522:        blr
                    523: 
                    524: /*
                    525:  * void lfs(fpsp,fpdp)
                    526:  *
                    527:  * load the single precision float to the double
                    528:  *
                    529:  * This routine is used by the alignment handler.
                    530:  *
                    531:  */
                    532: ENTRY(lfs, TAG_NO_FRAME_USED)
                    533:         lfs     f1,    0(r3)
                    534:        stfd    f1,     0(r4)
                    535:        blr
                    536: 
                    537: /*
                    538:  * fpsp stfs(fpdp,fpsp)
                    539:  *
                    540:  * store the double precision float to the single
                    541:  *
                    542:  * This routine is used by the alignment handler.
                    543:  *
                    544:  */
                    545: ENTRY(stfs, TAG_NO_FRAME_USED)
                    546:        lfd     f1,     0(r3)
                    547:         stfs   f1,     0(r4)
                    548:        blr
                    549: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.