Annotation of XNU/osfmk/ppc/status.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  * 
        !            25:  */
        !            26: 
        !            27: #include <kern/thread.h>
        !            28: #include <kern/thread_act.h>
        !            29: #include <kern/misc_protos.h>
        !            30: #include <mach/ppc/thread_status.h>
        !            31: #include <ppc/proc_reg.h>
        !            32: #include <ppc/exception.h>
        !            33: #include <ppc/fpu_protos.h>
        !            34: #include <ppc/misc_protos.h>
        !            35: #include <ppc/savearea.h>
        !            36: #include <ppc/thread_act.h>
        !            37: #include <ppc/Firmware.h>
        !            38: 
        !            39: #include <vm/vm_map.h>
        !            40: 
        !            41: extern unsigned int killprint;
        !            42: extern double FloatInit;
        !            43: extern unsigned long QNaNbarbarian[4];
        !            44: extern void thread_bootstrap_return(void);
        !            45: 
        !            46: 
        !            47: struct ppc_saved_state * get_user_regs(thread_act_t);
        !            48: 
        !            49: #define       USRSTACK        0xc0000000
        !            50: 
        !            51: kern_return_t
        !            52: thread_userstack(
        !            53:     thread_t,
        !            54:     int,
        !            55:     thread_state_t,
        !            56:     unsigned int,
        !            57:     vm_offset_t *
        !            58: );
        !            59: 
        !            60: kern_return_t
        !            61: thread_entrypoint(
        !            62:     thread_t,
        !            63:     int,
        !            64:     thread_state_t,
        !            65:     unsigned int,
        !            66:     vm_offset_t *
        !            67: ); 
        !            68: 
        !            69: unsigned int get_msr_exportmask(void);
        !            70: unsigned int get_msr_nbits(void);
        !            71: unsigned int get_msr_rbits(void);
        !            72: void thread_set_child(thread_act_t child, int pid);
        !            73:                
        !            74: /*
        !            75:  * Maps state flavor to number of words in the state:
        !            76:  */
        !            77: unsigned int state_count[] = {
        !            78:        /* FLAVOR_LIST */ 0,
        !            79:        PPC_THREAD_STATE_COUNT,
        !            80:        PPC_FLOAT_STATE_COUNT,
        !            81:        PPC_EXCEPTION_STATE_COUNT,
        !            82: };
        !            83: 
        !            84: /*
        !            85:  * thread_getstatus:
        !            86:  *
        !            87:  * Get the status of the specified thread.
        !            88:  */
        !            89: 
        !            90: kern_return_t 
        !            91: act_machine_get_state(
        !            92:                      thread_act_t           thr_act,
        !            93:                      thread_flavor_t        flavor,
        !            94:                      thread_state_t         tstate,
        !            95:                      mach_msg_type_number_t *count)
        !            96: {
        !            97:        
        !            98:        register struct savearea *sv;                                           /* Pointer to the context savearea */
        !            99:        int i, j;
        !           100:        unsigned int vrvalidwrk;
        !           101: 
        !           102:        register struct ppc_thread_state *ts;
        !           103:        register struct ppc_exception_state *es;
        !           104:        register struct ppc_float_state *fs;
        !           105:        register struct ppc_vector_state *vs;
        !           106:        
        !           107: #if    MACH_ASSERT
        !           108:     if (watchacts & WA_STATE)
        !           109:        printf("act_%x act_machine_get_state(thr_act=%x,flav=%x,st=%x,cnt@%x=%x)\n",
        !           110:               current_act(), thr_act, flavor, tstate,
        !           111:               count, (count ? *count : 0));
        !           112: #endif /* MACH_ASSERT */
        !           113: 
        !           114: 
        !           115:        switch (flavor) {
        !           116:                
        !           117:                case THREAD_STATE_FLAVOR_LIST:
        !           118:                        
        !           119:                        if (*count < 3)  {
        !           120:                                panic("act_machine_get_state: THREAD_STATE_FLAVOR_LIST returns KERN_INVALID_ARGUMENT\n");
        !           121:                                return (KERN_INVALID_ARGUMENT);
        !           122:                        }
        !           123:                
        !           124:                        tstate[0] = PPC_THREAD_STATE;
        !           125:                        tstate[1] = PPC_FLOAT_STATE;
        !           126:                        tstate[2] = PPC_EXCEPTION_STATE;
        !           127:                        *count = 3;
        !           128:                
        !           129:                        return KERN_SUCCESS;
        !           130:        
        !           131:                case PPC_THREAD_STATE:
        !           132:        
        !           133:                        if (*count < PPC_THREAD_STATE_COUNT) {                  /* Is the count ok? */
        !           134:                                panic("act_machine_get_state: PPC_THREAD_STATE returns KERN_INVALID_ARGUMENT\n");
        !           135:                                return KERN_INVALID_ARGUMENT;
        !           136:                        }
        !           137:                
        !           138:                        ts = (struct ppc_thread_state *) tstate;
        !           139: 
        !           140:                        sv = (savearea *)(thr_act->mact.pcb);                   /* Start with the normal savearea */
        !           141:                        while(sv) {                                                                             /* Find the user context */
        !           142:                                if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
        !           143:                                        break;                                                                  /* Outta here */
        !           144:                                }
        !           145:                                sv = sv->save_prev;                                                     /* Back chain */
        !           146:                        }
        !           147:                
        !           148:                        if(sv) {                                                                                /* Is there a save area yet? */
        !           149:                                ts->r0  = sv->save_r0;
        !           150:                                ts->r1  = sv->save_r1;
        !           151:                                ts->r2  = sv->save_r2;
        !           152:                                ts->r3  = sv->save_r3;
        !           153:                                ts->r4  = sv->save_r4;
        !           154:                                ts->r5  = sv->save_r5;
        !           155:                                ts->r6  = sv->save_r6;
        !           156:                                ts->r7  = sv->save_r7;
        !           157:                                ts->r8  = sv->save_r8;
        !           158:                                ts->r9  = sv->save_r9;
        !           159:                                ts->r10 = sv->save_r10;
        !           160:                                ts->r11 = sv->save_r11;
        !           161:                                ts->r12 = sv->save_r12;
        !           162:                                ts->r13 = sv->save_r13;
        !           163:                                ts->r14 = sv->save_r14;
        !           164:                                ts->r15 = sv->save_r15;
        !           165:                                ts->r16 = sv->save_r16;
        !           166:                                ts->r17 = sv->save_r17;
        !           167:                                ts->r18 = sv->save_r18;
        !           168:                                ts->r19 = sv->save_r19;
        !           169:                                ts->r20 = sv->save_r20;
        !           170:                                ts->r21 = sv->save_r21;
        !           171:                                ts->r22 = sv->save_r22;
        !           172:                                ts->r23 = sv->save_r23;
        !           173:                                ts->r24 = sv->save_r24;
        !           174:                                ts->r25 = sv->save_r25;
        !           175:                                ts->r26 = sv->save_r26;
        !           176:                                ts->r27 = sv->save_r27;
        !           177:                                ts->r28 = sv->save_r28;
        !           178:                                ts->r29 = sv->save_r29;
        !           179:                                ts->r30 = sv->save_r30;
        !           180:                                ts->r31 = sv->save_r31;
        !           181:                                ts->cr  = sv->save_cr;
        !           182:                                ts->xer = sv->save_xer;
        !           183:                                ts->lr  = sv->save_lr;
        !           184:                                ts->ctr = sv->save_ctr;
        !           185:                                ts->srr0 = sv->save_srr0;
        !           186:                                ts->srr1 = sv->save_srr1;
        !           187:                                ts->mq  = sv->save_mq;                          /* MQ register (601 only) */
        !           188:                                ts->vrsave      = sv->save_vrsave;              /* VRSAVE register (Altivec only) */
        !           189:                        }
        !           190:                        else {                                                                  /* No user state yet. Save seemingly random values. */
        !           191:                                                
        !           192:                                for(i=0; i < 32; i+=2) {                        /* Fill up with defaults */
        !           193:                                        ((unsigned int *)&ts->r0)[i] = ((unsigned int *)&FloatInit)[0];
        !           194:                                        ((unsigned int *)&ts->r0)[i+1] = ((unsigned int *)&FloatInit)[1];
        !           195:                                }
        !           196:                                ts->cr  = 0;
        !           197:                                ts->xer = 0;
        !           198:                                ts->lr  = ((unsigned int *)&FloatInit)[0];
        !           199:                                ts->ctr = ((unsigned int *)&FloatInit)[1];
        !           200:                                ts->srr0        = ((unsigned int *)&FloatInit)[0];
        !           201:                                ts->srr1 = MSR_EXPORT_MASK_SET;
        !           202:                                ts->mq  = 0;
        !           203:                                ts->vrsave      = 0;                                    /* VRSAVE register (Altivec only) */
        !           204:                        }
        !           205:                
        !           206:                        *count = PPC_THREAD_STATE_COUNT;                /* Pass back the amount we actually copied */
        !           207:                        return KERN_SUCCESS;
        !           208:        
        !           209:                case PPC_EXCEPTION_STATE:
        !           210:        
        !           211:                        if (*count < PPC_EXCEPTION_STATE_COUNT) {
        !           212:                                panic("act_machine_get_state: PPC_EXCEPTION_STATE returns KERN_INVALID_ARGUMENT\n");
        !           213:                                return KERN_INVALID_ARGUMENT;
        !           214:                        }
        !           215:                
        !           216:                        es = (struct ppc_exception_state *) tstate;
        !           217:                
        !           218:                        sv = (savearea *)(thr_act->mact.pcb);                   /* Start with the normal savearea */
        !           219:                        while(sv) {                                                                             /* Find the user context */
        !           220:                                if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
        !           221:                                        break;                                                                  /* Outta here */
        !           222:                                }
        !           223:                                sv = sv->save_prev;                                                     /* Back chain */
        !           224:                        }
        !           225: 
        !           226:                        if(sv) {                                                                        /* See if valid state yet */
        !           227:                                es->dar = sv->save_dar;
        !           228:                                es->dsisr = sv->save_dsisr;
        !           229:                                es->exception = sv->save_exception;
        !           230:                        }
        !           231:                        else {                                                                          /* Nope, not yet */
        !           232:                                es->dar = 0;
        !           233:                                es->dsisr = 0;
        !           234:                                es->exception = ((unsigned int *)&FloatInit)[0];
        !           235:                        }
        !           236:                
        !           237:                        *count = PPC_EXCEPTION_STATE_COUNT;
        !           238:                        return KERN_SUCCESS;
        !           239:        
        !           240:                case PPC_FLOAT_STATE: 
        !           241:                
        !           242:                        if (*count < PPC_FLOAT_STATE_COUNT)  {
        !           243:                                panic("act_machine_get_state: PPC_FLOAT_STATE returns KERN_INVALID_ARGUMENT\n");
        !           244:                                return KERN_INVALID_ARGUMENT;
        !           245:                        }
        !           246:                
        !           247:                        fpu_save();                                                                     /* Just in case it's live, save it */
        !           248:                
        !           249:                        fs = (struct ppc_float_state *) tstate;         /* Point to destination */
        !           250:                        
        !           251:                        sv = (savearea *)(thr_act->mact.FPU_pcb);       /* Start with the top FPU savearea */
        !           252:                        while(sv) {                                                                     /* Find the user context */
        !           253:                                if(!sv->save_level_fp) {                                /* Are we looking at the user context? */
        !           254:                                        break;                                                          /* Outta here */
        !           255:                                }
        !           256:                                sv = sv->save_prev_float;                               /* Back chain */
        !           257:                        }
        !           258:                        
        !           259:                        if(sv) {                                                                        /* See if we have any */
        !           260:                                bcopy((char *)&sv->save_fp0, (char *)fs, 33*8); /* 32 registers plus status and pad */
        !           261:                        }
        !           262:                        else {                                                                          /* No floating point yet */
        !           263:                        
        !           264:                                for(i=0; i < 32; i++) {                                 /* Initialize floating points */
        !           265:                                        fs->fpregs[i] = FloatInit;                      /* Initial value */
        !           266:                                }
        !           267:                                fs->fpscr_pad   = 0;                                    /* Initial value */
        !           268:                                fs->fpscr               = 0;                                    /* Initial value */
        !           269:                        }
        !           270:                        
        !           271:                        *count = PPC_FLOAT_STATE_COUNT;
        !           272:                        
        !           273: #if 0
        !           274:                        for(i=0; i < 32; i++) {                                         /* (TEST/DEBUG) */
        !           275:                                if((*((unsigned int *)&fs->fpregs[i]) >> 16) == 0xFFF8) __asm__ volatile ("tweq r1,r1");        /* (TEST/DEBUG) */
        !           276:                        }
        !           277: #endif
        !           278:                        
        !           279:                        return KERN_SUCCESS;
        !           280:        
        !           281:                case PPC_VECTOR_STATE: 
        !           282:                        
        !           283:                        if (*count < PPC_VECTOR_STATE_COUNT)  {
        !           284:                                panic("act_machine_get_state: PPC_VECTOR_STATE returns KERN_INVALID_ARGUMENT\n");
        !           285:                                return KERN_INVALID_ARGUMENT;
        !           286:                        }
        !           287:                
        !           288:                        vec_save();                                                                     /* Just in case it's live, save it */
        !           289:                
        !           290:                        vs = (struct ppc_vector_state *) tstate;        /* Point to destination */
        !           291:                        
        !           292:                        sv = (savearea *)(thr_act->mact.VMX_pcb);       /* Start with the top FPU savearea */
        !           293:                        while(sv) {                                                                     /* Find the user context */
        !           294:                                if(!sv->save_level_vec) {                               /* Are we looking at the user context? */
        !           295:                                        break;                                                          /* Outta here */
        !           296:                                }
        !           297:                                sv = sv->save_prev_vector;                              /* Back chain */
        !           298:                        }
        !           299:                        
        !           300:                        if(sv) {                                                                        /* See if we have any */
        !           301:                                
        !           302:                                vrvalidwrk = sv->save_vrvalid;                  /* Get the valid flags */
        !           303:                                vs->save_vrvalid = sv->save_vrvalid;    /* Set the valid flags */
        !           304:                                for(j=0; j < 4; j++) vs->save_vscr[j] = sv->save_vscr[j];       /* Set value for vscr */
        !           305:                                
        !           306:                                for(i=0; i < 32; i++) {                                 /* Copy the saved registers and invalidate the others */
        !           307:                                        for(j=0; j < 4; j++) {
        !           308:                                                if(vrvalidwrk & 0x80000000) (vs->save_vr)[i][j] = 
        !           309:                                                                ((unsigned long **)(&sv->save_vr0))[i][j];      /* We have this register saved */
        !           310:                                                else vs->save_vr[i][j] = QNaNbarbarian[j];      /* Set invalid value */
        !           311:                                        }
        !           312:                                        vrvalidwrk = vrvalidwrk << 1;           /* Shift over to the next */
        !           313:                                }
        !           314:                        }
        !           315:                        else {                                                                          /* No vector yet */
        !           316:                        
        !           317:                                for(i=0; i < 32; i++) {                                 /* Initialize vector registers */
        !           318:                                        for(j=0; j < 4; j++) vs->save_vr[i][j] = QNaNbarbarian[j];              /* Initial value */
        !           319:                                }
        !           320:                                for(j=0; j < 4; j++) vs->save_vscr[j] = 0;      /* Initial value */
        !           321:                                vs->save_vrvalid = 0;                                   /* Clear the valid flags */
        !           322:                        }
        !           323:                        
        !           324:                        for (i=0; i < 4; i++) vs->save_pad5[i] = 0;     /* Clear cruft */
        !           325:                        for (i=0; i < 7; i++) vs->save_pad6[i] = 0;     /* Clear cruft */
        !           326:                        
        !           327:                        *count = PPC_VECTOR_STATE_COUNT;
        !           328:                        return KERN_SUCCESS;
        !           329:        
        !           330:                default:
        !           331:                        panic("act_machine_get_state: default returns KERN_INVALID_ARGUMENT\n");
        !           332:                        return KERN_INVALID_ARGUMENT;
        !           333:        }
        !           334: }
        !           335: 
        !           336: 
        !           337: /*
        !           338:  * thread_setstatus:
        !           339:  *
        !           340:  * Set the status of the specified thread.
        !           341:  */
        !           342: kern_return_t 
        !           343: act_machine_set_state(
        !           344:                      thread_act_t           thr_act,
        !           345:                      thread_flavor_t        flavor,
        !           346:                      thread_state_t         tstate,
        !           347:                      mach_msg_type_number_t count)
        !           348: {
        !           349:   
        !           350:        savearea                *sv, *osv, *usv, *ssv;
        !           351:        unsigned int    spc, i, *srs, isnew, clgn;
        !           352:        register struct ppc_thread_state *ts;
        !           353:        register struct ppc_exception_state *es;
        !           354:        register struct ppc_float_state *fs;
        !           355:        register struct ppc_vector_state *vs;
        !           356:        spl_t                   spl;
        !           357:        
        !           358:     int        kernel_act = thr_act->kernel_loading || thr_act->kernel_loaded;
        !           359: 
        !           360: #if    MACH_ASSERT
        !           361:     if (watchacts & WA_STATE)
        !           362:        printf("act_%x act_machine_set_state(thr_act=%x,flav=%x,st=%x,cnt=%x)\n",
        !           363:               current_act(), thr_act, flavor, tstate, count);
        !           364: #endif /* MACH_ASSERT */
        !           365:                
        !           366: //     dbgTrace((unsigned int)thr_act, (unsigned int)sv, flavor);      /* (TEST/DEBUG) */
        !           367: 
        !           368:        clgn = count;                                                                                   /* Get the count */
        !           369:        
        !           370:        switch (flavor) {                                                                               /* Validate the count before we do anything else */
        !           371:                case PPC_THREAD_STATE:
        !           372:                        
        !           373:                        if (clgn < PPC_THREAD_STATE_COUNT)  {                   /* Is it too short? */
        !           374:                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
        !           375:                        }
        !           376:                        
        !           377:                        if(clgn > PPC_THREAD_STATE_COUNT) clgn = PPC_THREAD_STATE_COUNT;        /* If too long, pin it at max */
        !           378:                        break;
        !           379:                        
        !           380:                case PPC_EXCEPTION_STATE:
        !           381:                        
        !           382:                        if (clgn < PPC_EXCEPTION_STATE_COUNT)  {                /* Is it too short? */
        !           383:                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
        !           384:                        }
        !           385:                        
        !           386:                        if(clgn > PPC_EXCEPTION_STATE_COUNT) clgn = PPC_EXCEPTION_STATE_COUNT;  /* If too long, pin it at max */
        !           387:                        break;
        !           388:                        
        !           389:                case PPC_FLOAT_STATE:
        !           390:                        
        !           391:                        if (clgn < PPC_FLOAT_STATE_COUNT)  {                    /* Is it too short? */
        !           392:                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
        !           393:                        }
        !           394:                        
        !           395:                        if(clgn > PPC_FLOAT_STATE_COUNT) clgn = PPC_FLOAT_STATE_COUNT;  /* If too long, pin it at max */
        !           396:                        break;
        !           397:                        
        !           398: 
        !           399:                case PPC_VECTOR_STATE:
        !           400:                        
        !           401:                        if (clgn < PPC_VECTOR_STATE_COUNT)  {                   /* Is it too short? */
        !           402:                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
        !           403:                        }
        !           404:                        
        !           405:                        if(clgn > PPC_VECTOR_STATE_COUNT) clgn = PPC_VECTOR_STATE_COUNT;        /* If too long, pin it at max */
        !           406:                        break;
        !           407:                        
        !           408:                default:
        !           409:                        return KERN_INVALID_ARGUMENT;
        !           410:        }
        !           411: 
        !           412:     isnew = 0;                                                                                         /* Remember when we make a new one */
        !           413:        
        !           414:        switch (flavor) {
        !           415:                
        !           416:                case PPC_THREAD_STATE:
        !           417:                case PPC_EXCEPTION_STATE:
        !           418:                                
        !           419:                        ts = (struct ppc_thread_state *)tstate;
        !           420:                
        !           421:                        sv = (savearea *)thr_act->mact.pcb;                             /* Get the top savearea on the stack */
        !           422:                        osv = 0;                                                                                /* Set no user savearea yet */  
        !           423:                        
        !           424:                        while(sv) {                                                                             /* Find the user context */
        !           425:                                if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
        !           426:                                        break;                                                                  /* Outta here */
        !           427:                                }
        !           428:                                osv = sv;                                                                       /* Save the last one */
        !           429:                                sv = sv->save_prev;                                                     /* Get the previous context */
        !           430:                        }
        !           431:                
        !           432:                        if(!sv) {                                                                               /* We didn't find a user context so allocate and initialize one */
        !           433:                                isnew = 1;                                                                      /* Remember we made a new one */
        !           434:                                sv = save_alloc();                                                      /* Get one */
        !           435:                                sv->save_act = thr_act;                                         /* Point to the activation */
        !           436:                                sv->save_flags |= SAVattach;                            /* Say that it is in use  */
        !           437:                                sv->save_srr1 = MSR_EXPORT_MASK_SET & ~MASK(MSR_PR);    /* Assume kernel state */
        !           438:                                
        !           439:                                spc=(unsigned int)thr_act->map->pmap->space;    /* Get the space we're in */
        !           440:                                
        !           441:                                srs=(unsigned int *)&sv->save_sr0;                      /* Point to the SRs */
        !           442:                                for(i=0; i < 16; i++) {                                         /* Fill in the SRs for the new context */
        !           443:                                        srs[i] = SEG_REG_PROT | (i<<20) | spc;  /* Set the SR */
        !           444:                                }
        !           445:                                
        !           446:                                sv->save_sr_copyin = SEG_REG_PROT | (SR_COPYIN_NUM<<20) | spc;  /* Make sure the copyin is set */
        !           447:                                
        !           448:                                if(osv) {                                                                       /* Did we already have one? */
        !           449:                                        osv->save_prev = sv;                                    /* Chain us on the end */
        !           450:                                }
        !           451:                                else {                                                                          /* We are the first */
        !           452:                                        thr_act->mact.pcb = (pcb_t)sv;                  /* Put it there */
        !           453:                                }
        !           454:                                sv->save_prev = 0;                                                      /* Properly terminate the chain */
        !           455: 
        !           456:                        }
        !           457:                        
        !           458:                        if(flavor == PPC_THREAD_STATE) {                                /* Are we updating plain state? */
        !           459:                        
        !           460:                                sv->save_r0             = ts->r0;
        !           461:                                sv->save_r1             = ts->r1;
        !           462:                                sv->save_r2             = ts->r2;
        !           463:                                sv->save_r3             = ts->r3;
        !           464:                                sv->save_r4             = ts->r4;
        !           465:                                sv->save_r5             = ts->r5;
        !           466:                                sv->save_r6             = ts->r6;
        !           467:                                sv->save_r7             = ts->r7;
        !           468:                                sv->save_r8             = ts->r8;
        !           469:                                sv->save_r9             = ts->r9;
        !           470:                                sv->save_r10    = ts->r10;
        !           471:                                sv->save_r11    = ts->r11;
        !           472:                                sv->save_r12    = ts->r12;
        !           473:                                sv->save_r13    = ts->r13;
        !           474:                                sv->save_r14    = ts->r14;
        !           475:                                sv->save_r15    = ts->r15;
        !           476:                                sv->save_r16    = ts->r16;
        !           477:                                sv->save_r17    = ts->r17;
        !           478:                                sv->save_r18    = ts->r18;
        !           479:                                sv->save_r19    = ts->r19;
        !           480:                                sv->save_r20    = ts->r20;
        !           481:                                sv->save_r21    = ts->r21;
        !           482:                                sv->save_r22    = ts->r22;
        !           483:                                sv->save_r23    = ts->r23;
        !           484:                                sv->save_r24    = ts->r24;
        !           485:                                sv->save_r25    = ts->r25;
        !           486:                                sv->save_r26    = ts->r26;
        !           487:                                sv->save_r27    = ts->r27;
        !           488:                                sv->save_r28    = ts->r28;
        !           489:                                sv->save_r29    = ts->r29;
        !           490:                                sv->save_r30    = ts->r30;
        !           491:                                sv->save_r31    = ts->r31;
        !           492:                        
        !           493:                                sv->save_cr             = ts->cr;
        !           494:                                sv->save_xer    = ts->xer;
        !           495:                                sv->save_lr             = ts->lr;
        !           496:                                sv->save_ctr    = ts->ctr;
        !           497:                                sv->save_srr0   = ts->srr0;
        !           498:                                sv->save_mq             = ts->mq;       
        !           499:                                sv->save_vrsave = ts->vrsave;                                   /* VRSAVE register (Altivec only) */
        !           500:                                sv->save_srr1   = MSR_PREPARE_FOR_IMPORT(sv->save_srr1, ts->srr1);      /* Set the bits we can change */
        !           501:        
        !           502:                                if(!kernel_act) sv->save_srr1 |= MSR_EXPORT_MASK_SET;   /* If not a kernel guy, force the magic bits on */      
        !           503:                        
        !           504:                                sv->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_FP));        /* Make sure we don't enable the floating point unit */
        !           505:                        
        !           506:                                if(isnew) {                                                                             /* Is it a new one? */
        !           507:                                        sv->save_dar = 0;                                                       /* Yes, these need initialization also */
        !           508:                                        sv->save_dsisr = 0;
        !           509:                                        sv->save_exception = 0;
        !           510:                                }
        !           511:                                
        !           512:                                return KERN_SUCCESS;
        !           513:                        }
        !           514:                        else {                                                                                          /* This must be exception state */
        !           515:                                if(isnew)                                                                               /* If new, we need to initialize the normal registers */
        !           516:                                        for(i=0; i < 32; i+=2) {                                        /* Fill up with defaults */
        !           517:                                                ((unsigned int *)&sv->save_r0)[i] = ((unsigned int *)&FloatInit)[0];
        !           518:                                                ((unsigned int *)&sv->save_r0)[i+1] = ((unsigned int *)&FloatInit)[1];
        !           519:                                        }
        !           520:                                        sv->save_cr     = 0;
        !           521:                                        sv->save_xer    = 0;
        !           522:                                        sv->save_lr     = ((unsigned int *)&FloatInit)[0];
        !           523:                                        sv->save_ctr    = ((unsigned int *)&FloatInit)[1];
        !           524:                                        sv->save_srr0   = ((unsigned int *)&FloatInit)[0];
        !           525:                                        sv->save_srr1 = MSR_EXPORT_MASK_SET;
        !           526:                                        sv->save_mq     = 0;
        !           527:                                        sv->save_vrsave = 0;                                            /* VRSAVE register (Altivec only) */
        !           528:                        }
        !           529: 
        !           530:                        es = (struct ppc_exception_state *) tstate;
        !           531:                
        !           532:                        sv->save_dar = es->dar;
        !           533:                        sv->save_dsisr = es->dsisr;
        !           534:                        sv->save_exception = es->exception;
        !           535: 
        !           536:                        return KERN_SUCCESS;
        !           537:        
        !           538:                case PPC_FLOAT_STATE:
        !           539: 
        !           540:                        spl = splhigh();                                                                /* Don't bother me while I'm zapping the owner stuff */
        !           541:                        
        !           542:                        if (per_proc_info[cpu_number()].FPU_thread == (unsigned int)thr_act)    /* If we own the FPU, and */
        !           543:                                if(!thr_act->mact.FPU_lvl) per_proc_info[cpu_number()].FPU_thread = 0; /* it's user level, say we don't own it any more */
        !           544:                        
        !           545:                        splx(spl);                                                                              /* Restore the interrupt level */
        !           546:                        
        !           547:                        sv = (savearea *)thr_act->mact.FPU_pcb;                 /* Get the top savearea on the stack */
        !           548:                        osv = 0;                                                                                /* Set no user savearea yet */  
        !           549:                        
        !           550:                        while(sv) {                                                                             /* Find the user context */
        !           551:                                if(!(sv->save_level_fp)) {                                      /* Are we looking at the user context? */
        !           552:                                        break;                                                                  /* Outta here */
        !           553:                                }
        !           554:                                osv = sv;                                                                       /* Save the last one */
        !           555:                                sv = sv->save_prev_float;                                       /* Get the previous context */
        !           556:                        }
        !           557:                        
        !           558:                        if(!sv) {                                                                               /* We didn't find a user context so allocate and initialize one */
        !           559:        
        !           560:                                sv = (savearea *)thr_act->mact.pcb;                     /* Point to the top savearea on the normal stack */
        !           561:        
        !           562:                                while(sv) {                                                                     /* Have we hit the end? */
        !           563:                                        if(!(sv->save_flags & SAVfpuvalid)) break;      /* Is floating point in use here? */
        !           564:                                        sv = sv->save_prev;                                             /* Back chain */
        !           565:                                }
        !           566:        
        !           567:                                if(!sv) {                                                                       /* If there wasn't one on the normal chain, check vector */
        !           568:                                        sv = (savearea *)thr_act->mact.VMX_pcb; /* Point to the top savearea on the vector stack */
        !           569:                                        while(sv) {                                                             /* Have we hit the end? */
        !           570:                                                if(!(sv->save_flags & SAVfpuvalid)) break;      /* Is floating point in use here? */
        !           571:                                                sv = sv->save_prev_vector;                      /* Back chain */
        !           572:                                        }
        !           573:                                }
        !           574:                                
        !           575:                                if(!sv) {                                                                       /* Do we have one yet? */
        !           576:                                        sv = save_alloc();                                              /* If we still don't have one, get a new one */
        !           577:                                        sv->save_act = thr_act;                                 /* Point to the activation */
        !           578:                                        
        !           579:                                        spc=(unsigned int)thr_act->map->pmap->space;    /* Get the space we're in */
        !           580:                                        
        !           581:                                        srs=(unsigned int *)&sv->save_sr0;              /* Point to the SRs */
        !           582:                                        for(i=0; i < 16; i++) {                                 /* Fill in the SRs for the new context */
        !           583:                                                srs[i] = SEG_REG_PROT | (i<<20) | spc;  /* Set the SR */
        !           584:                                        }
        !           585:                                        
        !           586:                                        sv->save_sr_copyin = SEG_REG_PROT | (SR_COPYIN_NUM<<20) | spc;  /* Make sure the copyin is set */
        !           587:                                }
        !           588:                                        
        !           589:                                if(osv) {                                                                       /* Did we already have one? */
        !           590:                                        osv->save_prev_float = sv;                              /* Chain us on the end */
        !           591:                                }
        !           592:                                else {                                                                          /* We are the first */
        !           593:                                        thr_act->mact.FPU_pcb = (pcb_t)sv;              /* Put it there */
        !           594:                                }
        !           595:                                sv->save_prev_float = 0;                                        /* Properly terminate the chain */
        !           596:                                sv->save_level_fp = 0;                                          /* Make sure we are for the user level */
        !           597:                                sv->save_flags |= SAVfpuvalid;                          /* Say that it is in use by floating point */
        !           598:                        }
        !           599: 
        !           600:                        
        !           601:                        fs = (struct ppc_float_state *) tstate;                 /* Point to source */
        !           602: 
        !           603: #if 0
        !           604:                        for(i=0; i < 32; i++) {                                         /* (TEST/DEBUG) */
        !           605:                                if((*((unsigned int *)&fs->fpregs[i]) >> 16) == 0xFFF8) __asm__ volatile ("tweq r1,r1");        /* (TEST/DEBUG) */
        !           606:                        }
        !           607: #endif
        !           608:                
        !           609:                        bcopy((char *)fs, (char *)&sv->save_fp0, clgn*4); /* 32 registers plus status and pad */
        !           610:                
        !           611:                        return KERN_SUCCESS;
        !           612:                        
        !           613:        
        !           614:                case PPC_VECTOR_STATE:
        !           615: 
        !           616:                        spl = splhigh();                                                                /* Don't bother me while I'm zapping the owner stuff */
        !           617:                        
        !           618:                        if (per_proc_info[cpu_number()].VMX_thread == (unsigned int)thr_act)    /* If we own the vector, and */
        !           619:                                if(!thr_act->mact.VMX_lvl) per_proc_info[cpu_number()].VMX_thread = 0; /* it's user level, say we don't own it any more */
        !           620:                        
        !           621:                        splx(spl);                                                                              /* Restore the interrupt level */
        !           622:                        
        !           623:                        sv = (savearea *)thr_act->mact.VMX_pcb;                 /* Get the top savearea on the stack */
        !           624:                        osv = 0;                                                                                /* Set no user savearea yet */  
        !           625:                        
        !           626:                        while(sv) {                                                                             /* Find the user context */
        !           627:                                if(!(sv->save_level_vec)) {                                     /* Are we looking at the user context? */
        !           628:                                        break;                                                                  /* Outta here */
        !           629:                                }
        !           630:                                osv = sv;                                                                       /* Save the last one */
        !           631:                                sv = sv->save_prev_vector;                                      /* Get the previous context */
        !           632:                        }
        !           633:                        
        !           634:                        if(!sv) {                                                                               /* We didn't find a user context so allocate and initialize one */
        !           635:        
        !           636:                                sv = (savearea *)thr_act->mact.pcb;                     /* Point to the top savearea on the normal stack */
        !           637:        
        !           638:                                while(sv) {                                                                     /* Have we hit the end? */
        !           639:                                        if(!(sv->save_flags & SAVvmxvalid)) break;      /* Is vector in use here? */
        !           640:                                        sv = sv->save_prev;                                             /* Back chain */
        !           641:                                }
        !           642:        
        !           643:                                if(!sv) {                                                                       /* If there wasn't one on the normal chain, check vector */
        !           644:                                        sv = (savearea *)thr_act->mact.FPU_pcb; /* Point to the top savearea on the FPU stack */
        !           645:                                        while(sv) {                                                             /* Have we hit the end? */
        !           646:                                                if(!(sv->save_flags & SAVvmxvalid)) break;      /* Is vector in use here? */
        !           647:                                                sv = sv->save_prev_float;                       /* Get the previous context */
        !           648:                                        }
        !           649:                                }
        !           650:                                
        !           651:                                if(!sv) {                                                                       /* Do we have one yet? */
        !           652:                                        sv = save_alloc();                                              /* If we still don't have one, get a new one */
        !           653:                                        sv->save_act = thr_act;                                 /* Point to the activation */
        !           654:                                        
        !           655:                                        spc=(unsigned int)thr_act->map->pmap->space;    /* Get the space we're in */
        !           656:                                        
        !           657:                                        srs=(unsigned int *)&sv->save_sr0;              /* Point to the SRs */
        !           658:                                        for(i=0; i < 16; i++) {                                 /* Fill in the SRs for the new context */
        !           659:                                                srs[i] = SEG_REG_PROT | (i<<20) | spc;  /* Set the SR */
        !           660:                                        }
        !           661:                                        
        !           662:                                        sv->save_sr_copyin = SEG_REG_PROT | (SR_COPYIN_NUM<<20) | spc;  /* Make sure the copyin is set */
        !           663:                                }
        !           664:                                        
        !           665:                                if(osv) {                                                                       /* Did we already have one? */
        !           666:                                        osv->save_prev_vector = sv;                             /* Chain us on the end */
        !           667:                                }
        !           668:                                else {                                                                          /* We are the first */
        !           669:                                        thr_act->mact.VMX_pcb = (pcb_t)sv;              /* Put it there */
        !           670:                                }
        !           671:                                sv->save_prev_vector = 0;                                       /* Properly terminate the chain */
        !           672:                                sv->save_level_vec = 0;                                         /* Make sure we are for the user level */
        !           673:                                sv->save_flags |= SAVvmxvalid;                          /* Say that it is in use by vector */
        !           674:                        }
        !           675: 
        !           676:                        
        !           677:                        vs = (struct ppc_vector_state *) tstate;                /* Point to source */
        !           678:                
        !           679:                        bcopy((char *)vs, (char *)&sv->save_vr0, clgn*4); /* 32 registers plus status and validity and pad */
        !           680:                
        !           681:                        return KERN_SUCCESS;
        !           682:                        
        !           683:                
        !           684:                default:
        !           685:                        return KERN_INVALID_ARGUMENT;
        !           686:     }
        !           687: }
        !           688: 
        !           689: /*
        !           690:  *             Duplicates the context of one thread into a new one.
        !           691:  *             The new thread is assumed to be new and have no user state contexts.
        !           692:  *             We also assume that the old thread can't be running anywhere.
        !           693:  *
        !           694:  *             We're only going to be duplicating user context here.  That means that we will have to 
        !           695:  *             eliminate any floating point or vector kernel contexts and carry across the user state ones.
        !           696:  *             We will optimize and cram all states into one savearea.  Actually that will be the easiest thing
        !           697:  *             to do.
        !           698:  */
        !           699: 
        !           700: void act_thread_dup(thread_act_t old, thread_act_t new) {
        !           701: 
        !           702:        savearea                *sv, *osv, *fsv;
        !           703:        unsigned int    spc, i, *srs;
        !           704:        
        !           705:        fpu_save();                                                                             /* Make certain floating point state is all saved */
        !           706:        vec_save();                                                                             /* Make certain the vector state is all saved */
        !           707:        
        !           708:        osv = (savearea *)new->mact.pcb;                                /* Get the top savearea on the stack */
        !           709:        sv = 0;                                                                                 /* Set no new user savearea yet */      
        !           710:        
        !           711:        while(osv) {                                                                    /* Find the user context */
        !           712:                if(osv->save_srr1 & MASK(MSR_PR)) {                     /* Are we looking at the user context? */
        !           713:                        sv=osv;                                                                 /* Say which to use */
        !           714:                        break;                                                                  /* Outta here */
        !           715:                }
        !           716:                osv=osv->save_prev;                                                     /* Get the previous context */
        !           717:        }
        !           718:        
        !           719:        if(!sv) {                                                                               /* We didn't find a user context so allocate and initialize one */
        !           720:                osv = (savearea *)new->mact.pcb;                        /* Point to the top savearea on the stack */
        !           721:                sv = save_alloc();                                                      /* Get one */
        !           722:                sv->save_flags |= SAVattach;                            /* Say that it is in use  */
        !           723:                sv->save_act = new;                                                     /* Point to the activation */
        !           724:                
        !           725:                spc=(unsigned int)new->map->pmap->space;        /* Get the space we're in */
        !           726:                
        !           727:                srs=(unsigned int *)&sv->save_sr0;                      /* Point to the SRs */
        !           728:                for(i=0; i < 16; i++) {                                         /* Fill in the SRs for the new context */
        !           729:                        srs[i] = SEG_REG_PROT | (i<<20) | spc;  /* Set the SR */
        !           730:                }
        !           731:                
        !           732:                sv->save_sr_copyin = SEG_REG_PROT | (SR_COPYIN_NUM<<20) | spc;  /* Make sure the copyin is set */
        !           733:                
        !           734:                if(osv) {                                                                       /* Did we already have one? */
        !           735:                        sv->save_prev = osv->save_prev;                 /* Move the back chain of the top savearea */
        !           736:                        osv->save_prev = sv;                                    /* Chain us just after it */
        !           737:                }
        !           738:                else {                                                                          /* We are the first */
        !           739:                        new->mact.pcb = (pcb_t)sv;                              /* Make it the active one */
        !           740:                }
        !           741:                
        !           742:        }
        !           743: 
        !           744:        osv = (savearea *)(old->mact.pcb);                              /* Start with the normal savearea */
        !           745:        while(osv) {                                                                    /* Find the user context */
        !           746:                if(osv->save_srr1 & MASK(MSR_PR)) {                     /* Are we looking at the user context? */
        !           747:                        break;                                                                  /* Outta here */
        !           748:                }
        !           749:                osv = osv->save_prev;                                           /* Back chain */
        !           750:        }
        !           751: 
        !           752:        bcopy((char *)&osv->save_srr0, (char *)&sv->save_srr0, sizeof(struct ppc_thread_state)); /* Copy in normal state stuff */
        !           753:        
        !           754:        new->mact.FPU_pcb = (pcb_t)0 ;                                  /* Initialize floating point savearea */
        !           755:        new->mact.FPU_lvl = (pcb_t)0 ;                                  /* Initialize floating point level */
        !           756:        new->mact.FPU_cpu = 0 ;                                                 /* Initialize last used cpu (FP not live, so this doesn't really matter) */
        !           757:        new->mact.VMX_pcb = (pcb_t)0 ;                                  /* Initialize vector savearea */
        !           758:        new->mact.VMX_lvl = (pcb_t)0 ;                                  /* Initialize vector level */
        !           759:        new->mact.VMX_cpu = 0 ;                                                 /* Initialize last used cpu (vector not live, so this doesn't reall matter) */
        !           760: 
        !           761:        sv->save_prev_float = (savearea *)0;                    /* Clear the back chain */
        !           762:        sv->save_prev_vector = (savearea *)0;                   /* Clear the back chain */
        !           763:        
        !           764:        sv->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));       /* Make certain that floating point and vector are turned off */
        !           765:        
        !           766:        fsv = (savearea *)old->mact.FPU_pcb;                    /* Get the start of the floating point chain */
        !           767:        while(fsv) {                                                                    /* Look until the end or we find it */
        !           768:                if(!(fsv->save_level_fp)) {                                     /* Is the the user state stuff? (the level is 0 if so) */       
        !           769:                        sv->save_flags |= SAVfpuvalid;                  /* Show we have it */
        !           770:                        bcopy((char *)&osv->save_fp0, (char *)&sv->save_fp0, sizeof(struct ppc_float_state)); /* Copy in floating point state stuff */
        !           771:                        new->mact.FPU_pcb = (pcb_t)sv;                  /* Make it the active one */
        !           772:                        break;                                                                  /* Done, everything else is all set up... */
        !           773:                }
        !           774:                fsv = fsv->save_prev_float;                                     /* Try the previous one */
        !           775:        }
        !           776:        
        !           777:        fsv = (savearea *)old->mact.VMX_pcb;                    /* Get the start of the vector chain */
        !           778:        while(fsv) {                                                                    /* Look until the end or we find it */
        !           779:                if(!(fsv->save_level_vec)) {                            /* Is the the user state stuff? (the level is 0 if so) */       
        !           780:                        sv->save_flags |= SAVvmxvalid;                  /* Show we have it */
        !           781:                        bcopy((char *)&osv->save_vr0, (char *)&sv->save_vr0, sizeof(struct ppc_vector_state)); /* Copy in Altivec state stuff */
        !           782:                        new->mact.VMX_pcb = (pcb_t)sv;                  /* Make it the active one */
        !           783:                        break;                                                                  /* Done, everything else is all set up... */
        !           784:                }
        !           785:                fsv = fsv->save_prev_vector;                            /* Try the previous one */
        !           786:        }
        !           787: 
        !           788:        return;                                                                                 /* Bye bye... */
        !           789: }
        !           790: 
        !           791: /*
        !           792:  *             Initializes a fresh set of user state values.  If there is no user state context,
        !           793:  *             one is created. Floats and VMX are not created. We set initial values for everything.
        !           794:  */
        !           795: 
        !           796: struct ppc_saved_state * get_user_regs(thread_act_t act) {
        !           797: 
        !           798:        savearea                *sv, *osv;
        !           799:        unsigned int    spc, i, *srs;
        !           800: 
        !           801:        sv = (savearea *)act->mact.pcb;                                 /* Get the top savearea on the stack */
        !           802:        osv = 0;                                                                                /* Set no user savearea yet */  
        !           803:        
        !           804:        while(sv) {                                                                             /* Find the user context */
        !           805:                if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
        !           806:                        break;                                                                  /* Outta here */
        !           807:                }
        !           808:                osv = sv;                                                                       /* Save the last one */
        !           809:                sv = sv->save_prev;                                                     /* Get the previous context */
        !           810:        }
        !           811: 
        !           812:        if(!sv) {                                                                               /* We didn't find a user context so allocate and initialize one */
        !           813:                sv = save_alloc();                                                      /* Get one */
        !           814:                sv->save_flags |= SAVattach;                            /* Say that it is in use  */
        !           815:                sv->save_act = act;                                                     /* Point to the activation */
        !           816:                
        !           817:                if(osv) {                                                                       /* Did we already have one? */
        !           818:                        osv->save_prev = sv;                                    /* Chain us on the end */
        !           819:                }
        !           820:                else {                                                                          /* We are the first */
        !           821:                        act->mact.pcb = (pcb_t)sv;                              /* Put it there */
        !           822:                }
        !           823:                sv->save_prev = 0;                                                      /* Properly terminate the chain */
        !           824: 
        !           825:        }
        !           826: 
        !           827:        for(i=0; i < 32; i+=2) {                                                /* Fill up with defaults */
        !           828:                ((unsigned int *)&sv->save_r0)[i] = ((unsigned int *)&FloatInit)[0];
        !           829:                ((unsigned int *)&sv->save_r0)[i+1] = ((unsigned int *)&FloatInit)[1];
        !           830:        }
        !           831:        sv->save_cr     = 0;
        !           832:        sv->save_xer    = 0;
        !           833:        sv->save_lr     = ((unsigned int *)&FloatInit)[0];
        !           834:        sv->save_ctr    = ((unsigned int *)&FloatInit)[1];
        !           835:        sv->save_srr0   = ((unsigned int *)&FloatInit)[0];
        !           836:        sv->save_srr1 = MSR_EXPORT_MASK_SET;
        !           837:        sv->save_mq     = 0;
        !           838:        /* XXX: TO BE REMOVED WA for AltiVec compiler bug */
        !           839:        sv->save_vrsave = 0xffffffff;                                           /* VRSAVE register (Altivec only) */
        !           840:        
        !           841:        spc=(unsigned int)act->map->pmap->space;                /* Get the space we're in */
        !           842:        
        !           843:        srs=(unsigned int *)&sv->save_sr0;                              /* Point to the SRs */
        !           844:        for(i=0; i < 16; i++) {                                                 /* Fill in the SRs for the new context */
        !           845:                srs[i] = SEG_REG_PROT | (i<<20) | spc;          /* Set the SR */
        !           846:        }
        !           847:        
        !           848:        sv->save_sr_copyin = SEG_REG_PROT | (SR_COPYIN_NUM<<20) | spc;  /* Make sure the copyin is set */
        !           849:        
        !           850:        return (struct ppc_saved_state *)sv;                    /* Bye bye... */
        !           851: }
        !           852: 
        !           853: /*
        !           854:  *             Find the user state context.  If there is no user state context,
        !           855:  *             we just return a 0.
        !           856:  */
        !           857: 
        !           858: struct ppc_saved_state * find_user_regs(thread_act_t act) {
        !           859: 
        !           860:        savearea                *sv;
        !           861: 
        !           862:        sv = (savearea *)act->mact.pcb;                                 /* Get the top savearea on the stack */
        !           863:        
        !           864:        while(sv) {                                                                             /* Find the user context */
        !           865:                if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
        !           866:                        break;                                                                  /* Outta here */
        !           867:                }
        !           868:                sv = sv->save_prev;                                                     /* Get the previous context */
        !           869:        }
        !           870:        
        !           871:        return (struct ppc_saved_state *)sv;                    /* Bye bye... */
        !           872: }
        !           873: 
        !           874: /*
        !           875:  *             Find the user state floating pointcontext.  If there is no user state context,
        !           876:  *             we just return a 0.
        !           877:  */
        !           878: 
        !           879: struct ppc_float_state * find_user_fpu(thread_act_t act) {
        !           880: 
        !           881:        savearea                *fsv;
        !           882: 
        !           883:        fsv = (savearea *)act->mact.FPU_pcb;                    /* Get the start of the floating point chain */
        !           884:        while(fsv) {                                                                    /* Look until the end or we find it */
        !           885:                if(!(fsv->save_level_fp)) break;                        /* Is the the user state stuff? (the level is 0 if so) */       
        !           886:                fsv = fsv->save_prev_float;                                     /* Try the previous one */
        !           887:        }
        !           888:        
        !           889:        return (struct ppc_float_state *)&(fsv->save_fp0);      /* Bye bye... */
        !           890: }
        !           891: 
        !           892: /*
        !           893:  * thread_userstack:
        !           894:  *
        !           895:  * Return the user stack pointer from the machine
        !           896:  * dependent thread state info.
        !           897:  */
        !           898: kern_return_t
        !           899: thread_userstack(
        !           900:     thread_t            thread,
        !           901:     int                 flavor,
        !           902:     thread_state_t      tstate,
        !           903:     unsigned int        count,
        !           904:     vm_offset_t         *user_stack
        !           905: )
        !           906: {
        !           907:         struct ppc_thread_state *state;
        !           908: 
        !           909:         /*
        !           910:          * Set a default.
        !           911:          */
        !           912:         if (*user_stack == 0)
        !           913:                 *user_stack = USRSTACK;
        !           914: 
        !           915:         switch (flavor) {
        !           916:         case PPC_THREAD_STATE:
        !           917:                 if (count < PPC_THREAD_STATE_COUNT)
        !           918:                         return (KERN_INVALID_ARGUMENT);
        !           919:  
        !           920:                 state = (struct ppc_thread_state *) tstate;
        !           921:     
        !           922:                 /*
        !           923:                  * If a valid user stack is specified, use it.
        !           924:                  */
        !           925:                 *user_stack = state->r1 ? state->r1: USRSTACK;
        !           926:                 break;
        !           927:         default :
        !           928:                 return (KERN_INVALID_ARGUMENT);
        !           929:         }
        !           930:                 
        !           931:         return (KERN_SUCCESS);
        !           932: }    
        !           933: 
        !           934: kern_return_t
        !           935: thread_entrypoint(
        !           936:     thread_t            thread,
        !           937:     int                 flavor,
        !           938:     thread_state_t      tstate,
        !           939:     unsigned int        count,
        !           940:     vm_offset_t         *entry_point
        !           941: )
        !           942: { 
        !           943:     struct ppc_thread_state     *state;
        !           944:  
        !           945:     /*
        !           946:      * Set a default.
        !           947:      */
        !           948:     if (*entry_point == 0)
        !           949:         *entry_point = VM_MIN_ADDRESS;
        !           950:     
        !           951:     switch (flavor) {   
        !           952:     
        !           953:     case PPC_THREAD_STATE:
        !           954:         if (count < PPC_THREAD_STATE_COUNT)
        !           955:             return (KERN_INVALID_ARGUMENT);
        !           956: 
        !           957:         state = (struct ppc_thread_state *) tstate;
        !           958: 
        !           959:         /* 
        !           960:          * If a valid entry point is specified, use it.
        !           961:          */     
        !           962:         *entry_point = state->srr0 ? state->srr0: VM_MIN_ADDRESS;
        !           963:         break; 
        !           964:     default: 
        !           965:         return (KERN_INVALID_ARGUMENT);
        !           966:     }           
        !           967:  
        !           968:     return (KERN_SUCCESS);
        !           969: }   
        !           970: 
        !           971: unsigned int get_msr_exportmask(void)
        !           972: {
        !           973:         return (MSR_EXPORT_MASK_SET);
        !           974: }
        !           975: 
        !           976: unsigned int get_msr_nbits(void)
        !           977: {
        !           978:         return (MASK(MSR_POW)|MASK(MSR_ILE)|MASK(MSR_IP)|MASK(MSR_LE));
        !           979: }
        !           980: unsigned int get_msr_rbits(void)
        !           981: {
        !           982:        return (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE));
        !           983: }
        !           984: 
        !           985: void  thread_set_child(thread_act_t child, int pid)
        !           986: {
        !           987:        struct ppc_saved_state *child_state;
        !           988:        
        !           989:        child_state = find_user_regs(child);
        !           990:        
        !           991:        child_state->r3 = pid;
        !           992:        child_state->r4 = 1;
        !           993: }

unix.superglobalmegacorp.com

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