]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/status.c
xnu-792.tar.gz
[apple/xnu.git] / osfmk / ppc / status.c
index 398b0b719dff8d4379a6fde753b6d48a2c9ab991..a0545f6fe1154732922f8b4d7bc7d267c8d5184e 100644 (file)
@@ -1,24 +1,21 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  */
 
 #include <kern/thread.h>
-#include <kern/thread_act.h>
 #include <kern/misc_protos.h>
 #include <mach/ppc/thread_status.h>
 #include <ppc/proc_reg.h>
+#include <ppc/cpu_internal.h>
 #include <ppc/exception.h>
 #include <ppc/misc_protos.h>
 #include <ppc/savearea.h>
-#include <ppc/thread_act.h>
+#include <ppc/thread.h>
 #include <ppc/Firmware.h>
 
+//#include <sys/time.h>
+typedef        unsigned int fixpt_t;   /* XXX <sys/resource.h> not self contained */
+#include <ppc/vmparam.h>       /* USRSTACK, etc. */
+
 #include <vm/vm_map.h>
 
 extern unsigned int killprint;
 extern double FloatInit;
 extern unsigned long QNaNbarbarian[4];
-extern void thread_bootstrap_return(void);
-extern struct   Saveanchor saveanchor;
-extern int      real_ncpus;                     /* Number of actual CPUs */
+
+#define       USRSTACK        0xc0000000
 
 kern_return_t
 thread_userstack(
@@ -53,7 +53,7 @@ thread_userstack(
     int,
     thread_state_t,
     unsigned int,
-    vm_offset_t *,
+       mach_vm_offset_t *,
        int *
 );
 
@@ -63,23 +63,29 @@ thread_entrypoint(
     int,
     thread_state_t,
     unsigned int,
-    vm_offset_t *
+    mach_vm_offset_t *
 ); 
 
 unsigned int get_msr_exportmask(void);
 unsigned int get_msr_nbits(void);
 unsigned int get_msr_rbits(void);
-void thread_set_child(thread_act_t child, int pid);
-void thread_set_parent(thread_act_t parent, int pid);
+void ppc_checkthreadstate(void *, int);
+void thread_set_child(thread_t child, int pid);
+void thread_set_parent(thread_t parent, int pid);
+void save_release(struct savearea *save);
                
 /*
  * Maps state flavor to number of words in the state:
  */
-unsigned int state_count[] = {
+__private_extern__
+unsigned int _MachineStateCount[] = {
        /* FLAVOR_LIST */ 0,
        PPC_THREAD_STATE_COUNT,
        PPC_FLOAT_STATE_COUNT,
        PPC_EXCEPTION_STATE_COUNT,
+       PPC_VECTOR_STATE_COUNT,
+       PPC_THREAD_STATE64_COUNT,
+       PPC_EXCEPTION_STATE64_COUNT,
 };
 
 /*
@@ -89,11 +95,11 @@ unsigned int state_count[] = {
  */
 
 kern_return_t 
-act_machine_get_state(
-                     thread_act_t           thr_act,
-                     thread_flavor_t        flavor,
-                     thread_state_t         tstate,
-                     mach_msg_type_number_t *count)
+machine_thread_get_state(
+       thread_t                                thread,
+       thread_flavor_t                 flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  *count)
 {
        
        register struct savearea *sv;                                           /* Pointer to the context savearea */
@@ -104,32 +110,29 @@ act_machine_get_state(
        unsigned int vrvalidwrk;
 
        register struct ppc_thread_state *ts;
+       register struct ppc_thread_state64 *xts;
        register struct ppc_exception_state *es;
+       register struct ppc_exception_state64 *xes;
        register struct ppc_float_state *fs;
        register struct ppc_vector_state *vs;
        
-       
-#if    MACH_ASSERT
-    if (watchacts & WA_STATE)
-       printf("act_%x act_machine_get_state(thr_act=%x,flav=%x,st=%x,cnt@%x=%x)\n",
-              current_act(), thr_act, flavor, tstate,
-              count, (count ? *count : 0));
-#endif /* MACH_ASSERT */
-
-       genuser = find_user_regs(thr_act);                                              /* Find the current user general context for this activation */
+       genuser = find_user_regs(thread);
 
        switch (flavor) {
                
                case THREAD_STATE_FLAVOR_LIST:
                        
-                       if (*count < 3)  {
+                       if (*count < 6)  {
                                return (KERN_INVALID_ARGUMENT);
                        }
                
                        tstate[0] = PPC_THREAD_STATE;
                        tstate[1] = PPC_FLOAT_STATE;
                        tstate[2] = PPC_EXCEPTION_STATE;
-                       *count = 3;
+                       tstate[3] = PPC_VECTOR_STATE;
+                       tstate[4] = PPC_THREAD_STATE64;
+                       tstate[5] = PPC_EXCEPTION_STATE64;
+                       *count = 6;
                
                        return KERN_SUCCESS;
        
@@ -144,46 +147,46 @@ act_machine_get_state(
                        sv = genuser;                                                                   /* Copy this over */
                        
                        if(sv) {                                                                                /* Is there a save area yet? */
-                               ts->r0  = sv->save_r0;
-                               ts->r1  = sv->save_r1;
-                               ts->r2  = sv->save_r2;
-                               ts->r3  = sv->save_r3;
-                               ts->r4  = sv->save_r4;
-                               ts->r5  = sv->save_r5;
-                               ts->r6  = sv->save_r6;
-                               ts->r7  = sv->save_r7;
-                               ts->r8  = sv->save_r8;
-                               ts->r9  = sv->save_r9;
-                               ts->r10 = sv->save_r10;
-                               ts->r11 = sv->save_r11;
-                               ts->r12 = sv->save_r12;
-                               ts->r13 = sv->save_r13;
-                               ts->r14 = sv->save_r14;
-                               ts->r15 = sv->save_r15;
-                               ts->r16 = sv->save_r16;
-                               ts->r17 = sv->save_r17;
-                               ts->r18 = sv->save_r18;
-                               ts->r19 = sv->save_r19;
-                               ts->r20 = sv->save_r20;
-                               ts->r21 = sv->save_r21;
-                               ts->r22 = sv->save_r22;
-                               ts->r23 = sv->save_r23;
-                               ts->r24 = sv->save_r24;
-                               ts->r25 = sv->save_r25;
-                               ts->r26 = sv->save_r26;
-                               ts->r27 = sv->save_r27;
-                               ts->r28 = sv->save_r28;
-                               ts->r29 = sv->save_r29;
-                               ts->r30 = sv->save_r30;
-                               ts->r31 = sv->save_r31;
-                               ts->cr  = sv->save_cr;
-                               ts->xer = sv->save_xer;
-                               ts->lr  = sv->save_lr;
-                               ts->ctr = sv->save_ctr;
-                               ts->srr0 = sv->save_srr0;
-                               ts->srr1 = sv->save_srr1;
+                               ts->r0  = (unsigned int)sv->save_r0;
+                               ts->r1  = (unsigned int)sv->save_r1;
+                               ts->r2  = (unsigned int)sv->save_r2;
+                               ts->r3  = (unsigned int)sv->save_r3;
+                               ts->r4  = (unsigned int)sv->save_r4;
+                               ts->r5  = (unsigned int)sv->save_r5;
+                               ts->r6  = (unsigned int)sv->save_r6;
+                               ts->r7  = (unsigned int)sv->save_r7;
+                               ts->r8  = (unsigned int)sv->save_r8;
+                               ts->r9  = (unsigned int)sv->save_r9;
+                               ts->r10 = (unsigned int)sv->save_r10;
+                               ts->r11 = (unsigned int)sv->save_r11;
+                               ts->r12 = (unsigned int)sv->save_r12;
+                               ts->r13 = (unsigned int)sv->save_r13;
+                               ts->r14 = (unsigned int)sv->save_r14;
+                               ts->r15 = (unsigned int)sv->save_r15;
+                               ts->r16 = (unsigned int)sv->save_r16;
+                               ts->r17 = (unsigned int)sv->save_r17;
+                               ts->r18 = (unsigned int)sv->save_r18;
+                               ts->r19 = (unsigned int)sv->save_r19;
+                               ts->r20 = (unsigned int)sv->save_r20;
+                               ts->r21 = (unsigned int)sv->save_r21;
+                               ts->r22 = (unsigned int)sv->save_r22;
+                               ts->r23 = (unsigned int)sv->save_r23;
+                               ts->r24 = (unsigned int)sv->save_r24;
+                               ts->r25 = (unsigned int)sv->save_r25;
+                               ts->r26 = (unsigned int)sv->save_r26;
+                               ts->r27 = (unsigned int)sv->save_r27;
+                               ts->r28 = (unsigned int)sv->save_r28;
+                               ts->r29 = (unsigned int)sv->save_r29;
+                               ts->r30 = (unsigned int)sv->save_r30;
+                               ts->r31 = (unsigned int)sv->save_r31;
+                               ts->cr  = (unsigned int)sv->save_cr;
+                               ts->xer = (unsigned int)sv->save_xer;
+                               ts->lr  = (unsigned int)sv->save_lr;
+                               ts->ctr = (unsigned int)sv->save_ctr;
+                               ts->srr0 = (unsigned int)sv->save_srr0;
+                               ts->srr1 = (unsigned int)sv->save_srr1;
                                ts->mq  = 0;                                                    /* MQ register (601 only) */
-                               ts->vrsave      = sv->save_vrsave;                      /* VRSAVE register (Altivec only) */
+                               ts->vrsave      = (unsigned int)sv->save_vrsave;                        /* VRSAVE register (Altivec only) */
                        }
                        else {                                                                          /* No user state yet. Save seemingly random values. */
                                                
@@ -204,6 +207,77 @@ act_machine_get_state(
                        *count = PPC_THREAD_STATE_COUNT;                        /* Pass back the amount we actually copied */
                        return KERN_SUCCESS;
        
+       
+               case PPC_THREAD_STATE64:
+       
+                       if (*count < PPC_THREAD_STATE64_COUNT) {        /* Is the count ok? */
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       xts = (struct ppc_thread_state64 *) tstate;
+
+                       sv = genuser;                                                           /* Copy this over */
+                       
+                       if(sv) {                                                                        /* Is there a save area yet? */
+                               xts->r0         = sv->save_r0;
+                               xts->r1         = sv->save_r1;
+                               xts->r2         = sv->save_r2;
+                               xts->r3         = sv->save_r3;
+                               xts->r4         = sv->save_r4;
+                               xts->r5         = sv->save_r5;
+                               xts->r6         = sv->save_r6;
+                               xts->r7         = sv->save_r7;
+                               xts->r8         = sv->save_r8;
+                               xts->r9         = sv->save_r9;
+                               xts->r10        = sv->save_r10;
+                               xts->r11        = sv->save_r11;
+                               xts->r12        = sv->save_r12;
+                               xts->r13        = sv->save_r13;
+                               xts->r14        = sv->save_r14;
+                               xts->r15        = sv->save_r15;
+                               xts->r16        = sv->save_r16;
+                               xts->r17        = sv->save_r17;
+                               xts->r18        = sv->save_r18;
+                               xts->r19        = sv->save_r19;
+                               xts->r20        = sv->save_r20;
+                               xts->r21        = sv->save_r21;
+                               xts->r22        = sv->save_r22;
+                               xts->r23        = sv->save_r23;
+                               xts->r24        = sv->save_r24;
+                               xts->r25        = sv->save_r25;
+                               xts->r26        = sv->save_r26;
+                               xts->r27        = sv->save_r27;
+                               xts->r28        = sv->save_r28;
+                               xts->r29        = sv->save_r29;
+                               xts->r30        = sv->save_r30;
+                               xts->r31        = sv->save_r31;
+                               xts->cr         = sv->save_cr;
+                               xts->xer        = sv->save_xer;
+                               xts->lr         = sv->save_lr;
+                               xts->ctr        = sv->save_ctr;
+                               xts->srr0       = sv->save_srr0;
+                               xts->srr1       = sv->save_srr1;
+                               xts->vrsave     = sv->save_vrsave;                      /* VRSAVE register (Altivec only) */
+                       }
+                       else {                                                                          /* No user state yet. Save seemingly random values. */
+                                               
+                               for(i=0; i < 32; i++) {                                 /* Fill up with defaults */
+                                       ((unsigned long long *)&xts->r0)[i] = ((unsigned long long *)&FloatInit)[0];
+                               }
+                               xts->cr         = 0;
+                               xts->xer        = 0;
+                               xts->lr         = ((unsigned long long *)&FloatInit)[0];
+                               xts->ctr        = ((unsigned long long *)&FloatInit)[0];
+                               xts->srr0       = ((unsigned long long *)&FloatInit)[0];
+                               xts->srr1       = MSR_EXPORT_MASK_SET;
+                               if(task_has_64BitAddr(thread->task)) 
+                                       xts->srr1 |= (uint64_t)MASK32(MSR_SF) << 32;    /* If 64-bit task, force 64-bit mode */
+                               xts->vrsave     = 0;                                            /* VRSAVE register (Altivec only) */
+                       }
+               
+                       *count = PPC_THREAD_STATE64_COUNT;                      /* Pass back the amount we actually copied */
+                       return KERN_SUCCESS;
+       
                case PPC_EXCEPTION_STATE:
        
                        if (*count < PPC_EXCEPTION_STATE_COUNT) {
@@ -211,17 +285,10 @@ act_machine_get_state(
                        }
                
                        es = (struct ppc_exception_state *) tstate;
+                       sv = genuser;                                                           /* Copy this over */
                
-                       sv = thr_act->mact.pcb;                                         /* Start with the normal savearea */
-                       while(sv) {                                                                     /* Find the user context */
-                               if(sv->save_srr1 & MASK(MSR_PR)) {              /* Are we looking at the user context? */
-                                       break;                                                          /* Outta here */
-                               }
-                               sv = sv->save_hdr.save_prev;                    /* Back chain */
-                       }
-
                        if(sv) {                                                                        /* See if valid state yet */
-                               es->dar = sv->save_dar;
+                               es->dar = (unsigned int)sv->save_dar;
                                es->dsisr = sv->save_dsisr;
                                es->exception = sv->save_exception;
                        }
@@ -234,24 +301,40 @@ act_machine_get_state(
                        *count = PPC_EXCEPTION_STATE_COUNT;
                        return KERN_SUCCESS;
        
+               case PPC_EXCEPTION_STATE64:
+       
+                       if (*count < PPC_EXCEPTION_STATE64_COUNT) {
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       xes = (struct ppc_exception_state64 *) tstate;
+                       sv = genuser;                                                           /* Copy this over */
+               
+                       if(sv) {                                                                        /* See if valid state yet */
+                               xes->dar = sv->save_dar;
+                               xes->dsisr = sv->save_dsisr;
+                               xes->exception = sv->save_exception;
+                       }
+                       else {                                                                          /* Nope, not yet */
+                               xes->dar = 0;
+                               xes->dsisr = 0;
+                               xes->exception = ((unsigned int *)&FloatInit)[0];
+                       }
+               
+                       *count = PPC_EXCEPTION_STATE64_COUNT;
+                       return KERN_SUCCESS;
+       
                case PPC_FLOAT_STATE: 
                
                        if (*count < PPC_FLOAT_STATE_COUNT)  {
                                return KERN_INVALID_ARGUMENT;
                        }
                
-                       fpu_save(thr_act->mact.curctx);                         /* Just in case it's live, save it */
+                       fpu_save(thread->machine.curctx);                               /* Just in case it's live, save it */
                
                        fs = (struct ppc_float_state *) tstate;         /* Point to destination */
                        
-                       fsv = (savearea_fpu *)thr_act->mact.curctx->FPUsave;    /* Start with the top FPU savearea */
-                       
-                       while(fsv) {                                                            /* Find the user context */
-                               if(!fsv->save_hdr.save_level) {                 /* Are we looking at the user context? */
-                                       break;                                                          /* Outta here */
-                               }
-                               fsv = (savearea_fpu *)fsv->save_hdr.save_prev;  /* Back chain */
-                       }
+                       fsv = find_user_fpu(thread);                            /* Get the user's fpu savearea */
                        
                        if(fsv) {                                                                       /* See if we have any */
                                bcopy((char *)&fsv->save_fp0, (char *)fs, 32*8); /* 32 registers  */
@@ -278,18 +361,11 @@ act_machine_get_state(
                                return KERN_INVALID_ARGUMENT;
                        }
                
-                       vec_save(thr_act->mact.curctx);                         /* Just in case it's live, save it */
+                       vec_save(thread->machine.curctx);                               /* Just in case it's live, save it */
                
                        vs = (struct ppc_vector_state *) tstate;        /* Point to destination */
                        
-                       vsv = (savearea_vec *)thr_act->mact.curctx->VMXsave;    /* Start with the top vector savearea */
-                       
-                       while(vsv) {                                                            /* Find the user context */
-                               if(!vsv->save_hdr.save_level) {                 /* Are we looking at the user context? */
-                                       break;                                                          /* Outta here */
-                               }
-                               vsv = (savearea_vec *)vsv->save_hdr.save_prev;  /* Back chain */
-                       }
+                       vsv = find_user_vec(thread);                            /* Find the vector savearea */
                        
                        if(vsv) {                                                                       /* See if we have any */
                                
@@ -300,7 +376,7 @@ act_machine_get_state(
                                        vs->save_vscr[0] = 0;                           /* Set an initial value if no general user yet */
                                        vs->save_vscr[1] = 0;
                                        vs->save_vscr[2] = 0;
-                                       vs->save_vscr[3] = 0x00010000;
+                                       vs->save_vscr[3] = 0x00010000;          /* Always start with Java mode off */
                                }
                                for(i=0; i < 32; i++) {                                 /* Copy the saved registers and invalidate the others */
                                        for(j=0; j < 4; j++) {
@@ -322,7 +398,7 @@ act_machine_get_state(
                                        vs->save_vscr[0] = 0;                           /* Set an initial value if no general user yet */
                                        vs->save_vscr[1] = 0;
                                        vs->save_vscr[2] = 0;
-                                       vs->save_vscr[3] = 0x00010000;
+                                       vs->save_vscr[3] = 0x00010000;          /* Always start with Java mode off */
                                }
                                vs->save_vrvalid = 0;                                   /* Clear the valid flags */
                        }
@@ -337,6 +413,240 @@ act_machine_get_state(
                        return KERN_INVALID_ARGUMENT;
        }
 }
+/* Close cousin of machine_thread_get_state(). 
+ * This function is currently incomplete since we don't really need vector
+ * or FP for the core dump (the save area can be accessed directly if the 
+ * user is so inclined). Also the function name is something of a misnomer,
+ * see the comment above find_kern_regs(). 
+ */
+
+kern_return_t 
+machine_thread_get_kern_state(
+       thread_t                                thread,
+       thread_flavor_t                 flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  *count)
+{
+       
+       register struct savearea *sv;                                           /* Pointer to the context savearea */
+       savearea *genkern;
+       int i;
+
+       register struct ppc_thread_state *ts;
+       register struct ppc_thread_state64 *xts;
+       register struct ppc_exception_state *es;
+       register struct ppc_exception_state64 *xes;
+       
+       genkern = find_kern_regs(thread);
+
+       switch (flavor) {
+               
+               case THREAD_STATE_FLAVOR_LIST:
+                       
+                       if (*count < 6)  {
+                               return (KERN_INVALID_ARGUMENT);
+                       }
+               
+                       tstate[0] = PPC_THREAD_STATE;
+                       tstate[1] = PPC_FLOAT_STATE;
+                       tstate[2] = PPC_EXCEPTION_STATE;
+                       tstate[3] = PPC_VECTOR_STATE;
+                       tstate[4] = PPC_THREAD_STATE64;
+                       tstate[5] = PPC_EXCEPTION_STATE64;
+                       *count = 6;
+               
+                       return KERN_SUCCESS;
+       
+               case PPC_THREAD_STATE:
+       
+                       if (*count < PPC_THREAD_STATE_COUNT) {                  /* Is the count ok? */
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       ts = (struct ppc_thread_state *) tstate;
+
+                       sv = genkern;                                                                   /* Copy this over */
+                       
+                       if(sv) {                                                                                /* Is there a save area yet? */
+                               ts->r0  = (unsigned int)sv->save_r0;
+                               ts->r1  = (unsigned int)sv->save_r1;
+                               ts->r2  = (unsigned int)sv->save_r2;
+                               ts->r3  = (unsigned int)sv->save_r3;
+                               ts->r4  = (unsigned int)sv->save_r4;
+                               ts->r5  = (unsigned int)sv->save_r5;
+                               ts->r6  = (unsigned int)sv->save_r6;
+                               ts->r7  = (unsigned int)sv->save_r7;
+                               ts->r8  = (unsigned int)sv->save_r8;
+                               ts->r9  = (unsigned int)sv->save_r9;
+                               ts->r10 = (unsigned int)sv->save_r10;
+                               ts->r11 = (unsigned int)sv->save_r11;
+                               ts->r12 = (unsigned int)sv->save_r12;
+                               ts->r13 = (unsigned int)sv->save_r13;
+                               ts->r14 = (unsigned int)sv->save_r14;
+                               ts->r15 = (unsigned int)sv->save_r15;
+                               ts->r16 = (unsigned int)sv->save_r16;
+                               ts->r17 = (unsigned int)sv->save_r17;
+                               ts->r18 = (unsigned int)sv->save_r18;
+                               ts->r19 = (unsigned int)sv->save_r19;
+                               ts->r20 = (unsigned int)sv->save_r20;
+                               ts->r21 = (unsigned int)sv->save_r21;
+                               ts->r22 = (unsigned int)sv->save_r22;
+                               ts->r23 = (unsigned int)sv->save_r23;
+                               ts->r24 = (unsigned int)sv->save_r24;
+                               ts->r25 = (unsigned int)sv->save_r25;
+                               ts->r26 = (unsigned int)sv->save_r26;
+                               ts->r27 = (unsigned int)sv->save_r27;
+                               ts->r28 = (unsigned int)sv->save_r28;
+                               ts->r29 = (unsigned int)sv->save_r29;
+                               ts->r30 = (unsigned int)sv->save_r30;
+                               ts->r31 = (unsigned int)sv->save_r31;
+                               ts->cr  = (unsigned int)sv->save_cr;
+                               ts->xer = (unsigned int)sv->save_xer;
+                               ts->lr  = (unsigned int)sv->save_lr;
+                               ts->ctr = (unsigned int)sv->save_ctr;
+                               ts->srr0 = (unsigned int)sv->save_srr0;
+                               ts->srr1 = (unsigned int)sv->save_srr1;
+                               ts->mq  = 0;                                                    /* MQ register (601 only) */
+                               ts->vrsave      = (unsigned int)sv->save_vrsave;                        /* VRSAVE register (Altivec only) */
+                       }
+                       else {                                                                          /* No state yet. Save seemingly random values. */
+                                               
+                               for(i=0; i < 32; i+=2) {                                /* Fill up with defaults */
+                                       ((unsigned int *)&ts->r0)[i] = ((unsigned int *)&FloatInit)[0];
+                                       ((unsigned int *)&ts->r0)[i+1] = ((unsigned int *)&FloatInit)[1];
+                               }
+                               ts->cr  = 0;
+                               ts->xer = 0;
+                               ts->lr  = ((unsigned int *)&FloatInit)[0];
+                               ts->ctr = ((unsigned int *)&FloatInit)[1];
+                               ts->srr0        = ((unsigned int *)&FloatInit)[0];
+                               ts->srr1 = MSR_EXPORT_MASK_SET;
+                               ts->mq  = 0;
+                               ts->vrsave      = 0;                                            /* VRSAVE register (Altivec only) */
+                       }
+               
+                       *count = PPC_THREAD_STATE_COUNT;                        /* Pass back the amount we actually copied */
+                       return KERN_SUCCESS;
+       
+       
+               case PPC_THREAD_STATE64:
+       
+                       if (*count < PPC_THREAD_STATE64_COUNT) {        /* Is the count ok? */
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       xts = (struct ppc_thread_state64 *) tstate;
+
+                       sv = genkern;                                                           /* Copy this over */
+                       
+                       if(sv) {                                                                        /* Is there a save area yet? */
+                               xts->r0         = sv->save_r0;
+                               xts->r1         = sv->save_r1;
+                               xts->r2         = sv->save_r2;
+                               xts->r3         = sv->save_r3;
+                               xts->r4         = sv->save_r4;
+                               xts->r5         = sv->save_r5;
+                               xts->r6         = sv->save_r6;
+                               xts->r7         = sv->save_r7;
+                               xts->r8         = sv->save_r8;
+                               xts->r9         = sv->save_r9;
+                               xts->r10        = sv->save_r10;
+                               xts->r11        = sv->save_r11;
+                               xts->r12        = sv->save_r12;
+                               xts->r13        = sv->save_r13;
+                               xts->r14        = sv->save_r14;
+                               xts->r15        = sv->save_r15;
+                               xts->r16        = sv->save_r16;
+                               xts->r17        = sv->save_r17;
+                               xts->r18        = sv->save_r18;
+                               xts->r19        = sv->save_r19;
+                               xts->r20        = sv->save_r20;
+                               xts->r21        = sv->save_r21;
+                               xts->r22        = sv->save_r22;
+                               xts->r23        = sv->save_r23;
+                               xts->r24        = sv->save_r24;
+                               xts->r25        = sv->save_r25;
+                               xts->r26        = sv->save_r26;
+                               xts->r27        = sv->save_r27;
+                               xts->r28        = sv->save_r28;
+                               xts->r29        = sv->save_r29;
+                               xts->r30        = sv->save_r30;
+                               xts->r31        = sv->save_r31;
+                               xts->cr         = sv->save_cr;
+                               xts->xer        = sv->save_xer;
+                               xts->lr         = sv->save_lr;
+                               xts->ctr        = sv->save_ctr;
+                               xts->srr0       = sv->save_srr0;
+                               xts->srr1       = sv->save_srr1;
+                               xts->vrsave     = sv->save_vrsave;                      /* VRSAVE register (Altivec only) */
+                       }
+                       else {                                                                          /* No user state yet. Save seemingly random values. */
+                                               
+                               for(i=0; i < 32; i++) {                                 /* Fill up with defaults */
+                                       ((unsigned long long *)&xts->r0)[i] = ((unsigned long long *)&FloatInit)[0];
+                               }
+                               xts->cr         = 0;
+                               xts->xer        = 0;
+                               xts->lr         = ((unsigned long long *)&FloatInit)[0];
+                               xts->ctr        = ((unsigned long long *)&FloatInit)[0];
+                               xts->srr0       = ((unsigned long long *)&FloatInit)[0];
+                               xts->srr1       = MSR_EXPORT_MASK_SET;
+                               xts->vrsave     = 0;                                            /* VRSAVE register (Altivec only) */
+                       }
+               
+                       *count = PPC_THREAD_STATE64_COUNT;                      /* Pass back the amount we actually copied */
+                       return KERN_SUCCESS;
+       
+               case PPC_EXCEPTION_STATE:
+       
+                       if (*count < PPC_EXCEPTION_STATE_COUNT) {
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       es = (struct ppc_exception_state *) tstate;
+                       sv = genkern;                                                           /* Copy this over */
+               
+                       if(sv) {                                                                        /* See if valid state yet */
+                               es->dar = (unsigned int)sv->save_dar;
+                               es->dsisr = sv->save_dsisr;
+                               es->exception = sv->save_exception;
+                       }
+                       else {                                                                          /* Nope, not yet */
+                               es->dar = 0;
+                               es->dsisr = 0;
+                               es->exception = ((unsigned int *)&FloatInit)[0];
+                       }
+               
+                       *count = PPC_EXCEPTION_STATE_COUNT;
+                       return KERN_SUCCESS;
+       
+               case PPC_EXCEPTION_STATE64:
+       
+                       if (*count < PPC_EXCEPTION_STATE64_COUNT) {
+                               return KERN_INVALID_ARGUMENT;
+                       }
+               
+                       xes = (struct ppc_exception_state64 *) tstate;
+                       sv = genkern;                                                           /* Copy this over */
+               
+                       if(sv) {                                                                        /* See if valid state yet */
+                               xes->dar = sv->save_dar;
+                               xes->dsisr = sv->save_dsisr;
+                               xes->exception = sv->save_exception;
+                       }
+                       else {                                                                          /* Nope, not yet */
+                               xes->dar = 0;
+                               xes->dsisr = 0;
+                               xes->exception = ((unsigned int *)&FloatInit)[0];
+                       }
+               
+                       *count = PPC_EXCEPTION_STATE64_COUNT;
+                       return KERN_SUCCESS;
+       
+               default:
+                       return KERN_INVALID_ARGUMENT;
+       }
+}
 
 
 /*
@@ -345,32 +655,26 @@ act_machine_get_state(
  * Set the status of the specified thread.
  */
 kern_return_t 
-act_machine_set_state(
-                     thread_act_t           thr_act,
-                     thread_flavor_t        flavor,
-                     thread_state_t         tstate,
-                     mach_msg_type_number_t count)
+machine_thread_set_state(
+       thread_t                                thread,
+       thread_flavor_t                 flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  count)
 {
   
-       savearea                *sv, *genuser;
+       savearea                *genuser;
        savearea_fpu    *fsv, *fsvn, *fsvo;
        savearea_vec    *vsv, *vsvn, *vsvo;
        unsigned int    i;
-       int                             clgn;
+       unsigned int    clgn;
        register struct ppc_thread_state *ts;
+       register struct ppc_thread_state64 *xts;
        register struct ppc_exception_state *es;
+       register struct ppc_exception_state *xes;
        register struct ppc_float_state *fs;
        register struct ppc_vector_state *vs;
        
-    int        kernel_act = thr_act->kernel_loading || thr_act->kernel_loaded;
-
-#if    MACH_ASSERT
-    if (watchacts & WA_STATE)
-       printf("act_%x act_machine_set_state(thr_act=%x,flav=%x,st=%x,cnt=%x)\n",
-              current_act(), thr_act, flavor, tstate, count);
-#endif /* MACH_ASSERT */
-               
-//     dbgTrace((unsigned int)thr_act, (unsigned int)sv, flavor);      /* (TEST/DEBUG) */
+//     dbgTrace((unsigned int)thr_act, (unsigned int)0 /*sv: was never set*/, flavor); /* (TEST/DEBUG) */
 
        clgn = count;                                                                                   /* Get the count */
        
@@ -381,6 +685,13 @@ act_machine_set_state(
                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
                        }
                        break;
+       
+               case PPC_THREAD_STATE64:
+                       
+                       if (clgn < PPC_THREAD_STATE64_COUNT)  {                 /* Is it too short? */
+                               return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
+                       }
+                       break;
                        
                case PPC_EXCEPTION_STATE:
                        
@@ -388,6 +699,12 @@ act_machine_set_state(
                                return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
                        }
                        
+               case PPC_EXCEPTION_STATE64:
+                       
+                       if (clgn < PPC_EXCEPTION_STATE64_COUNT)  {              /* Is it too short? */
+                               return KERN_INVALID_ARGUMENT;                           /* Yeah, just leave... */
+                       }
+                       
                        break;
                        
                case PPC_FLOAT_STATE:
@@ -411,99 +728,174 @@ act_machine_set_state(
                        return KERN_INVALID_ARGUMENT;
        }
        
-       genuser = get_user_regs(thr_act);                                               /* Find or allocate and initialize one */
+       genuser = get_user_regs(thread);                                                /* Find or allocate and initialize one */
 
        switch (flavor) {
                
                case PPC_THREAD_STATE:
-               case PPC_EXCEPTION_STATE:
                                
                        ts = (struct ppc_thread_state *)tstate;
-                                                                               
-                       if(flavor == PPC_THREAD_STATE) {                                /* Are we updating plain state? */
-                       
-                               genuser->save_r0        = ts->r0;
-                               genuser->save_r1        = ts->r1;
-                               genuser->save_r2        = ts->r2;
-                               genuser->save_r3        = ts->r3;
-                               genuser->save_r4        = ts->r4;
-                               genuser->save_r5        = ts->r5;
-                               genuser->save_r6        = ts->r6;
-                               genuser->save_r7        = ts->r7;
-                               genuser->save_r8        = ts->r8;
-                               genuser->save_r9        = ts->r9;
-                               genuser->save_r10       = ts->r10;
-                               genuser->save_r11       = ts->r11;
-                               genuser->save_r12       = ts->r12;
-                               genuser->save_r13       = ts->r13;
-                               genuser->save_r14       = ts->r14;
-                               genuser->save_r15       = ts->r15;
-                               genuser->save_r16       = ts->r16;
-                               genuser->save_r17       = ts->r17;
-                               genuser->save_r18       = ts->r18;
-                               genuser->save_r19       = ts->r19;
-                               genuser->save_r20       = ts->r20;
-                               genuser->save_r21       = ts->r21;
-                               genuser->save_r22       = ts->r22;
-                               genuser->save_r23       = ts->r23;
-                               genuser->save_r24       = ts->r24;
-                               genuser->save_r25       = ts->r25;
-                               genuser->save_r26       = ts->r26;
-                               genuser->save_r27       = ts->r27;
-                               genuser->save_r28       = ts->r28;
-                               genuser->save_r29       = ts->r29;
-                               genuser->save_r30       = ts->r30;
-                               genuser->save_r31       = ts->r31;
-                       
-                               genuser->save_cr        = ts->cr;
-                               genuser->save_xer       = ts->xer;
-                               genuser->save_lr        = ts->lr;
-                               genuser->save_ctr       = ts->ctr;
-                               genuser->save_srr0      = ts->srr0;
-                               genuser->save_vrsave    = ts->vrsave;                                   /* VRSAVE register (Altivec only) */
 
-                               genuser->save_srr1 = MSR_PREPARE_FOR_IMPORT(genuser->save_srr1, ts->srr1);      /* Set the bits we can change */
-       
-                               if(!kernel_act) genuser->save_srr1 |= MSR_EXPORT_MASK_SET;      /* If not a kernel guy, force the magic bits on */      
-                       
-                               genuser->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));  /* Make sure we don't enable the floating point unit */
+                       genuser->save_r0        = (uint64_t)ts->r0;
+                       genuser->save_r1        = (uint64_t)ts->r1;
+                       genuser->save_r2        = (uint64_t)ts->r2;
+                       genuser->save_r3        = (uint64_t)ts->r3;
+                       genuser->save_r4        = (uint64_t)ts->r4;
+                       genuser->save_r5        = (uint64_t)ts->r5;
+                       genuser->save_r6        = (uint64_t)ts->r6;
+                       genuser->save_r7        = (uint64_t)ts->r7;
+                       genuser->save_r8        = (uint64_t)ts->r8;
+                       genuser->save_r9        = (uint64_t)ts->r9;
+                       genuser->save_r10       = (uint64_t)ts->r10;
+                       genuser->save_r11       = (uint64_t)ts->r11;
+                       genuser->save_r12       = (uint64_t)ts->r12;
+                       genuser->save_r13       = (uint64_t)ts->r13;
+                       genuser->save_r14       = (uint64_t)ts->r14;
+                       genuser->save_r15       = (uint64_t)ts->r15;
+                       genuser->save_r16       = (uint64_t)ts->r16;
+                       genuser->save_r17       = (uint64_t)ts->r17;
+                       genuser->save_r18       = (uint64_t)ts->r18;
+                       genuser->save_r19       = (uint64_t)ts->r19;
+                       genuser->save_r20       = (uint64_t)ts->r20;
+                       genuser->save_r21       = (uint64_t)ts->r21;
+                       genuser->save_r22       = (uint64_t)ts->r22;
+                       genuser->save_r23       = (uint64_t)ts->r23;
+                       genuser->save_r24       = (uint64_t)ts->r24;
+                       genuser->save_r25       = (uint64_t)ts->r25;
+                       genuser->save_r26       = (uint64_t)ts->r26;
+                       genuser->save_r27       = (uint64_t)ts->r27;
+                       genuser->save_r28       = (uint64_t)ts->r28;
+                       genuser->save_r29       = (uint64_t)ts->r29;
+                       genuser->save_r30       = (uint64_t)ts->r30;
+                       genuser->save_r31       = (uint64_t)ts->r31;
+               
+                       genuser->save_cr        = ts->cr;
+                       genuser->save_xer       = (uint64_t)ts->xer;
+                       genuser->save_lr        = (uint64_t)ts->lr;
+                       genuser->save_ctr       = (uint64_t)ts->ctr;
+                       genuser->save_srr0      = (uint64_t)ts->srr0;
+                       genuser->save_vrsave    = ts->vrsave;                                   /* VRSAVE register (Altivec only) */
+
+                       genuser->save_srr1 = MSR_PREPARE_FOR_IMPORT(genuser->save_srr1, ts->srr1);      /* Set the bits we can change */
+
+                       genuser->save_srr1 |= MSR_EXPORT_MASK_SET;
+               
+                       genuser->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));  /* Make sure we don't enable the floating point unit */
                        
-                               return KERN_SUCCESS;
+                       if(task_has_64BitAddr(thread->task)) 
+                               genuser->save_srr1 |= (uint64_t)MASK32(MSR_SF) << 32;   /* If 64-bit task, force 64-bit mode */
+                       else
+                               genuser->save_srr1 &= ~((uint64_t)MASK32(MSR_SF) << 32);        /* else 32-bit mode */
+               
+                       return KERN_SUCCESS;
+
+
+               case PPC_THREAD_STATE64:
                                
-                       }
+                       xts = (struct ppc_thread_state64 *)tstate;
+
+                       genuser->save_r0        = xts->r0;
+                       genuser->save_r1        = xts->r1;
+                       genuser->save_r2        = xts->r2;
+                       genuser->save_r3        = xts->r3;
+                       genuser->save_r4        = xts->r4;
+                       genuser->save_r5        = xts->r5;
+                       genuser->save_r6        = xts->r6;
+                       genuser->save_r7        = xts->r7;
+                       genuser->save_r8        = xts->r8;
+                       genuser->save_r9        = xts->r9;
+                       genuser->save_r10       = xts->r10;
+                       genuser->save_r11       = xts->r11;
+                       genuser->save_r12       = xts->r12;
+                       genuser->save_r13       = xts->r13;
+                       genuser->save_r14       = xts->r14;
+                       genuser->save_r15       = xts->r15;
+                       genuser->save_r16       = xts->r16;
+                       genuser->save_r17       = xts->r17;
+                       genuser->save_r18       = xts->r18;
+                       genuser->save_r19       = xts->r19;
+                       genuser->save_r20       = xts->r20;
+                       genuser->save_r21       = xts->r21;
+                       genuser->save_r22       = xts->r22;
+                       genuser->save_r23       = xts->r23;
+                       genuser->save_r24       = xts->r24;
+                       genuser->save_r25       = xts->r25;
+                       genuser->save_r26       = xts->r26;
+                       genuser->save_r27       = xts->r27;
+                       genuser->save_r28       = xts->r28;
+                       genuser->save_r29       = xts->r29;
+                       genuser->save_r30       = xts->r30;
+                       genuser->save_r31       = xts->r31;
+               
+                       genuser->save_cr        = xts->cr;
+                       genuser->save_xer       = xts->xer;
+                       genuser->save_lr        = xts->lr;
+                       genuser->save_ctr       = xts->ctr;
+                       genuser->save_srr0      = xts->srr0;
+                       genuser->save_vrsave    = xts->vrsave;                                  /* VRSAVE register (Altivec only) */
 
+                       genuser->save_srr1 = MSR_PREPARE_FOR_IMPORT(genuser->save_srr1, xts->srr1);     /* Set the bits we can change */
+
+                       genuser->save_srr1 |= MSR_EXPORT_MASK_SET;
+               
+                       genuser->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));  /* Make sure we don't enable the floating point unit */
+                       
+                       if(task_has_64BitAddr(thread->task)) 
+                               genuser->save_srr1 |= (uint64_t)MASK32(MSR_SF) << 32;   /* If 64-bit task, force 64-bit mode */
+                       else
+                               genuser->save_srr1 &= ~((uint64_t)MASK32(MSR_SF) << 32);        /* else 32-bit mode */
+               
+                       return KERN_SUCCESS;
+                               
+                               
+               case PPC_EXCEPTION_STATE:
+                       
                        es = (struct ppc_exception_state *) tstate;
                
-                       genuser->save_dar = es->dar;
+                       genuser->save_dar = (uint64_t)es->dar;
                        genuser->save_dsisr = es->dsisr;
                        genuser->save_exception = es->exception;
 
                        return KERN_SUCCESS;
        
+/*
+ *             It's pretty worthless to try to change this stuff, but we'll do it anyway.
+ */
+               case PPC_EXCEPTION_STATE64:
+                       
+                       xes = (struct ppc_exception_state *) tstate;
+               
+                       genuser->save_dar       = xes->dar;
+                       genuser->save_dsisr = xes->dsisr;
+                       genuser->save_exception = xes->exception;
+
+                       return KERN_SUCCESS;
+       
                case PPC_FLOAT_STATE:
 
-                       toss_live_fpu(thr_act->mact.curctx);                    /* Toss my floating point if live anywhere */
+                       toss_live_fpu(thread->machine.curctx);                  /* Toss my floating point if live anywhere */
                        
-                       fsv = find_user_fpu(thr_act);                                   /* Get the user's floating point context */
+                       fsv = find_user_fpu(thread);                                    /* Get the user's floating point context */
                
                        if(!fsv) {                                                                              /* Do we have one yet? */
                                fsv = (savearea_fpu *)save_alloc();                     /* If we still don't have one, get a new one */
                                fsv->save_hdr.save_flags = (fsv->save_hdr.save_flags & ~SAVtype) | (SAVfloat << SAVtypeshft);   /* Mark as in use as float */
-                               fsv->save_hdr.save_act = thr_act;                       /* Point to the activation */
+                               fsv->save_hdr.save_act = thread;
                                fsv->save_hdr.save_prev = 0;                            /* Mark no more */
                                fsv->save_hdr.save_level = 0;                           /* Mark user state */
                                
-                               if(!thr_act->mact.curctx->FPUsave) thr_act->mact.curctx->FPUsave = fsv; /* If no floating point, chain us first */
+                               if(!thread->machine.curctx->FPUsave) thread->machine.curctx->FPUsave = fsv;     /* If no floating point, chain us first */
                                else {
                                
-                                       fsvn = fsvo = thr_act->mact.curctx->FPUsave;    /* Remember first one */
+                                       fsvn = fsvo = thread->machine.curctx->FPUsave;  /* Remember first one */
                                        
                                        while (fsvn) {                                                  /* Go until we hit the end */
                                                fsvo = fsvn;                                            /* Remember the previous one */
-                                               fsvn = (savearea_fpu *)fsvo->save_hdr.save_prev;        /* Skip on to the next */
+                                               fsvn = CAST_DOWN(savearea_fpu *, fsvo->save_hdr.save_prev);     /* Skip on to the next */
                                        }
                                        
-                                       fsvo->save_hdr.save_prev = (savearea *)fsv;             /* Queue us on in */
+                                       fsvo->save_hdr.save_prev = (addr64_t)((uintptr_t)fsv);          /* Queue us on in */
                                }
                                
                        }
@@ -520,28 +912,28 @@ act_machine_set_state(
        
                case PPC_VECTOR_STATE:
 
-                       toss_live_vec(thr_act->mact.curctx);                    /* Toss my vector if live anywhere */
+                       toss_live_vec(thread->machine.curctx);                  /* Toss my vector if live anywhere */
                        
-                       vsv = find_user_vec(thr_act);                                   /* Get the user's vector context */
+                       vsv = find_user_vec(thread);                                    /* Get the user's vector context */
                
                        if(!vsv) {                                                                              /* Do we have one yet? */
                                vsv = (savearea_vec *)save_alloc();                     /* If we still don't have one, get a new one */
                                vsv->save_hdr.save_flags = (vsv->save_hdr.save_flags & ~SAVtype) | (SAVvector << SAVtypeshft);  /* Mark as in use as vector */
-                               vsv->save_hdr.save_act = thr_act;                       /* Point to the activation */
+                               vsv->save_hdr.save_act = thread;
                                vsv->save_hdr.save_prev = 0;                            /* Mark no more */
                                vsv->save_hdr.save_level = 0;                           /* Mark user state */
                                
-                               if(!thr_act->mact.curctx->VMXsave) thr_act->mact.curctx->VMXsave = vsv; /* If no vector, chain us first */
+                               if(!thread->machine.curctx->VMXsave) thread->machine.curctx->VMXsave = vsv;     /* If no vector, chain us first */
                                else {
                                
-                                       vsvn = vsvo = thr_act->mact.curctx->VMXsave;    /* Remember first one */
+                                       vsvn = vsvo = thread->machine.curctx->VMXsave;  /* Remember first one */
                                        
                                        while (vsvn) {                                                  /* Go until we hit the end */
                                                vsvo = vsvn;                                            /* Remember the previous one */
-                                               vsvn = (savearea_vec *)vsvo->save_hdr.save_prev;        /* Skip on to the next */
+                                               vsvn = CAST_DOWN(savearea_vec *, vsvo->save_hdr.save_prev);     /* Skip on to the next */
                                        }
                                        
-                                       vsvo->save_hdr.save_prev = (savearea *)vsv;     /* Queue us on in */
+                                       vsvo->save_hdr.save_prev = (addr64_t)((uintptr_t)vsv);  /* Queue us on in */
                                }
                                
                        }
@@ -562,6 +954,33 @@ act_machine_set_state(
     }
 }
 
+
+/*
+ * This is where registers that are not normally specified by the mach-o
+ * file on an execve should be nullified, perhaps to avoid a covert channel.
+ * We've never bothered to clear FPRs or VRs, but it is important to clear
+ * the FPSCR, which is kept in the general state but not set by the general
+ * flavor (ie, PPC_THREAD_STATE or PPC_THREAD_STATE64.)
+ */
+kern_return_t
+machine_thread_state_initialize(
+       thread_t thread)
+{
+       savearea                *sv;
+       
+       sv = get_user_regs(thread);                                             /* Find or allocate and initialize one */
+
+       sv->save_fpscr = 0;                                                             /* Clear all floating point exceptions */
+       sv->save_vrsave = 0;                                                    /* Set the vector save state */
+       sv->save_vscr[0] = 0x00000000;                                  
+       sv->save_vscr[1] = 0x00000000;                                  
+       sv->save_vscr[2] = 0x00000000;                                  
+       sv->save_vscr[3] = 0x00010000;                                  /* Disable java mode and clear saturated */
+
+    return  KERN_SUCCESS;
+}
+
+
 /*
  *             Duplicates the context of one thread into a new one.
  *             The new thread is assumed to be new and have no user state contexts except maybe a general one.
@@ -571,66 +990,67 @@ act_machine_set_state(
  *             eliminate any floating point or vector kernel contexts and carry across the user state ones.
  */
 
-void act_thread_dup(thread_act_t old, thread_act_t new) {
-
+kern_return_t
+machine_thread_dup(
+       thread_t                self,
+       thread_t                target)
+{
        savearea                *sv, *osv; 
        savearea_fpu    *fsv, *fsvn;
        savearea_vec    *vsv, *vsvn;
-       unsigned int    spc, i, *srs;
        
-       fpu_save(old->mact.curctx);                                             /* Make certain floating point state is all saved */
-       vec_save(old->mact.curctx);                                             /* Make certain the vector state is all saved */
+       fpu_save(self->machine.curctx);                                         /* Make certain floating point state is all saved */
+       vec_save(self->machine.curctx);                                         /* Make certain the vector state is all saved */
        
-       sv = get_user_regs(new);                                                /* Allocate and initialze context in the new activation */
+       sv = get_user_regs(target);                                             /* Allocate and initialze context in the new activation */
        
-       osv = find_user_regs(old);                                              /* Find the original context */
-       if(!osv) {
-               panic("act_thread_dup: old activation (%08X) has no general user context\n", old);
-       }
+       osv = find_user_regs(self);                                             /* Find the original context */
+       if(!osv)
+               return (KERN_FAILURE);
        
        bcopy((char *)((unsigned int)osv + sizeof(savearea_comm)),      /* Copy everything but the headers */
                (char *)((unsigned int)sv + sizeof(savearea_comm)), 
                sizeof(struct savearea) - sizeof(savearea_comm));
        
-       sv->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));       /* Make certain that floating point and vector are turned off */
+       sv->save_srr1 &= (uint64_t)(~(MASK(MSR_FP) | MASK(MSR_VEC)));   /* Make certain that floating point and vector are turned off */
 
-       fsv = find_user_fpu(old);                                               /* Get any user floating point */
+       fsv = find_user_fpu(self);                                              /* Get any user floating point */
        
-       new->mact.curctx->FPUsave = 0;                                  /* Assume no floating point */
+       target->machine.curctx->FPUsave = 0;                                    /* Assume no floating point */
 
        if(fsv) {                                                                               /* Did we find one? */
                fsvn = (savearea_fpu *)save_alloc();            /* If we still don't have one, get a new one */
                fsvn->save_hdr.save_flags = (fsvn->save_hdr.save_flags & ~SAVtype) | (SAVfloat << SAVtypeshft); /* Mark as in use as float */
-               fsvn->save_hdr.save_act = new;                          /* Point to the activation */
+               fsvn->save_hdr.save_act = target;
                fsvn->save_hdr.save_prev = 0;                           /* Mark no more */
                fsvn->save_hdr.save_level = 0;                          /* Mark user state */
 
-               new->mact.curctx->FPUsave = fsvn;                       /* Chain in the floating point */
+               target->machine.curctx->FPUsave = fsvn;                 /* Chain in the floating point */
 
                bcopy((char *)((unsigned int)fsv + sizeof(savearea_comm)),      /* Copy everything but the headers */
                        (char *)((unsigned int)fsvn + sizeof(savearea_comm)), 
                        sizeof(struct savearea) - sizeof(savearea_comm));
        }
 
-       vsv = find_user_vec(old);                                               /* Get any user vector */
+       vsv = find_user_vec(self);                                              /* Get any user vector */
        
-       new->mact.curctx->VMXsave = 0;                                  /* Assume no vector */
+       target->machine.curctx->VMXsave = 0;                                    /* Assume no vector */
 
        if(vsv) {                                                                               /* Did we find one? */
                vsvn = (savearea_vec *)save_alloc();            /* If we still don't have one, get a new one */
                vsvn->save_hdr.save_flags = (vsvn->save_hdr.save_flags & ~SAVtype) | (SAVvector << SAVtypeshft);        /* Mark as in use as float */
-               vsvn->save_hdr.save_act = new;                          /* Point to the activation */
+               vsvn->save_hdr.save_act = target;
                vsvn->save_hdr.save_prev = 0;                           /* Mark no more */
                vsvn->save_hdr.save_level = 0;                          /* Mark user state */
 
-               new->mact.curctx->VMXsave = vsvn;                       /* Chain in the floating point */
+               target->machine.curctx->VMXsave = vsvn;                 /* Chain in the floating point */
 
                bcopy((char *)((unsigned int)vsv + sizeof(savearea_comm)),      /* Copy everything but the headers */
                        (char *)((unsigned int)vsvn + sizeof(savearea_comm)), 
                        sizeof(struct savearea) - sizeof(savearea_comm));
        }
 
-       return;                                                                                 /* Bye bye... */
+       return (KERN_SUCCESS);
 }
 
 /*
@@ -640,33 +1060,37 @@ void act_thread_dup(thread_act_t old, thread_act_t new) {
  *             We only set initial values if there was no context found.
  */
 
-savearea *get_user_regs(thread_act_t act) {
-
+savearea *
+get_user_regs(
+       thread_t         thread)
+{
        savearea                *sv, *osv;
-       unsigned int    spc, i, *srs;
+       unsigned int    i;
 
-       sv = act->mact.pcb;                                                             /* Get the top savearea on the stack */
+       if (thread->machine.upcb)
+               return  thread->machine.upcb;
+
+       sv = thread->machine.pcb;                                                               /* Get the top savearea on the stack */
        osv = 0;                                                                                /* Set no user savearea yet */  
        
        while(sv) {                                                                             /* Find the user context */
-               if(sv->save_srr1 & MASK(MSR_PR)) return sv;     /* We found a user state context... */
-
                osv = sv;                                                                       /* Save the last one */
-               sv = sv->save_hdr.save_prev;                            /* Get the previous context */
+               sv = CAST_DOWN(savearea *, sv->save_hdr.save_prev);     /* Get the previous context */ 
        }
 
        sv = save_alloc();                                                              /* Get one */
        sv->save_hdr.save_flags = (sv->save_hdr.save_flags & ~SAVtype) | (SAVgeneral << SAVtypeshft);   /* Mark as in use as general */
-       sv->save_hdr.save_act = act;                                    /* Point to the activation */
+       sv->save_hdr.save_act = thread;
        sv->save_hdr.save_prev = 0;                                             /* Mark no more */
        sv->save_hdr.save_level = 0;                                    /* Mark user state */
        
        if(osv) {                                                                               /* Did we already have one? */
-               osv->save_hdr.save_prev = sv;                           /* Chain us on the end */
+               osv->save_hdr.save_prev = (addr64_t)((uintptr_t)sv);            /* Chain us on the end */
        }
        else {                                                                                  /* We are the first */
-               act->mact.pcb = sv;                                                     /* Put it there */
+               thread->machine.pcb = sv;                                                       /* Put it there */
        }
+       thread->machine.upcb = sv;                                                      /* Set user pcb */
 
        for(i=0; i < 32; i+=2) {                                                /* Fill up with defaults */
                ((unsigned int *)&sv->save_r0)[i] = ((unsigned int *)&FloatInit)[0];
@@ -674,10 +1098,12 @@ savearea *get_user_regs(thread_act_t act) {
        }
        sv->save_cr     = 0;
        sv->save_xer    = 0;
-       sv->save_lr     = ((unsigned int *)&FloatInit)[0];
-       sv->save_ctr    = ((unsigned int *)&FloatInit)[1];
-       sv->save_srr0   = ((unsigned int *)&FloatInit)[0];
-       sv->save_srr1 = MSR_EXPORT_MASK_SET;
+       sv->save_lr     = (uint64_t)FloatInit;
+       sv->save_ctr    = (uint64_t)FloatInit;
+       sv->save_srr0   = (uint64_t)FloatInit;
+       sv->save_srr1 = (uint64_t)MSR_EXPORT_MASK_SET;
+       if(task_has_64BitAddr(thread->task)) 
+               sv->save_srr1 |= (uint64_t)MASK32(MSR_SF) << 32;        /* If 64-bit task, force 64-bit mode */
 
        sv->save_fpscr = 0;                                                             /* Clear all floating point exceptions */
 
@@ -685,14 +1111,7 @@ savearea *get_user_regs(thread_act_t act) {
        sv->save_vscr[0] = 0x00000000;                                  
        sv->save_vscr[1] = 0x00000000;                                  
        sv->save_vscr[2] = 0x00000000;                                  
-       sv->save_vscr[3] = 0x00010000;                                  /* Supress java mode and clear saturated */
-       
-       spc = (unsigned int)act->map->pmap->space;              /* Get the space we're in */
-       
-       srs = (unsigned int *)&sv->save_sr0;                    /* Point to the SRs */
-       for(i = 0; i < 16; i++) {                                               /* Fill in the SRs for the new context */
-               srs[i] = SEG_REG_PROT | (i<<20) | spc;          /* Set the SR */
-       }
+       sv->save_vscr[3] = 0x00010000;                                  /* Disable java mode and clear saturated */
        
        return sv;                                                                              /* Bye bye... */
 }
@@ -702,20 +1121,21 @@ savearea *get_user_regs(thread_act_t act) {
  *             we just return a 0.
  */
 
-savearea *find_user_regs(thread_act_t act) {
-
-       savearea                *sv;
+savearea *
+find_user_regs(
+       thread_t        thread)
+{
+       return thread->machine.upcb;
+}
 
-       sv = act->mact.pcb;                                                             /* Get the top savearea on the stack */
-       
-       while(sv) {                                                                             /* Find the user context */
-               if(sv->save_srr1 & MASK(MSR_PR)) {                      /* Are we looking at the user context? */
-                       break;                                                                  /* Outta here */
-               }
-               sv = sv->save_hdr.save_prev;                            /* Get the previous context */
-       }
-       
-       return sv;                                                                              /* Bye bye... */
+/* The name of this call is something of a misnomer since the mact.pcb can 
+ * contain chained saveareas, but it will do for now..
+ */
+savearea *
+find_kern_regs(
+       thread_t        thread)
+{
+        return thread->machine.pcb;
 }
 
 /*
@@ -723,16 +1143,21 @@ savearea *find_user_regs(thread_act_t act) {
  *             we just return a 0.
  */
 
-savearea_fpu *find_user_fpu(thread_act_t act) {
-
+savearea_fpu *
+find_user_fpu(
+       thread_t        thread)
+{
        savearea_fpu    *fsv;
+       boolean_t               intr;
 
-       fsv = act->mact.curctx->FPUsave;                                /* Get the start of the floating point chain */
+       intr = ml_set_interrupts_enabled(FALSE);
+       fsv = thread->machine.curctx->FPUsave;                          /* Get the start of the floating point chain */
        
        while(fsv) {                                                                    /* Look until the end or we find it */
                if(!(fsv->save_hdr.save_level)) break;          /* Is the the user state stuff? (the level is 0 if so) */       
-               fsv = (savearea_fpu *)fsv->save_hdr.save_prev;  /* Try the previous one */
+               fsv = CAST_DOWN(savearea_fpu *, fsv->save_hdr.save_prev);       /* Try the previous one */ 
        }
+       (void) ml_set_interrupts_enabled(intr);
        
        return fsv;                                                                             /* Bye bye... */
 }
@@ -742,16 +1167,45 @@ savearea_fpu *find_user_fpu(thread_act_t act) {
  *             we just return a 0.
  */
 
-savearea_vec *find_user_vec(thread_act_t act) {
+savearea_vec *
+find_user_vec(
+       thread_t        thread)
+{
+       savearea_vec    *vsv;
+       boolean_t               intr;
+
+       intr = ml_set_interrupts_enabled(FALSE);
+       vsv = thread->machine.curctx->VMXsave;                          /* Get the start of the vector chain */
+       
+       while(vsv) {                                                                    /* Look until the end or we find it */
+               if(!(vsv->save_hdr.save_level)) break;          /* Is the the user state stuff? (the level is 0 if so) */       
+               vsv = CAST_DOWN(savearea_vec *, vsv->save_hdr.save_prev);       /* Try the previous one */ 
+       }
+       (void) ml_set_interrupts_enabled(intr);
+       
+       return vsv;                                                                             /* Bye bye... */
+}
+/*
+ *             Find the user state vector context for the current thread.  If there is no user state context,
+ *             we just return a 0.
+ */
+
+savearea_vec *find_user_vec_curr(void) {
 
        savearea_vec    *vsv;
+       thread_t                thread = current_thread();
+       boolean_t               intr;
+       
+       vec_save(thread->machine.curctx);                                               /* Force save if live */
 
-       vsv = act->mact.curctx->VMXsave;                                /* Get the start of the vector chain */
+       intr = ml_set_interrupts_enabled(FALSE);
+       vsv = thread->machine.curctx->VMXsave;                          /* Get the start of the vector chain */
        
        while(vsv) {                                                                    /* Look until the end or we find it */
                if(!(vsv->save_hdr.save_level)) break;          /* Is the the user state stuff? (the level is 0 if so) */       
-               vsv = (savearea_vec *)vsv->save_hdr.save_prev;  /* Try the previous one */
+               vsv = CAST_DOWN(savearea_vec *, vsv->save_hdr.save_prev);       /* Try the previous one */ 
        }
+       (void) ml_set_interrupts_enabled(intr);
        
        return vsv;                                                                             /* Bye bye... */
 }
@@ -764,34 +1218,67 @@ savearea_vec *find_user_vec(thread_act_t act) {
  */
 kern_return_t
 thread_userstack(
-    thread_t            thread,
+    __unused thread_t  thread,
     int                 flavor,
     thread_state_t      tstate,
     unsigned int        count,
-    vm_offset_t         *user_stack,
+    mach_vm_offset_t   *user_stack,
        int                                     *customstack
 )
 {
-        struct ppc_thread_state *state;
-
-       if (customstack)
-               *customstack = 0;
+        /*
+         * Set a default.
+         */
 
         switch (flavor) {
         case PPC_THREAD_STATE:
+               {
+                       struct ppc_thread_state *state;
+
                 if (count < PPC_THREAD_STATE_COUNT)
                         return (KERN_INVALID_ARGUMENT);
  
                 state = (struct ppc_thread_state *) tstate;
     
-                /* If a valid user stack is specified, use it. */
-               if (state->r1)
-                       *user_stack = state->r1;
-
-               if (customstack && state->r1)
-                       *customstack = 1;
+                /*
+                 * If a valid user stack is specified, use it.
+                 */
+                       if (state->r1) {
+                               *user_stack = CAST_USER_ADDR_T(state->r1);
+                               if (customstack)
+                                       *customstack = 1;
+                       } else {
+                               *user_stack = CAST_USER_ADDR_T(USRSTACK);
+                               if (customstack)
+                                       *customstack = 0;
+                       }
+               }
+                break;
+                                       
+       case PPC_THREAD_STATE64:
+               {
+                       struct ppc_thread_state64 *state64;
+                                       
+                       if (count < PPC_THREAD_STATE64_COUNT)
+                               return (KERN_INVALID_ARGUMENT);
 
+                       state64 = (struct ppc_thread_state64 *)tstate;
+
+                       /*
+                        * If a valid user stack is specified, use it.
+                        */
+                       if (state64->r1 != MACH_VM_MIN_ADDRESS) {
+                               *user_stack = state64->r1;
+                               if (customstack)
+                                       *customstack = 1;
+                       } else {
+                               *user_stack = USRSTACK64;
+                               if (customstack)
+                                       *customstack = 0;
+                       }
+               }
                 break;
+               
         default :
                 return (KERN_INVALID_ARGUMENT);
         }
@@ -806,11 +1293,12 @@ thread_userstack(
  * Sets the user stack pointer into the machine
  * dependent thread state info.
  */
-void thread_setuserstack(struct thread_activation *act, unsigned int user_stack)
+void
+thread_setuserstack(thread_t thread, mach_vm_address_t user_stack)
 {
        savearea *sv;
        
-       sv = get_user_regs(act);                /* Get the user state registers */
+       sv = get_user_regs(thread);     /* Get the user state registers */
        
        sv->save_r1 = user_stack;
        
@@ -821,17 +1309,18 @@ void thread_setuserstack(struct thread_activation *act, unsigned int user_stack)
  * thread_adjuserstack:
  *
  * Returns the adjusted user stack pointer from the machine
- * dependent thread state info.
+ * dependent thread state info.  Usef for small (<2G) deltas.
  */
-unsigned int thread_adjuserstack(struct thread_activation *act, int adjust)
+uint64_t
+thread_adjuserstack(thread_t thread, int adjust)
 {
        savearea *sv;
        
-       sv = get_user_regs(act);                /* Get the user state registers */
+       sv = get_user_regs(thread);     /* Get the user state registers */
        
-       sv->save_r1 += adjust;                  /* Adjust the stack */
+       sv->save_r1 += adjust;          /* Adjust the stack */
        
-       return sv->save_r1;                             /* Return the adjusted stack */
+       return sv->save_r1;             /* Return the adjusted stack */
        
 }    
 
@@ -842,11 +1331,12 @@ unsigned int thread_adjuserstack(struct thread_activation *act, int adjust)
  * dependent thread state info.
  */
 
-void thread_setentrypoint(struct thread_activation *act, unsigned int entry)
+void
+thread_setentrypoint(thread_t thread, uint64_t entry)
 {
        savearea *sv;
        
-       sv = get_user_regs(act);                /* Get the user state registers */
+       sv = get_user_regs(thread);     /* Get the user state registers */
        
        sv->save_srr0 = entry;
        
@@ -855,24 +1345,27 @@ void thread_setentrypoint(struct thread_activation *act, unsigned int entry)
 
 kern_return_t
 thread_entrypoint(
-    thread_t            thread,
+    __unused thread_t  thread,
     int                 flavor,
     thread_state_t      tstate,
     unsigned int        count,
-    vm_offset_t         *entry_point
+    mach_vm_offset_t   *entry_point
 )
 { 
-    struct ppc_thread_state     *state;
+#if 0
+       /* Silly code: "if *entry_point is 0, make it 0" */
     /*
      * Set a default.
      */
-    if (*entry_point == 0)
-        *entry_point = VM_MIN_ADDRESS;
+    if (*entry_point == 0ULL)
+        *entry_point = MACH_VM_MIN_ADDRESS;
+#endif
     
     switch (flavor) {   
-    
     case PPC_THREAD_STATE:
+       {
+           struct ppc_thread_state     *state;
+
         if (count < PPC_THREAD_STATE_COUNT)
             return (KERN_INVALID_ARGUMENT);
 
@@ -881,8 +1374,34 @@ thread_entrypoint(
         /* 
          * If a valid entry point is specified, use it.
          */     
-        *entry_point = state->srr0 ? state->srr0: VM_MIN_ADDRESS;
+           if (state->srr0) {
+               *entry_point = CAST_USER_ADDR_T(state->srr0);
+           } else {
+               *entry_point = CAST_USER_ADDR_T(VM_MIN_ADDRESS);
+           }
+       }
         break; 
+
+    case PPC_THREAD_STATE64:
+       {
+           struct ppc_thread_state64     *state64;
+
+           if (count < PPC_THREAD_STATE_COUNT)
+               return (KERN_INVALID_ARGUMENT);
+
+           state64 = (struct ppc_thread_state64 *)tstate;
+
+           /* 
+            * If a valid entry point is specified, use it.
+            */     
+           if (state64->srr0) {
+               *entry_point = state64->srr0;
+           } else {
+               *entry_point = MACH_VM_MIN_ADDRESS;
+           }
+       }
+        break; 
+
     default: 
         return (KERN_INVALID_ARGUMENT);
     }           
@@ -904,22 +1423,46 @@ unsigned int get_msr_rbits(void)
        return (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE));
 }
 
-void  thread_set_child(thread_act_t child, int pid)
+void ppc_checkthreadstate(void * tsptr, int flavor)
+{
+       if (flavor == PPC_THREAD_STATE64) {
+               struct ppc_thread_state64 *ts64 =(struct ppc_thread_state64 *)tsptr;
+
+               /* Make sure naughty bits are off and necessary bits are on */
+               ts64->srr1 &= ~(MASK(MSR_POW)|MASK(MSR_ILE)|MASK(MSR_IP)|MASK(MSR_LE));
+               ts64->srr1 |= (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE));
+       } else {
+               struct ppc_thread_state *ts =(struct ppc_thread_state *)tsptr;
+
+               /* Make sure naughty bits are off and necessary bits are on */
+               ts->srr1 &= ~(MASK(MSR_POW)|MASK(MSR_ILE)|MASK(MSR_IP)|MASK(MSR_LE));
+               ts->srr1 |= (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE));
+       }
+       return;
+}
+
+void
+thread_set_child(
+       thread_t        child,
+       int                     pid)
 {
        struct savearea *child_state;
        
        child_state = get_user_regs(child);
        
-       child_state->save_r3 = pid;
-       child_state->save_r4 = 1;
+       child_state->save_r3 = (uint_t)pid;
+       child_state->save_r4 = 1ULL;
 }
-void  thread_set_parent(thread_act_t parent, int pid)
+void
+thread_set_parent(
+       thread_t        parent,
+       int                     pid)
 {
        struct savearea *parent_state;
        
        parent_state = get_user_regs(parent);
        
-       parent_state->save_r3 = pid;
+       parent_state->save_r3 = (uint64_t)pid;
        parent_state->save_r4 = 0;
 }
 
@@ -938,24 +1481,23 @@ void *act_thread_csave(void) {
        savearea                *sv, *osv;
        savearea_fpu    *fsv, *ofsv;
        savearea_vec    *vsv, *ovsv;
-       unsigned int    spc, i, *srs;
        
-       thread_act_t act;       
+       thread_t thread;        
        
-       act = current_act();                                                    /* Find ourselves */    
+       thread = current_thread();
        
-       fpu_save(act->mact.curctx);                                             /* Make certain floating point state is all saved */
-       vec_save(act->mact.curctx);                                             /* Make certain the vector state is all saved */
+       fpu_save(thread->machine.curctx);                                               /* Make certain floating point state is all saved */
+       vec_save(thread->machine.curctx);                                               /* Make certain the vector state is all saved */
 
-       osv = find_user_regs(act);                                              /* Get our savearea */
+       osv = find_user_regs(thread);                                           /* Get our savearea */
 
        if(!osv) {
-               panic("act_thread_csave: attempting to preserve the context of an activation with none (%08X)\n", act);
+               panic("act_thread_csave: attempting to preserve the context of an activation with none (%08X)\n", thread);
        }
        
        sv = save_alloc();                                                              /* Get a fresh save area to save into */
        sv->save_hdr.save_flags = (sv->save_hdr.save_flags & ~SAVtype) | (SAVgeneral << SAVtypeshft);   /* Mark as in use as general */
-       sv->save_hdr.save_act = act;                                    /* Point to the activation */
+       sv->save_hdr.save_act = thread;
        sv->save_hdr.save_prev = 0;                                             /* Mark no more */
        sv->save_hdr.save_level = 0;                                    /* Mark user state */
        
@@ -964,46 +1506,46 @@ void *act_thread_csave(void) {
                (char *)((unsigned int)sv + sizeof(savearea_comm)), 
                sizeof(struct savearea) - sizeof(savearea_comm));
        
-       sv->save_srr1 &= ~(MASK(MSR_FP) | MASK(MSR_VEC));       /* Make certain that floating point and vector are turned off */        
+       sv->save_srr1 &= (uint64_t)(~(MASK(MSR_FP) | MASK(MSR_VEC)));   /* Make certain that floating point and vector are turned off */        
        
        sv->save_hdr.save_misc2 = 0xDEBB1ED0;                   /* Eye catcher for debug */
        sv->save_hdr.save_misc3 = 0xE5DA11A5;                   /* Eye catcher for debug */
        
 
-       ofsv = find_user_fpu(act);                                              /* Get any user floating point */
+       ofsv = find_user_fpu(thread);                                           /* Get any user floating point */
 
        sv->save_hdr.save_misc0 = 0;                                    /* Assume no floating point */
 
        if(ofsv) {                                                                              /* Did we find one? */
                fsv = (savearea_fpu *)save_alloc();                     /* If we still don't have one, get a new one */
                fsv->save_hdr.save_flags = (fsv->save_hdr.save_flags & ~SAVtype) | (SAVfloat << SAVtypeshft);   /* Mark as in use as float */
-               fsv->save_hdr.save_act = act;                           /* Point to the activation */
+               fsv->save_hdr.save_act = thread;
                fsv->save_hdr.save_prev = 0;                            /* Mark no more */
                fsv->save_hdr.save_level = 0;                           /* Mark user state */
                fsv->save_hdr.save_misc2 = 0xDEBB1ED0;          /* Eye catcher for debug */
                fsv->save_hdr.save_misc3 = 0xE5DA11A5;          /* Eye catcher for debug */
 
-               sv->save_hdr.save_misc0 = (unsigned int)fsv;    /* Remember this one */
+               sv->save_hdr.save_misc0 = (uint64_t)((uintptr_t)fsv);   /* Remember this one */
 
                bcopy((char *)((unsigned int)ofsv + sizeof(savearea_comm)),     /* Copy everything but the headers */
                        (char *)((unsigned int)fsv + sizeof(savearea_comm)), 
                        sizeof(struct savearea) - sizeof(savearea_comm));
        }
 
-       ovsv = find_user_vec(act);                                              /* Get any user vector */
+       ovsv = find_user_vec(thread);                                           /* Get any user vector */
        
        sv->save_hdr.save_misc1 = 0;                                    /* Assume no vector */
 
        if(ovsv) {                                                                              /* Did we find one? */
                vsv = (savearea_vec *)save_alloc();                     /* If we still don't have one, get a new one */
                vsv->save_hdr.save_flags = (vsv->save_hdr.save_flags & ~SAVtype) | (SAVvector << SAVtypeshft);  /* Mark as in use as float */
-               vsv->save_hdr.save_act = act;                           /* Point to the activation */
+               vsv->save_hdr.save_act = thread;
                vsv->save_hdr.save_prev = 0;                            /* Mark no more */
                vsv->save_hdr.save_level = 0;                           /* Mark user state */
                vsv->save_hdr.save_misc2 = 0xDEBB1ED0;          /* Eye catcher for debug */
                vsv->save_hdr.save_misc3 = 0xE5DA11A5;          /* Eye catcher for debug */
 
-               sv->save_hdr.save_misc1 = (unsigned int)vsv;    /* Chain in the floating point */
+               sv->save_hdr.save_misc1 = (uint64_t)((uintptr_t)vsv);   /* Chain in the floating point */
 
                bcopy((char *)((unsigned int)ovsv + sizeof(savearea_comm)),     /* Copy everything but the headers */
                        (char *)((unsigned int)vsv + sizeof(savearea_comm)), 
@@ -1031,13 +1573,13 @@ void act_thread_catt(void *ctx) {
        savearea                *sv, *osv, *psv;
        savearea_fpu    *fsv, *ofsv, *pfsv;
        savearea_vec    *vsv, *ovsv, *pvsv;
-       unsigned int    spc, i, *srs;
-       thread_act_t act;       
+       unsigned int    spc;
+       thread_t thread;        
        
        sv = (savearea *)ctx;                                                   /* Make this easier for C */
        
-       fsv = (savearea_fpu *)sv->save_hdr.save_misc0;  /* Get a possible floating point savearea */
-       vsv = (savearea_vec *)sv->save_hdr.save_misc1;  /* Get a possible vector savearea */
+       fsv = CAST_DOWN(savearea_fpu *, sv->save_hdr.save_misc0);       /* Get a possible floating point savearea */ 
+       vsv = CAST_DOWN(savearea_vec *, sv->save_hdr.save_misc1);       /* Get a possible vector savearea */ 
        
        if((sv->save_hdr.save_misc2 != 0xDEBB1ED0) || (sv->save_hdr.save_misc3 != 0xE5DA11A5)) {        /* See if valid savearea */
                panic("act_thread_catt: attempt to attach invalid general context savearea - %08X\n", sv);      /* Die */
@@ -1051,89 +1593,85 @@ void act_thread_catt(void *ctx) {
                panic("act_thread_catt: attempt to attach invalid vector context savearea - %08X\n", vsv);      /* Die */
        }
 
-       act = current_act();                                                    /* Find ourselves */    
+       thread = current_thread();
 
-       toss_live_fpu(act->mact.curctx);                                /* Toss my floating point if live anywhere */
-       toss_live_vec(act->mact.curctx);                                /* Toss my vector if live anywhere */
+       toss_live_fpu(thread->machine.curctx);                          /* Toss my floating point if live anywhere */
+       toss_live_vec(thread->machine.curctx);                          /* Toss my vector if live anywhere */
                
        sv->save_hdr.save_misc2 = 0;                                    /* Eye catcher for debug */
        sv->save_hdr.save_misc3 = 0;                                    /* Eye catcher for debug */
-       sv->save_hdr.save_act = act;                                    /* Set us as owner */
+       sv->save_hdr.save_act = thread;
        
-       spc = (unsigned int)act->map->pmap->space;              /* Get the space we're in */
+       spc = (unsigned int)thread->map->pmap->space;           /* Get the space we're in */
        
-       srs = (unsigned int *)&sv->save_sr0;                    /* Point to the SRs */
-       for(i = 0; i < 16; i++) {                                               /* Fill in the SRs for the new context */
-               srs[i] = SEG_REG_PROT | (i<<20) | spc;          /* Set the SRs */
-       }
-       
-       osv = act->mact.pcb;                                                    /* Get the top general savearea */
+       osv = thread->machine.pcb;                                                      /* Get the top general savearea */
        psv = 0;
        while(osv) {                                                                    /* Any saved state? */
                if(osv->save_srr1 & MASK(MSR_PR)) break;        /* Leave if this is user state */
                psv = osv;                                                                      /* Save previous savearea address */
-               osv = osv->save_hdr.save_prev;                          /* Get one underneath our's */
+               osv = CAST_DOWN(savearea *, osv->save_hdr.save_prev);   /* Get one underneath our's */
        }
        
        if(osv) {                                                                               /* Did we find one? */
                if(psv) psv->save_hdr.save_prev = 0;            /* Yes, clear pointer to it (it should always be last) or */    
-               else act->mact.pcb = 0;                                         /* to the start if the only one */
+               else thread->machine.pcb = 0;                                           /* to the start if the only one */
 
                save_release(osv);                                                      /* Nope, release it */
                
        }
 
-       if(psv) psv->save_hdr.save_prev = sv;                   /* Chain us to the end or */
-       else act->mact.pcb = (pcb_t)sv;                                 /* to the start if the only one */
+       if(psv) psv->save_hdr.save_prev = (addr64_t)((uintptr_t)sv);    /* Chain us to the end or */
+       else thread->machine.pcb = (pcb_t)sv;                                   /* to the start if the only one */
+       thread->machine.upcb = (pcb_t)sv;                                               /* Set the user pcb */
        
-       ovsv = act->mact.curctx->VMXsave;                               /* Get the top vector savearea */
+       ovsv = thread->machine.curctx->VMXsave;                         /* Get the top vector savearea */
        
        pvsv = 0;
        while(ovsv) {                                                                   /* Any VMX saved state? */
                if(!(ovsv->save_hdr.save_level)) break;         /* Leave if this is user state */
                pvsv = ovsv;                                                            /* Save previous savearea address */
-               ovsv = (savearea_vec *)ovsv->save_hdr.save_prev;        /* Get one underneath our's */
+               ovsv = CAST_DOWN(savearea_vec *, ovsv->save_hdr.save_prev);     /* Get one underneath our's */ 
        }
        
        if(ovsv) {                                                                              /* Did we find one? */
                if(pvsv) pvsv->save_hdr.save_prev = 0;          /* Yes, clear pointer to it (it should always be last) or */    
-               else act->mact.curctx->VMXsave = 0;                     /* to the start if the only one */
+               else thread->machine.curctx->VMXsave = 0;                       /* to the start if the only one */
 
                save_release((savearea *)ovsv);                         /* Nope, release it */
        }
        
        if(vsv) {                                                                               /* Are we sticking any vector on this one? */
-               if(pvsv) pvsv->save_hdr.save_prev = (savearea *)vsv;    /* Yes, chain us to the end or */
-               else act->mact.curctx->VMXsave = vsv;           /* to the start if the only one */
+               if(pvsv) pvsv->save_hdr.save_prev = (addr64_t)((uintptr_t)vsv); /* Yes, chain us to the end or */
+               else thread->machine.curctx->VMXsave = vsv;             /* to the start if the only one */
 
                vsv->save_hdr.save_misc2 = 0;                           /* Eye catcher for debug */
                vsv->save_hdr.save_misc3 = 0;                           /* Eye catcher for debug */
-               vsv->save_hdr.save_act = act;                           /* Set us as owner */
+               vsv->save_hdr.save_act = thread;
        }
        
-       ofsv = act->mact.curctx->FPUsave;                               /* Get the top float savearea */
+       ofsv = thread->machine.curctx->FPUsave;                         /* Get the top float savearea */
        
        pfsv = 0;
        while(ofsv) {                                                                   /* Any float saved state? */
                if(!(ofsv->save_hdr.save_level)) break;         /* Leave if this is user state */
                pfsv = ofsv;                                                            /* Save previous savearea address */
-               ofsv = (savearea_fpu *)ofsv->save_hdr.save_prev;        /* Get one underneath our's */
+               ofsv = CAST_DOWN(savearea_fpu *, ofsv->save_hdr.save_prev);     /* Get one underneath our's */
        }
        
        if(ofsv) {                                                                              /* Did we find one? */
                if(pfsv) pfsv->save_hdr.save_prev = 0;          /* Yes, clear pointer to it (it should always be last) or */    
-               else act->mact.curctx->FPUsave = 0;                     /* to the start if the only one */
+               else thread->machine.curctx->FPUsave = 0;                       /* to the start if the only one */
 
                save_release((savearea *)ofsv);                         /* Nope, release it */
        }
        
        if(fsv) {                                                                               /* Are we sticking any vector on this one? */
-               if(pfsv) pfsv->save_hdr.save_prev = (savearea *)fsv;    /* Yes, chain us to the end or */
-               else act->mact.curctx->FPUsave = fsv;           /* to the start if the only one */
+               if(pfsv) pfsv->save_hdr.save_prev = (addr64_t)((uintptr_t)fsv); /* Yes, chain us to the end or */
+               else thread->machine.curctx->FPUsave = fsv;             /* to the start if the only one */
 
                fsv->save_hdr.save_misc2 = 0;                           /* Eye catcher for debug */
                fsv->save_hdr.save_misc3 = 0;                           /* Eye catcher for debug */
-               fsv->save_hdr.save_act = act;                           /* Set us as owner */
+               fsv->save_hdr.save_act = thread;
        }
        
 }
@@ -1146,16 +1684,18 @@ void act_thread_catt(void *ctx) {
  *
  */
 
-void act_thread_cfree(void *ctx) {
+void
+act_thread_cfree(void *ctx)
+{
 
-       savearea                *sv, *osv;
-       savearea_fpu    *fsv, *ofsv;
-       savearea_vec    *vsv, *ovsv, *pvsv;
+       savearea        *sv;
+       savearea_fpu    *fsv;
+       savearea_vec    *vsv;
 
        sv = (savearea *)ctx;                                                   /* Make this easier for C */
        
-       fsv = (savearea_fpu *)sv->save_hdr.save_misc0;  /* Get a possible floating point savearea */
-       vsv = (savearea_vec *)sv->save_hdr.save_misc1;  /* Get a possible vector savearea */
+       fsv = CAST_DOWN(savearea_fpu *, sv->save_hdr.save_misc0);       /* Get a possible floating point savearea */ 
+       vsv = CAST_DOWN(savearea_vec *, sv->save_hdr.save_misc1);       /* Get a possible vector savearea */ 
        
        if((sv->save_hdr.save_misc2 != 0xDEBB1ED0) || (sv->save_hdr.save_misc3 != 0xE5DA11A5)) {        /* See if valid savearea */
                panic("act_thread_cfree: attempt to detatch invalid general context savearea - %08X\n", sv);    /* Die */
@@ -1188,19 +1728,20 @@ void act_thread_cfree(void *ctx) {
  * enables or disables floating point exceptions for the thread.
  * returns old state
  */
-int thread_enable_fpe(thread_act_t act, int onoff)
+int thread_enable_fpe(
+       thread_t                thread,
+       int                             onoff)
 {
         savearea *sv;
-        unsigned int oldmsr;
+        uint64_t oldmsr;
 
-        sv = find_user_regs(act);                                               /* Find the user registers */
-        if(!sv) sv = get_user_regs(act);                                /* Didn't find any, allocate and initialize o
-ne */
+        sv = find_user_regs(thread);                                                                           /* Find the user registers */
+        if(!sv) sv = get_user_regs(thread);                                                                    /* Didn't find any, allocate and initialize one */
 
-        oldmsr = sv->save_srr1;                                                 /* Get the old msr */
+        oldmsr = sv->save_srr1;                                                                                                /* Get the old msr */
 
-        if(onoff) sv->save_srr1 = oldmsr | MASK(MSR_FE0) | MASK(MSR_FE1);       /* Flip on precise FP exceptions */
-        else sv->save_srr1 = oldmsr & ~(MASK(MSR_FE0) | MASK(MSR_FE1)); /* Flip on precise FP exceptions */
+        if(onoff) sv->save_srr1 = oldmsr | (uint64_t)(MASK(MSR_FE0) | MASK(MSR_FE1));  /* Flip on precise FP exceptions */
+        else sv->save_srr1 = oldmsr & (uint64_t)(~(MASK(MSR_FE0) | MASK(MSR_FE1)));            /* Flip on precise FP exceptions */
 
-        return ((oldmsr & (MASK(MSR_FE0) | MASK(MSR_FE1))) != 0);       /* Return if it was enabled or not */
+        return ((oldmsr & (MASK(MSR_FE0) | MASK(MSR_FE1))) != 0);                      /* Return if it was enabled or not */
 }