Index: vm/vm_glue.c
===================================================================
--- vm/vm_glue.c	(revision 256815)
+++ vm/vm_glue.c	(working copy)
@@ -364,6 +364,14 @@
 	    M_BESTFIT | M_NOWAIT, &ks)) {
 		ks = 0;
 	}
+#elif defined(__arm__) && defined(ARM_ARCH_6)
+	if (vmem_xalloc(kernel_arena,
+	    (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE, 
+	    KSTACK_MAX_PAGES * PAGE_SIZE, 
+	    (KSTACK_MAX_PAGES - (pages + KSTACK_GUARD_PAGES)) * PAGE_SIZE, 0,
+	     VMEM_ADDR_MIN, VMEM_ADDR_MAX,
+	    M_BESTFIT | M_NOWAIT, &ks))
+		ks = 0;
 #else
 	ks = kva_alloc((pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
 #endif
Index: vm/vm_init.c
===================================================================
--- vm/vm_init.c	(revision 256815)
+++ vm/vm_init.c	(working copy)
@@ -227,6 +227,7 @@
 	    (long)bio_transient_maxcnt * MAXPHYS;
 	kmi->clean_sva = firstaddr = kva_alloc(size);
 	kmi->clean_eva = firstaddr + size;
+	printf("SET CLEAN SVA TO %x\n", kmi->clean_sva);
 
 	/*
 	 * Allocate the buffer arena.
Index: kern/kern_idle.c
===================================================================
--- kern/kern_idle.c	(revision 256815)
+++ kern/kern_idle.c	(working copy)
@@ -59,6 +59,7 @@
 	int error;
 
 	p = NULL; /* start with no idle process */
+	printf("SETTING UP IDLE THREAD YOYOYOYOYOYOYO\n");
 #ifdef SMP
 	STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
 #endif
@@ -66,6 +67,7 @@
 		error = kproc_kthread_add(sched_idletd, NULL, &p, &td,
 		    RFSTOPPED | RFHIGHPID, 0, "idle", "idle: cpu%d", pc->pc_cpuid);
 		pc->pc_idlethread = td;
+		printf("LOLOLOL\n");
 #else
 		error = kproc_kthread_add(sched_idletd, NULL, &p, &td,
 		    RFSTOPPED | RFHIGHPID, 0, "idle", "idle");
Index: arm/include/param.h
===================================================================
--- arm/include/param.h	(revision 256815)
+++ arm/include/param.h	(working copy)
@@ -125,6 +125,13 @@
 #define KSTACK_GUARD_PAGES	1
 #endif /* !KSTACK_GUARD_PAGES */
 
+/* Must be a power of 2 */
+#ifndef KSTACK_MAX_PAGES
+#define KSTACK_MAX_PAGES	32
+#endif /* !KSTACK_MAX_PAGES */
+
+#define KSTACK_MAX_MASK		((KSTACK_MAX_PAGES * PAGE_SIZE) - 1)
+
 #define USPACE_SVC_STACK_TOP		KSTACK_PAGES * PAGE_SIZE
 #define USPACE_SVC_STACK_BOTTOM		(USPACE_SVC_STACK_TOP - 0x1000)
 #define USPACE_UNDEF_STACK_TOP		(USPACE_SVC_STACK_BOTTOM - 0x10)
Index: arm/include/pcb.h
===================================================================
--- arm/include/pcb.h	(revision 256815)
+++ arm/include/pcb.h	(working copy)
@@ -80,6 +80,7 @@
 #define PCB_NOALIGNFLT	0x00000002
 	caddr_t	pcb_onfault;			/* On fault handler */
 	struct	pcb_arm32 un_32;
+	void 	*pcb_curthread;
 	struct vfp_state pcb_vfpstate;          /* VP/NEON state */
 	u_int pcb_vfpcpu;                       /* VP/NEON last cpu */
 };
Index: arm/include/asmacros.h
===================================================================
--- arm/include/asmacros.h	(revision 256815)
+++ arm/include/asmacros.h	(working copy)
@@ -82,9 +82,7 @@
 	sub	sp, sp, #4;		/* Align the stack */		   \
 	str	lr, [sp, #-4]!;		/* Push the return address */	   \
 	sub	sp, sp, #(4*17);	/* Adjust the stack pointer */	   \
-	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
-	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
-	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	stmia	sp, {r0-r14}^;		/* Push the user mode registers */ \
         mov     r0, r0;                 /* NOP for previous instruction */ \
 	mrs	r0, spsr_all;		/* Put the SPSR on the stack */	   \
 	str	r0, [sp, #-4]!;
@@ -182,9 +180,7 @@
 	msr     spsr_all, r3;		/* Restore correct spsr */	   \
 	ldmdb	r1, {r0-r3};		/* Restore 4 regs from xxx mode */ \
 	sub	sp, sp, #(4*15);	/* Adjust the stack pointer */	   \
-	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
-	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
-	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	stmia	sp, {r0-r14}^;		/* Push the user mode registers */ \
         mov     r0, r0;                 /* NOP for previous instruction */ \
 	mrs	r0, spsr_all;		/* Put the SPSR on the stack */	   \
 	str	r0, [sp, #-4]!
@@ -234,8 +230,23 @@
 name:
 
 #ifdef _ARM_ARCH_6
-#define	AST_LOCALS
-#define GET_CURTHREAD_PTR(tmp) \
+#define KSTACK_LOCALS \
+.Lkstack_consts:	\
+	.word KSTACK_ADDR_MASK;	\
+	.word KSTACK_PCB_ADDR;	
+#define	AST_LOCALS KSTACK_LOCALS
+
+#define GET_PCB(tmp, tmp2) \
+	ldr tmp2, .Lkstack_consts; \
+	bic tmp, sp, tmp2; \
+	ldr tmp2, .Lkstack_consts + 4; \
+	add tmp, tmp,  tmp2
+
+#define GET_CURTHREAD(tmp, tmp2) \
+	GET_PCB(tmp, tmp2); \
+	ldr tmp, [tmp, #PCB_CURTHREAD]
+
+#define GET_PCPU_CURTHREAD_PTR(tmp) \
 	mrc p15, 0, tmp, c13, c0, 4; \
 	add	tmp, tmp, #(PC_CURTHREAD)
 #else
@@ -243,8 +254,12 @@
 .Lcurthread:								;\
 	.word	_C_LABEL(__pcpu) + PC_CURTHREAD
 
-#define GET_CURTHREAD_PTR(tmp) \
+#define GET_PCPU_CURTHREAD_PTR(tmp) \
 	ldr	tmp, .Lcurthread
+
+#define GET_CURTHREAD(tmp, tmp2) \
+	ldr	tmp, .Lcurthread; \
+	ldr	tmp, [tmp]
 #endif
 
 #define	DO_AST								\
@@ -256,8 +271,7 @@
 	teq	r0, #(PSR_USR32_MODE)					;\
 	bne	2f			/* Nope, get out now */		;\
 	bic	r4, r4, #(I32_bit|F32_bit)				;\
-1:	GET_CURTHREAD_PTR(r5)						;\
-	ldr	r5, [r5]						;\
+1:	GET_CURTHREAD(r5, r6)						;\
 	ldr	r1, [r5, #(TD_FLAGS)]					;\
 	and	r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED)		;\
 	teq	r1, #0x00000000						;\
Index: arm/include/pcpu.h
===================================================================
--- arm/include/pcpu.h	(revision 256815)
+++ arm/include/pcpu.h	(working copy)
@@ -33,8 +33,14 @@
 #ifdef _KERNEL
 
 #include <machine/cpuconf.h>
+#include <machine/cpufunc.h>
 #include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/atomic.h>
 
+#include <sys/types.h>
+#include <sys/systm.h>
+
 #define	ALT_STACK_SIZE	128
 
 struct vmspace;
@@ -94,15 +100,95 @@
 
 	__asm __volatile("mcr p15, 0, %0, c13, c0, 3" : : "r" (tls));
 }
+
+/*
+ * Evaluates to the byte offset of the per-cpu variable name.
+ */
+#define	__pcpu_offset(name)						\
+	__offsetof(struct pcpu, name)
+
+/*
+ * Evaluates to the type of the per-cpu variable name.
+ */
+#define	__pcpu_type(name)						\
+	__typeof(((struct pcpu *)0)->name)
+
+/*
+ * Evaluates to the address of the per-cpu variable name.
+ */
+#define	__PCPU_PTR(name) __extension__ ({				\
+	__pcpu_type(name) *__p;						\
+    	int __s;							\
+									\
+    	__s = disable_interrupts(I32_bit | F32_bit);			\
+	__p = &get_pcpu()->name;					\
+    	restore_interrupts(__s);					\
+	__p;								\
+})
+
+/*
+ * Evaluates to the value of the per-cpu variable name.
+ */
+#define	__PCPU_GET(name) __extension__ ({				\
+    	int __s;							\
+	__pcpu_type(name) __res;					\
+    	__s = disable_interrupts(I32_bit | F32_bit);			\
+	__res = get_pcpu()->name;					\
+    	restore_interrupts(__s);					\
+	__res;								\
+})
+
+/*
+ * Adds the value to the per-cpu counter name.  The implementation
+ * must be atomic with respect to interrupts.
+ */
+#define	__PCPU_ADD(name, val) do {					\
+	int __s ;							\
+	__s = disable_interrupts(I32_bit | F32_bit);			\
+	get_pcpu()->name += (val);					\
+	restore_interrupts(__s);					\
+} while (0)
+
+/*
+ * Sets the value of the per-cpu variable name to value val.
+ */
+#define	__PCPU_SET(name, val) {						\
+	int __s;							\
+	__s = disable_interrupts(I32_bit | F32_bit);			\
+	get_pcpu()->name = val;						\
+	restore_interrupts(__s);					\
+}
+
+#define	PCPU_GET(member)	__PCPU_GET(pc_ ## member)
+#define	PCPU_ADD(member, val)	__PCPU_ADD(pc_ ## member, val)
+#define	PCPU_INC(member)	PCPU_ADD(member, 1)
+#define	PCPU_PTR(member)	__PCPU_PTR(pc_ ## member)
+#define	PCPU_SET(member, val)	__PCPU_SET(pc_ ## member, val)
+
+static __inline struct pcb *
+__curpcb(void)
+{
+	register_t sp;
+
+	__asm __volatile("mov %0, sp" : "=r" (sp));
+	return ((struct pcb *)((sp &~ KSTACK_MAX_MASK) + 
+		(KSTACK_MAX_PAGES * PAGE_SIZE - sizeof(struct pcb))));
+}
+
+
+#define curpcb (__curpcb())
+#define curthread ((struct thread *)(curpcb->pcb_curthread))
+
+
 #else
 #define get_pcpu()	pcpup
-#endif
 
 #define	PCPU_GET(member)	(get_pcpu()->pc_ ## member)
 #define	PCPU_ADD(member, value)	(get_pcpu()->pc_ ## member += (value))
 #define	PCPU_INC(member)	PCPU_ADD(member, 1)
 #define	PCPU_PTR(member)	(&get_pcpu()->pc_ ## member)
 #define	PCPU_SET(member,value)	(get_pcpu()->pc_ ## member = (value))
+#endif
 
 void pcpu0_init(void);
 #endif	/* _KERNEL */
Index: arm/arm/copystr.S
===================================================================
--- arm/arm/copystr.S	(revision 256815)
+++ arm/arm/copystr.S	(working copy)
@@ -51,15 +51,14 @@
 	.align	0
 
 #ifdef _ARM_ARCH_6
-#define GET_PCB(tmp) \
-	mrc p15, 0, tmp, c13, c0, 4; \
-	add	tmp, tmp, #(PC_CURPCB)
+KSTACK_LOCALS
 #else
 .Lpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 
-#define GET_PCB(tmp) \
-	ldr	tmp, .Lpcb
+#define GET_PCB(tmp, tmp2) \
+	ldr	tmp, .Lpcb; \
+	ldr	tmp, [tmp]
 #endif
 
 /*
@@ -114,8 +113,7 @@
 	moveq	r0, #ENAMETOOLONG
 	beq	2f
 
-	GET_PCB(r4)
-	ldr	r4, [r4]
+	GET_PCB(r4, r5)
 
 #ifdef DIAGNOSTIC
 	teq	r4, #0x00000000
@@ -162,8 +160,7 @@
 	moveq	r0, #ENAMETOOLONG
 	beq	2f
 
-	GET_PCB(r4)
-	ldr	r4, [r4]
+	GET_PCB(r4, r5)
 
 #ifdef DIAGNOSTIC
 	teq	r4, #0x00000000
Index: arm/arm/genassym.c
===================================================================
--- arm/arm/genassym.c	(revision 256815)
+++ arm/arm/genassym.c	(working copy)
@@ -25,6 +25,8 @@
  *
  */
 
+#include "opt_kstack_max_pages.h"
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 #include <sys/param.h>
@@ -69,6 +71,7 @@
 ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12));
 ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc));
 ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp));
+ASSYM(PCB_CURTHREAD, offsetof(struct pcb, pcb_curthread));
 
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
 ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
@@ -138,3 +141,6 @@
 
 ASSYM(MAXCOMLEN, MAXCOMLEN);
 ASSYM(NIRQ, NIRQ);
+
+ASSYM(KSTACK_ADDR_MASK, KSTACK_MAX_PAGES * PAGE_SIZE - 1);
+ASSYM(KSTACK_PCB_ADDR, KSTACK_MAX_PAGES * PAGE_SIZE - sizeof(struct pcb));
Index: arm/arm/mp_machdep.c
===================================================================
--- arm/arm/mp_machdep.c	(revision 256815)
+++ arm/arm/mp_machdep.c	(working copy)
@@ -196,7 +196,6 @@
 		;
 
 	/* Initialize curthread */
-	KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
 	pc->pc_curthread = pc->pc_idlethread;
 	pc->pc_curpcb = pc->pc_idlethread->td_pcb;
 #ifdef VFP
@@ -205,6 +204,13 @@
 	vfp_init();
 #endif
 
+	/* 
+	 * We need to switch to the idlethread stack right away
+	 * as curthread depends on it.
+	 */
+	   
+	__asm __volatile("mov sp, %0" : :
+	    "r" (pc->pc_idlethread->td_pcb->un_32.pcb32_sp));
 	mtx_lock_spin(&ap_boot_mtx);
 
 	atomic_add_rel_32(&smp_cpus, 1);
Index: arm/arm/machdep.c
===================================================================
--- arm/arm/machdep.c	(revision 256815)
+++ arm/arm/machdep.c	(working copy)
@@ -42,6 +42,7 @@
  * Updated	: 18/04/01 updated for new wscons
  */
 
+#include "opt_kstack_max_pages.h"
 #include "opt_compat.h"
 #include "opt_ddb.h"
 #include "opt_platform.h"
@@ -874,9 +875,9 @@
 	set_pcpu(pcpup);
 #endif
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
-	PCPU_SET(curthread, &thread0);
+	pcpup->pc_curthread = &thread0;
 #ifdef VFP
-	PCPU_SET(cpu, 0);
+	pcpup->pc_cpu = 0;
 #endif
 }
 
@@ -1028,6 +1029,7 @@
 	thread0.td_pcb = (struct pcb *)
 		(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
 	thread0.td_pcb->pcb_flags = 0;
+	thread0.td_pcb->pcb_curthread = &thread0;
 	thread0.td_frame = &proc0_tf;
 	pcpup->pc_curpcb = thread0.td_pcb;
 }
@@ -1368,8 +1370,19 @@
 	valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
 	valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
 	valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
-	valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU);
 	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	if ((KSTACK_MAX_PAGES * PAGE_SIZE) - 
+	    (freemempos & (KSTACK_MAX_MASK)) >= KSTACK_PAGES)
+		freemempos = (freemempos &~ KSTACK_MAX_MASK) +
+		    (KSTACK_MAX_PAGES * PAGE_SIZE) - 
+		    (KSTACK_PAGES * PAGE_SIZE);
+	
+	else
+		freemempos = (freemempos &~ KSTACK_MAX_MASK) + 
+		2 * (KSTACK_MAX_PAGES * PAGE_SIZE) -
+		(KSTACK_PAGES * PAGE_SIZE);
+		
+	valloc_pages(kernelstack, KSTACK_PAGES);
 
 	/*
 	 * Now we start construction of the L1 page table
@@ -1494,8 +1507,6 @@
 	arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
 	pmap_bootstrap(freemempos, &kernel_l1pt);
 	msgbufp = (void *)msgbufpv.pv_va;
-	msgbufinit(msgbufp, msgbufsize);
-	mutex_init();
 
 	/*
 	 * Prepare map of physical memory regions available to vm subsystem.
@@ -1504,6 +1515,7 @@
 
 	init_param2(physmem);
 	kdb_init();
+	msgbufinit(msgbufp, msgbufsize);
 
 	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
 	    sizeof(struct pcb)));
Index: arm/arm/fusu.S
===================================================================
--- arm/arm/fusu.S	(revision 256815)
+++ arm/arm/fusu.S	(working copy)
@@ -40,14 +40,13 @@
 __FBSDID("$FreeBSD$");
 
 #ifdef _ARM_ARCH_6
-#define GET_PCB(tmp) \
-	mrc p15, 0, tmp, c13, c0, 4; \
-	add	tmp, tmp, #(PC_CURPCB)
+KSTACK_LOCALS
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
-#define GET_PCB(tmp) \
-	ldr	tmp, .Lcurpcb
+#define GET_PCB(tmp, tmp2) \
+	ldr	tmp, .Lcurpcb; \
+	ldr	tmp, [tmp]
 #endif
 
 /*
@@ -57,14 +56,9 @@
 
 ENTRY_NP(casuword32)
 ENTRY(casuword)
-	GET_PCB(r3)
-	ldr	r3, [r3]
 
-#ifdef DIAGNOSTIC
-	teq	r3, #0x00000000
-	beq	.Lfusupcbfault
-#endif
 	stmfd	sp!, {r4, r5}
+	GET_PCB(r3, r4)
 	adr	r4, .Lcasuwordfault
 	str	r4, [r3, #PCB_ONFAULT]
 #ifdef _ARM_ARCH_6
@@ -113,14 +107,8 @@
 
 ENTRY_NP(fuword32)
 ENTRY(fuword)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r1, .Lfusufault
 	str	r1, [r2, #PCB_ONFAULT]
 
@@ -139,14 +127,8 @@
  */
 
 ENTRY(fusword)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r1, .Lfusufault
 	str	r1, [r2, #PCB_ONFAULT]
 
@@ -175,14 +157,8 @@
 	mvnne	r0, #0x00000000
 	RETne
 
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r1, _C_LABEL(fusubailout)
 	str	r1, [r2, #PCB_ONFAULT]
 
@@ -215,14 +191,8 @@
  */
 
 ENTRY(fubyte)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r1, .Lfusufault
 	str	r1, [r2, #PCB_ONFAULT]
 
@@ -258,36 +228,15 @@
 	mvn	r0, #0x00000000
 	RET
 
-#ifdef DIAGNOSTIC
 /*
- * Handle earlier faults from [fs]u*(), due to no pcb
- */
-
-.Lfusupcbfault:
-	mov	r1, r0
-	adr	r0, fusupcbfaulttext
-	b	_C_LABEL(panic)
-
-fusupcbfaulttext:
-	.asciz	"Yikes - no valid PCB during fusuxxx() addr=%08x\n"
-	.align	0
-#endif
-
-/*
  * suword(caddr_t uaddr, int x);
  * Store an int in the user's address space.
  */
 
 ENTRY_NP(suword32)
 ENTRY(suword)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
@@ -312,14 +261,8 @@
 	mvnne	r0, #0x00000000
 	RETne
 
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r3, _C_LABEL(fusubailout)
 	str	r3, [r2, #PCB_ONFAULT]
 
@@ -343,14 +286,8 @@
  */
 
 ENTRY(susword)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
@@ -374,15 +311,8 @@
  */
 
 ENTRY(subyte)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
-
-#ifdef DIAGNOSTIC
-	teq	r2, #0x00000000
-	beq	.Lfusupcbfault
-#endif
-
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
Index: arm/arm/swtch.S
===================================================================
--- arm/arm/swtch.S	(revision 256815)
+++ arm/arm/swtch.S	(working copy)
@@ -192,7 +192,7 @@
 #endif
 
 	/* We have a new curthread now so make a note it */
-	GET_CURTHREAD_PTR(r6)
+	GET_PCPU_CURTHREAD_PTR(r6)
 	str	r5, [r6]
 
 	/* Set the new tp */
@@ -231,7 +231,7 @@
 
 	/* Process is now on a processor. */
 	/* We have a new curthread now so make a note it */
-	GET_CURTHREAD_PTR(r7)
+	GET_PCPU_CURTHREAD_PTR(r7)
 	str	r1, [r7]
 
 	/* Hook in a new pcb */
@@ -439,7 +439,11 @@
 	str	r6, [r4, #TD_LOCK]
 #if defined(SCHED_ULE) && defined(SMP)
 	ldr	r6, .Lblocked_lock
-	GET_CURTHREAD_PTR(r3)
+	/* 
+	 * It's fine to use GET_PCPU_CURTHREAD_PTR here, because interrupts
+	 * are disabled, so it will be atomic.
+	 */
+	GET_PCPU_CURTHREAD_PTR(r3)
 
 1:
 	ldr	r4, [r3, #TD_LOCK]
Index: arm/arm/bcopyinout.S
===================================================================
--- arm/arm/bcopyinout.S	(revision 256815)
+++ arm/arm/bcopyinout.S	(working copy)
@@ -39,6 +39,7 @@
 #include "assym.s"
 
 #include <machine/asm.h>
+#include <machine/asmacros.h>
 #include <sys/errno.h>
 
 .L_arm_memcpy:
@@ -55,15 +56,14 @@
 	.align	0
 
 #ifdef _ARM_ARCH_6
-#define GET_PCB(tmp) \
-	mrc p15, 0, tmp, c13, c0, 4; \
-	add	tmp, tmp, #(PC_CURPCB)
+KSTACK_LOCALS
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 
-#define GET_PCB(tmp) \
-	ldr	tmp, .Lcurpcb
+#define GET_PCB(tmp, tmp2) \
+	ldr	tmp, .Lcurpcb; \
+	ldr	tmp, [tmp]
 #endif
 
 
@@ -116,8 +116,7 @@
 
 .Lnormal:
 	SAVE_REGS
-	GET_PCB(r4)
-	ldr	r4, [r4]
+	GET_PCB(r4, r5)
 
 
 	ldr	r5, [r4, #PCB_ONFAULT]
@@ -354,8 +353,7 @@
 
 .Lnormale:
 	SAVE_REGS
-	GET_PCB(r4)
-	ldr	r4, [r4]
+	GET_PCB(r4, r5)
 
 	ldr	r5, [r4, #PCB_ONFAULT]
 	adr	r3, .Lcopyfault
@@ -549,8 +547,7 @@
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_1)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
@@ -575,8 +572,7 @@
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_2)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
@@ -601,8 +597,7 @@
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_4)
-	GET_PCB(r2)
-	ldr	r2, [r2]
+	GET_PCB(r2, r3)
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
Index: arm/arm/pmap-v6.c
===================================================================
--- arm/arm/pmap-v6.c	(revision 256815)
+++ arm/arm/pmap-v6.c	(working copy)
@@ -1976,7 +1976,7 @@
 	cpu_tlb_flushID();
 	cpu_cpwait();
 	if (vector_page < KERNBASE) {
-		struct pcb *curpcb = PCPU_GET(curpcb);
+		struct pcb *_curpcb = curpcb;
 		pcb = thread0.td_pcb;
 		if (pmap_is_current(pmap)) {
 			/*
@@ -1996,10 +1996,10 @@
 		 * Make sure cpu_switch(), et al, DTRT. This is safe to do
 		 * since this process has no remaining mappings of its own.
 		 */
-		curpcb->pcb_pl1vec = pcb->pcb_pl1vec;
-		curpcb->pcb_l1vec = pcb->pcb_l1vec;
-		curpcb->pcb_dacr = pcb->pcb_dacr;
-		curpcb->pcb_pagedir = pcb->pcb_pagedir;
+		_curpcb->pcb_pl1vec = pcb->pcb_pl1vec;
+		_curpcb->pcb_l1vec = pcb->pcb_l1vec;
+		_curpcb->pcb_dacr = pcb->pcb_dacr;
+		_curpcb->pcb_pagedir = pcb->pcb_pagedir;
 
 	}
 	pmap_free_l1(pmap);
Index: arm/arm/db_trace.c
===================================================================
--- arm/arm/db_trace.c	(revision 256815)
+++ arm/arm/db_trace.c	(working copy)
@@ -200,8 +200,10 @@
 	int update_vsp = 0;
 
 	/* This should never happen */
-	if (state->entries == 0)
+	if (state->entries == 0) {
+		printf("ptdr\n");
 		return 1;
+	}
 
 	/* Read the next instruction */
 	insn = db_unwind_exec_read_byte(state);
@@ -220,8 +222,10 @@
 		mask |= (insn & INSN_STD_DATA_MASK) << 8;
 
 		/* We have a refuse to unwind instruction */
-		if (mask == 0)
+		if (mask == 0) {
+			printf("OUIN\n");
 			return 1;
+		}
 
 		/* Update SP */
 		update_vsp = 1;
@@ -273,8 +277,10 @@
 		unsigned int mask, reg;
 
 		mask = db_unwind_exec_read_byte(state);
-		if (mask == 0 || (mask & 0xf0) != 0)
+		if (mask == 0 || (mask & 0xf0) != 0) {
+			printf("pwned\n");
 			return 1;
+		}
 
 		/* Update SP */
 		update_vsp = 1;
@@ -439,7 +445,8 @@
 			db_printf("Unable to unwind further\n");
 			finished = true;
 		} else if (state->registers[PC] < VM_MIN_KERNEL_ADDRESS) {
-			db_printf("Unable to unwind into user mode\n");
+			db_printf("Unable to unwind into user mode %x\n",
+			    state->registers[PC]);
 			finished = true;
 		} else if (state->update_mask == 0) {
 			db_printf("Unwind failure (no registers changed)\n");
Index: arm/arm/vm_machdep.c
===================================================================
--- arm/arm/vm_machdep.c	(revision 256815)
+++ arm/arm/vm_machdep.c	(working copy)
@@ -144,11 +144,12 @@
 #endif
 	td2->td_pcb = pcb2;
 	bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
+	pcb2->pcb_curthread = td2;
 	mdp2 = &p2->p_md;
 	bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
 	pcb2->un_32.pcb32_und_sp = td2->td_kstack + USPACE_UNDEF_STACK_TOP;
-	pcb2->un_32.pcb32_sp = td2->td_kstack +
-	    USPACE_SVC_STACK_TOP - sizeof(*pcb2);
+	pcb2->un_32.pcb32_sp = (td2->td_kstack +
+	    USPACE_SVC_STACK_TOP - sizeof(*pcb2)) &~ 7;
 	pmap_activate(td2);
 	td2->td_frame = tf = (struct trapframe *)STACKALIGN(
 	    pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
@@ -357,6 +358,7 @@
 
 	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
 	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
+	td->td_pcb->pcb_curthread = td;
 	tf = td->td_frame;
 	sf = (struct switchframe *)tf - 1;
 	sf->sf_r4 = (u_int)fork_return;
@@ -419,6 +421,7 @@
 {
 	td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_pages *
 	    PAGE_SIZE) - 1;
+	td->td_pcb->pcb_curthread = td;
 	/*
 	 * Ensure td_frame is aligned to an 8 byte boundary as it will be
 	 * placed into the stack pointer which must be 8 byte aligned in
Index: arm/arm/vfp.c
===================================================================
--- arm/arm/vfp.c	(revision 256815)
+++ arm/arm/vfp.c	(working copy)
@@ -182,7 +182,7 @@
 #ifdef SMP
 	curpcb->pcb_vfpcpu = PCPU_GET(cpu);
 #endif
-	PCPU_SET(vfpcthread, PCPU_GET(curthread));
+	PCPU_SET(vfpcthread, curthread);
 	return 0;
 }
 
@@ -217,7 +217,7 @@
 			"ldr	%0, [%1]\n"		/* set old vfpscr */
 			"mcr	p10, 7, %0, cr1, c0, 0\n"
 			: "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
-		PCPU_SET(vfpcthread, PCPU_GET(curthread));
+		PCPU_SET(vfpcthread, curthread);
 	}
 }
 
Index: arm/arm/pmap.c
===================================================================
--- arm/arm/pmap.c	(revision 256815)
+++ arm/arm/pmap.c	(working copy)
@@ -3497,6 +3497,8 @@
 				} else
 					m->md.pv_kva = va;
 			} else {
+				if (va >= kmi.clean_sva && va < kmi.clean_eva)
+					printf("roflou %x %x %X\n", va, kmi.clean_sva, kmi.clean_eva);
 				KASSERT(va < kmi.clean_sva ||
 				    va >= kmi.clean_eva,
 		("pmap_enter: managed mapping within the clean submap"));
Index: arm/arm/locore.S
===================================================================
--- arm/arm/locore.S	(revision 256815)
+++ arm/arm/locore.S	(working copy)
@@ -226,6 +226,9 @@
 	/* init arm will return the new stack pointer. */
 	mov	sp, r0
 
+#ifdef _ARM_ARCH_6
+	bl	_C_LABEL(mutex_init)
+#endif
 	bl	_C_LABEL(mi_startup)		/* call mi_startup()! */
 
 	adr	r0, .Lmainreturned
@@ -261,6 +264,7 @@
 	MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
 	/* map VA 0xc0000000..0xc3ffffff to PA */
 	MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	MMU_INIT(0x48000000, 0x48000000, 1, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW))
 #else
 	MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW))
 	/* map VA 0xc0000000..0xc3ffffff to PA */
Index: arm/arm/bcopyinout_xscale.S
===================================================================
--- arm/arm/bcopyinout_xscale.S	(revision 256815)
+++ arm/arm/bcopyinout_xscale.S	(working copy)
@@ -42,14 +42,13 @@
 	.align	0
 
 #ifdef _ARM_ARCH_6
-#define GET_PCB(tmp) \
-	mrc p15, 0, tmp, c13, c0, 4; \
-	add	tmp, tmp, #(PC_CURPCB)
+KSTACK_LOCALS
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
-#define GET_PCB(tmp) \
-	ldr	tmp, .Lcurpcb
+#define GET_PCB(tmp, tmp2) \
+	ldr	tmp, .Lcurpcb; \
+	ldr	tmp, [tmp]
 #endif
 
 /*
@@ -88,8 +87,7 @@
 .Lnormal:
 	stmfd	sp!, {r10-r11, lr}
 
-	GET_PCB(r10)
-	ldr	r10, [r10]
+	GET_PCB(r10, r11)
 
 	mov	r3, #0x00
 	adr	ip, .Lcopyin_fault
@@ -530,8 +528,7 @@
 .Lnormale:									
 	stmfd	sp!, {r10-r11, lr}
 
-	GET_PCB(r10)
-	ldr	r10, [r10]
+	GET_PCB(r10, r11)
 
 	mov	r3, #0x00
 	adr	ip, .Lcopyout_fault
Index: arm/xscale/std.xscale-be
===================================================================
--- arm/xscale/std.xscale-be	(revision 256815)
+++ arm/xscale/std.xscale-be	(working copy)
@@ -3,3 +3,4 @@
 
 include		"../xscale/std.xscale"
 machine 	arm	armeb
+makeoptions	CONF_CFLAGS="-mcpu=xscale -mbig-endian"
Index: arm/conf/AVILA
===================================================================
--- arm/conf/AVILA	(revision 256815)
+++ arm/conf/AVILA	(working copy)
@@ -51,16 +51,17 @@
 options 	FFS			#Berkeley Fast Filesystem
 options 	SOFTUPDATES		#Enable FFS soft updates support
 options 	NFSCL			#New Network Filesystem Client
-options 	NFS_ROOT		#NFS usable as /, requires NFSCL
-options 	BOOTP
-options 	BOOTP_NFSROOT
-options 	BOOTP_NFSV3
-options 	BOOTP_WIRED_TO=npe0
+#options 	NFS_ROOT		#NFS usable as /, requires NFSCL
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=npe0
 #options 	BOOTP_WIRED_TO=ath0
 #options 	BOOTP_WIRED_TO=rl0
 options 	BOOTP_COMPAT
 #options 	PREEMPTION
 #options 	VERBOSE_SYSINIT
+options		ROOTDEVNAME=\"ufs:/dev/ada0s1\"
 
 # Hardware performance counters
 options 	HWPMC_HOOKS
