Annotation of XNU/osfmk/ppc/status.c, revision 1.1.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.