diff -Nru a/Makefile b/Makefile
--- a/Makefile	Sun May  4 16:48:05 2003
+++ b/Makefile	Tue May  6 04:32:59 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 69
-EXTRAVERSION =
+EXTRAVERSION = -bk1
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -Nru a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c
--- a/arch/ppc64/kernel/LparData.c	Mon Nov 11 05:21:11 2002
+++ b/arch/ppc64/kernel/LparData.c	Tue Mar 25 20:30:58 2003
@@ -61,7 +61,7 @@
 	0xc8a5d9c4,	/* desc = "HvRD" ebcdic */
 	sizeof(struct HvReleaseData),
 	offsetof(struct naca_struct, xItVpdAreas),
-	(struct naca_struct *)(KERNELBASE+0x4000), /* 64-bit Naca address */
+	(struct naca_struct *)(NACA_VIRT_ADDR), /* 64-bit Naca address */
 	0x6000,		/* offset of LparMap within loadarea (see head.S) */
 	0,
 	1,		/* tags inactive       */
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Sun Mar  9 14:15:54 2003
+++ b/arch/ppc64/kernel/Makefile	Tue Mar 25 20:30:58 2003
@@ -15,7 +15,7 @@
 			     iSeries_IoMmTable.o iSeries_irq.o \
 			     iSeries_VpdInfo.o   XmPciLpEvent.o \
 			     HvCall.o HvLpConfig.o LparData.o mf_proc.o \
-			     proc_pmc.o iSeries_setup.o ItLpQueue.o hvCall.o \
+			     iSeries_setup.o ItLpQueue.o hvCall.o \
 			     mf.o HvLpEvent.o iSeries_proc.o 
 
 obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
@@ -25,6 +25,7 @@
 obj-y			  += open_pic.o xics.o pSeries_htab.o rtas.o \
 			     chrp_setup.o i8259.o ras.o prom.o 
 
+obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
diff -Nru a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
--- a/arch/ppc64/kernel/align.c	Thu Feb 20 19:55:52 2003
+++ b/arch/ppc64/kernel/align.c	Mon Mar 31 11:43:44 2003
@@ -237,7 +237,7 @@
 	dsisr = regs->dsisr;
 
 	/* Power4 doesn't set DSISR for an alignment interrupt */
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+	if (!cpu_alignexc_sets_dsisr()) {
 		unsigned int real_instr;
 		if (__get_user(real_instr, (unsigned int *)regs->nip))
 			return 0;
@@ -309,6 +309,7 @@
 				/* Doing stfs, have to convert to single */
 				enable_kernel_fp();
 				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+				disable_kernel_fp();
 			}
 			else
 				data.dd = current->thread.fpr[reg];
@@ -342,6 +343,7 @@
 				/* Doing lfs, have to convert to double */
 				enable_kernel_fp();
 				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+				disable_kernel_fp();
 			}
 			else
 				current->thread.fpr[reg] = data.dd;
diff -Nru a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
--- a/arch/ppc64/kernel/asm-offsets.c	Sat Oct 26 14:47:45 2002
+++ b/arch/ppc64/kernel/asm-offsets.c	Tue Mar 25 20:30:58 2003
@@ -59,14 +59,14 @@
 
 	/* naca */
         DEFINE(PACA, offsetof(struct naca_struct, paca));
-	DEFINE(DCACHEL1LINESIZE, offsetof(struct naca_struct, dCacheL1LineSize));
+	DEFINE(DCACHEL1LINESIZE, offsetof(struct systemcfg, dCacheL1LineSize));
         DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct naca_struct, dCacheL1LogLineSize));
         DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct naca_struct, dCacheL1LinesPerPage));
-        DEFINE(ICACHEL1LINESIZE, offsetof(struct naca_struct, iCacheL1LineSize));
+        DEFINE(ICACHEL1LINESIZE, offsetof(struct systemcfg, iCacheL1LineSize));
         DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize));
         DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage));
 	DEFINE(SLBSIZE, offsetof(struct naca_struct, slb_size));
-	DEFINE(PLATFORM, offsetof(struct naca_struct, platform));
+	DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
 
 	/* paca */
         DEFINE(PACA_SIZE, sizeof(struct paca_struct));
diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c	Thu Apr 24 03:30:41 2003
+++ b/arch/ppc64/kernel/chrp_setup.c	Fri Apr 25 13:27:32 2003
@@ -263,6 +263,8 @@
 	char *os;
 	static int display_character, set_indicator;
 	static int max_width;
+	static spinlock_t progress_lock = SPIN_LOCK_UNLOCKED;
+	static int pending_newline = 0;  /* did last write end with unprinted newline? */
 
 	if (!rtas.base)
 		return;
@@ -278,34 +280,79 @@
 		display_character = rtas_token("display-character");
 		set_indicator = rtas_token("set-indicator");
 	}
-	if (display_character == RTAS_UNKNOWN_SERVICE) {
-		/* use hex display */
-		if (set_indicator == RTAS_UNKNOWN_SERVICE)
-			return;
-		rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
+
+	if(display_character == RTAS_UNKNOWN_SERVICE) {
+		/* use hex display if available */
+		if(set_indicator != RTAS_UNKNOWN_SERVICE)
+			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
 		return;
 	}
 
-	rtas_call(display_character, 1, 1, NULL, '\r');
+	spin_lock(&progress_lock);
 
+	/* Last write ended with newline, but we didn't print it since
+	 * it would just clear the bottom line of output. Print it now
+	 * instead.
+	 *
+	 * If no newline is pending, print a CR to start output at the
+	 * beginning of the line.
+	 */
+	if(pending_newline) {
+		rtas_call(display_character, 1, 1, NULL, '\r');
+		rtas_call(display_character, 1, 1, NULL, '\n');
+		pending_newline = 0;
+	} else
+		rtas_call(display_character, 1, 1, NULL, '\r');
+ 
 	width = max_width;
 	os = s;
-	while ( *os )
-	{
-		if ( (*os == '\n') || (*os == '\r') )
+	while (*os) {
+		if(*os == '\n' || *os == '\r') {
+			/* Blank to end of line. */
+			while(width-- > 0)
+				rtas_call(display_character, 1, 1, NULL, ' ');
+ 
+			/* If newline is the last character, save it
+			 * until next call to avoid bumping up the
+			 * display output.
+			 */
+			if(*os == '\n' && !os[1]) {
+				pending_newline = 1;
+				spin_unlock(&progress_lock);
+				return;
+			}
+ 
+			/* RTAS wants CR-LF, not just LF */
+ 
+			if(*os == '\n') {
+				rtas_call(display_character, 1, 1, NULL, '\r');
+				rtas_call(display_character, 1, 1, NULL, '\n');
+			} else {
+				/* CR might be used to re-draw a line, so we'll
+				 * leave it alone and not add LF.
+				 */
+				rtas_call(display_character, 1, 1, NULL, *os);
+			}
+ 
 			width = max_width;
-		else
+		} else {
 			width--;
-		rtas_call(display_character, 1, 1, NULL, *os++ );
+			rtas_call(display_character, 1, 1, NULL, *os);
+		}
+ 
+		os++;
+ 
 		/* if we overwrite the screen length */
-		if ( width == 0 )
+		if ( width <= 0 )
 			while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
 				os++;
 	}
-
+ 
 	/* Blank to end of line. */
 	while ( width-- > 0 )
 		rtas_call(display_character, 1, 1, NULL, ' ' );
+
+	spin_unlock(&progress_lock);
 }
 
 extern void setup_default_decr(void);
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	Sat Feb 22 18:35:54 2003
+++ b/arch/ppc64/kernel/entry.S	Thu May  1 19:04:21 2003
@@ -225,10 +225,6 @@
 	bl	.sys32_rt_sigreturn
 	b	80f
 
-_GLOBAL(ppc64_sigreturn)
-	bl	.sys_sigreturn
-	b	80f
-
 _GLOBAL(ppc64_rt_sigreturn)
 	bl	.sys_rt_sigreturn
 
@@ -412,11 +408,6 @@
 	ld	r4,GPR4(r1)
 	ld	r1,GPR1(r1)
 
-	/*
-	 *  What if we took an exception and stole this segment, we may
-	 * fault on the above addresses and globber SRR0/1. Should check RI
-	 * bit and repeat - Anton
-	 */
 	rfid
 
 /* Note: this must change if we start using the  TIF_NOTIFY_RESUME bit */
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S	Sun Mar  2 14:39:15 2003
+++ b/arch/ppc64/kernel/head.S	Thu May  1 19:04:21 2003
@@ -29,6 +29,8 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
+#include <asm/naca.h>
+#include <asm/systemcfg.h>
 #include <asm/ppc_asm.h>
 #include <asm/offsets.h>
 #include <asm/bug.h>
@@ -49,8 +51,9 @@
  * 0x0100 - 0x2fff : pSeries Interrupt prologs
  * 0x3000 - 0x3fff : Interrupt support
  * 0x4000 - 0x4fff : NACA
- * 0x5000 - 0x5fff : Initial segment table
+ * 0x5000 - 0x5fff : SystemCfg
  * 0x6000          : iSeries and common interrupt prologs
+ * 0x9000 - 0x9fff : Initial segment table
  */
 
 /*
@@ -123,6 +126,10 @@
  * All of it must fit below the first exception vector at 0x100.
  */
 _GLOBAL(__secondary_hold)
+	mfmsr	r24
+	ori	r24,r24,MSR_RI
+	mtmsrd	r24			/* RI on */
+
 	/* Grab our linux cpu number */
 	mr      r24,r3
 
@@ -362,11 +369,11 @@
 	STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
 
 	/* Space for the naca.  Architected to be located at real address
-	 * 0x4000.  Various tools rely on this location being fixed.
+	 * NACA_PHYS_ADDR.  Various tools rely on this location being fixed.
 	 * The first dword of the naca is required by iSeries LPAR to
 	 * point to itVpdAreas.  On pSeries native, this value is not used.
 	 */
-	. = 0x4000
+	. = NACA_PHYS_ADDR
 	.globl __end_interrupts
 	.globl __start_naca
 __end_interrupts:
@@ -380,21 +387,14 @@
 	.llong 0x0
 	.llong paca
 
-	/*
-	 * Space for the initial segment table
-	 * For LPAR, the hypervisor must fill in at least one entry
-	 * before we get control (with relocate on)
-	 */
-	. = 0x5000
+	. = SYSTEMCFG_PHYS_ADDR
 	.globl __end_naca
-	.globl __start_stab
+	.globl __start_systemcfg
 __end_naca:
-__start_stab:
-
-
-	. = 0x6000
-	.globl __end_stab
-__end_stab:
+__start_systemcfg:
+	. = (SYSTEMCFG_PHYS_ADDR + PAGE_SIZE)
+	.globl __end_systemcfg
+__end_systemcfg:
 
 #ifdef CONFIG_PPC_ISERIES
 	/*
@@ -408,7 +408,7 @@
 
 	.llong	1		/* # ESIDs to be mapped by hypervisor         */
 	.llong	1		/* # memory ranges to be mapped by hypervisor */
-	.llong	5		/* Page # of segment table within load area   */
+	.llong	STAB0_PAGE	/* Page # of segment table within load area   */
 	.llong	0		/* Reserved */
 	.llong  0		/* Reserved */
 	.llong  0		/* Reserved */
@@ -529,6 +529,20 @@
 MachineCheck_FWNMI:
 	EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
 
+	/*
+	 * Space for the initial segment table
+	 * For LPAR, the hypervisor must fill in at least one entry
+	 * before we get control (with relocate on)
+	 */
+	. = STAB0_PHYS_ADDR
+	.globl __start_stab
+__start_stab:
+
+	. = (STAB0_PHYS_ADDR + PAGE_SIZE)
+	.globl __end_stab
+__end_stab:
+
+
 /*** Common interrupt handlers ***/
 
 	STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
@@ -782,11 +796,16 @@
 FPUnavailable_common:
 	EXCEPTION_PROLOG_COMMON
 	bne	.load_up_fpu		/* if from user, just load it up */
-	li	r20,0
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
 	li	r6,0x800
-	bl      .save_remaining_regs    /* if from kernel, take a trap */
-	bl      .KernelFP
-	b       .ret_from_except
+	bl      .save_remaining_regs
+	bl      .KernelFPUnavailableException
+	BUG_OPCODE
 
 	.globl SystemCall_common
 SystemCall_common:
@@ -1032,7 +1051,7 @@
 	slbmfee	r23,r22
 	rldicl  r23,r23,37,63
 	cmpwi   r23,0
-	beq     3f              /* Found an invalid entry              */
+	beq     4f              /* Found an invalid entry              */
 
 	addi	r22,r22,1
 	cmpldi	r22,64
@@ -1041,18 +1060,37 @@
 	/* No free entry - just take the next entry, round-robin */
 	/* XXX we should get the number of SLB entries from the naca */
 SLB_NUM_ENTRIES = 64
-	mfspr	r21,SPRG3
+2:	mfspr	r21,SPRG3
 	ld	r22,PACASTABRR(r21)
 	addi	r23,r22,1
 	cmpdi	r23,SLB_NUM_ENTRIES
-	blt	2f
+	blt	3f
 	li	r23,1
-2:	std	r23,PACASTABRR(r21)
+3:	std	r23,PACASTABRR(r21)
 
 	/* r20 = vsid, r22 = entry */
-3:
+
+	/* 
+	 * Never cast out the segment for our kernel stack. Since we
+	 * dont invalidate the ERAT we could have a valid translation
+	 * for the kernel stack during the first part of exception exit 
+	 * which gets invalidated due to a tlbie from another cpu at a
+	 * non recoverable point (after setting srr0/1) - Anton
+	 */
+	slbmfee	r23,r22
+	srdi	r23,r23,28
+	/*
+	 * This is incorrect (r1 is not the kernel stack) if we entered
+	 * from userspace but there is no critical window from userspace
+	 * so this should be OK. Also if we cast out the userspace stack
+	 * segment while in userspace we will fault it straight back in.
+	 */
+	srdi	r21,r1,28
+	cmpd	r21,r23
+	beq-	2b
+
 	/* Put together the vsid portion of the entry. */
-	li      r21,0
+4:	li      r21,0
 	rldimi  r21,r20,12,0
 	ori     r20,r21,1024
 	ori	r20,r20,128    /* set class bit for kernel region */
@@ -1060,17 +1098,6 @@
 	ori	r20,r20,256    /* map kernel region with large ptes */
 #endif
 
-	/*
-	 * XXX we should handle this in the exception exit path in 2.5,
-	 * we need to make this path quick - Anton
-	 */
-	/* Invalidate the old entry */
-	slbmfee	r21,r22
-	lis	r23,-2049
-	ori	r23,r23,65535
-	and	r21,r21,r23
-	slbie	r21
-
 	/* Put together the esid portion of the entry. */
 	mfspr	r21,DAR        /* Get the new esid                     */
 	rldicl  r21,r21,36,28  /* Permits a full 36b of ESID           */
@@ -1252,9 +1279,12 @@
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
 
+	LOADADDR(r9,systemcfg)
+	SET_REG_TO_CONST(r4, SYSTEMCFG_VIRT_ADDR)
+	std	r4,0(r9)		/* set the systemcfg pointer */
+
 	LOADADDR(r9,naca)
-	SET_REG_TO_CONST(r4, KERNELBASE)
-	addi	r4,r4,0x4000
+	SET_REG_TO_CONST(r4, NACA_VIRT_ADDR)
 	std	r4,0(r9)		/* set the naca pointer */
 
 	/* Get the pointer to the segment table */
@@ -1285,13 +1315,18 @@
 	/* Relocate the TOC from a virt addr to a real addr */
 	sub	r2,r2,r3
 
+	/* setup the systemcfg pointer which is needed by prom_init       */
+	LOADADDR(r9,systemcfg)
+	sub	r9,r9,r3                /* addr of the variable systemcfg */
+	SET_REG_TO_CONST(r4, SYSTEMCFG_VIRT_ADDR)
+	sub	r4,r4,r3
+	std	r4,0(r9)		/* set the value of systemcfg     */
+
 	/* setup the naca pointer which is needed by prom_init            */
 	LOADADDR(r9,naca)
 	sub	r9,r9,r3                /* addr of the variable naca      */
-
-	SET_REG_TO_CONST(r4, KERNELBASE)
+	SET_REG_TO_CONST(r4, NACA_VIRT_ADDR)
 	sub	r4,r4,r3
-	addi	r4,r4,0x4000
 	std	r4,0(r9)		/* set the value of naca          */
 
 	/* DRENG / PPPBBB Fix the following comment!!! -Peter */
@@ -1410,11 +1445,13 @@
 copy_to_here:
 
 /*
+ * load_up_fpu(unused, unused, tsk)
  * Disable FP for the task which had the FPU previously,
  * and save its floating-point registers in its thread_struct.
  * Enables the FPU for use in the kernel on return.
  * On SMP we know the fpu is free, since we give it up every
- * switch.  -- Cort
+ * switch (ie, no lazy save of the FP registers).
+ * On entry: r13 == 'current' && last_task_used_math != 'current'
  */
 _STATIC(load_up_fpu)
 	mfmsr	r5                      /* grab the current MSR */
@@ -1432,27 +1469,30 @@
 	ld	r4,last_task_used_math@l(r3)
 	cmpi	0,r4,0
 	beq	1f
-	addi	r4,r4,THREAD	       /* want THREAD of last_task_used_math */
+	/* Save FP state to last_task_used_math's THREAD struct */
+	addi	r4,r4,THREAD
 	SAVE_32FPRS(0, r4)
 	mffs	fr0
 	stfd	fr0,THREAD_FPSCR(r4)
+	/* Disable FP for last_task_used_math */
 	ld	r5,PT_REGS(r4)
 	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 	li	r20,MSR_FP|MSR_FE0|MSR_FE1
-	andc	r4,r4,r20		/* disable FP for previous task */
+	andc	r4,r4,r20
 	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 #endif /* CONFIG_SMP */
 	/* enable use of FP after return */
 	ld	r4,PACACURRENT(r13)
 	addi	r5,r4,THREAD		/* Get THREAD */
-	lwz	r4,THREAD_FPEXC_MODE(r5)
+	ld	r4,THREAD_FPEXC_MODE(r5)
 	ori	r23,r23,MSR_FP
 	or	r23,r23,r4
 	lfd	fr0,THREAD_FPSCR(r5)
 	mtfsf	0xff,fr0
 	REST_32FPRS(0, r5)
 #ifndef CONFIG_SMP
+	/* Update last_task_used_math to 'current' */
 	subi	r4,r5,THREAD		/* Back to 'current' */
 	std	r4,last_task_used_math@l(r3)
 #endif /* CONFIG_SMP */
@@ -1460,19 +1500,16 @@
 	b	fast_exception_return
 
 /*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
+ * disable_kernel_fp()
+ * Disable the FPU.
  */
-_GLOBAL(KernelFP)
-	ld	r3,_MSR(r1)
-	ori	r3,r3,MSR_FP
-	std	r3,_MSR(r1)		/* enable use of FP after return */
-	LOADADDR(r3,86f)
-	ld	r4,PACACURRENT(r13)	/* current */
-	ld	r5,_NIP(r1)
-	b	.ret_from_except
-86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
-	.align	4
+_GLOBAL(disable_kernel_fp)
+	mfmsr   r3
+	rldicl  r0,r3,(63-MSR_FP_LG),1
+	rldicl  r3,r0,(MSR_FP_LG+1),0
+	mtmsrd  r3			/* disable use of fpu now */
+	isync
+	blr
 
 /*
  * giveup_fpu(tsk)
@@ -1562,8 +1599,8 @@
 	sc				/* HvCall_setASR */
 #else
 	/* set the ASR */
-	addi	r3,0,0x4000     /* r3 = ptr to naca */
-	lhz   	r3,PLATFORM(r3) /* r3 = platform flags */
+	li	r3,SYSTEMCFG_PHYS_ADDR	/* r3 = ptr to systemcfg  */
+	lwz   	r3,PLATFORM(r3)		/* r3 = platform flags */
 	cmpldi 	r3,PLATFORM_PSERIES_LPAR
 	bne   	98f
 	mfspr	r3,PVR
@@ -1642,10 +1679,20 @@
 	bl	.reloc_offset
 	mr	r26,r3
 
+	mfmsr	r6
+	ori	r6,r6,MSR_RI
+	mtmsrd	r6			/* RI on */
+
+	/* setup the systemcfg pointer which is needed by *tab_initialize  */
+	LOADADDR(r6,systemcfg)
+	sub	r6,r6,r26                /* addr of the variable systemcfg */
+	li	r27,SYSTEMCFG_PHYS_ADDR
+	std	r27,0(r6)	 	 /* set the value of systemcfg     */
+
 	/* setup the naca pointer which is needed by *tab_initialize       */
 	LOADADDR(r6,naca)
 	sub	r6,r6,r26                /* addr of the variable naca      */
-	li	r27,0x4000
+	li	r27,NACA_PHYS_ADDR
 	std	r27,0(r6)	 	 /* set the value of naca          */
 
 #ifdef CONFIG_HMT
@@ -1709,15 +1756,12 @@
 	sub	r13,r13,r26		/* convert to physical addr         */
 
 	mtspr	SPRG3,r13		/* PPPBBB: Temp... -Peter */
-	li	r3,0x5000
-	std	r3,PACASTABREAL(r13)
-	LOADADDR(r24, __start_stab)
-	std	r24,PACASTABVIRT(r13)
+	ld	r3,PACASTABREAL(r13)
 	ori	r4,r3,1			/* turn on valid bit                */
 	
 	/* set the ASR */
-	addi	r3,0,0x4000     /* r3 = ptr to naca */
-	lhz   	r3,PLATFORM(r3) /* r3 = platform flags */
+	li	r3,SYSTEMCFG_PHYS_ADDR	/* r3 = ptr to systemcfg */
+	lwz   	r3,PLATFORM(r3)		/* r3 = platform flags */
 	cmpldi 	r3,PLATFORM_PSERIES_LPAR
 	bne   	98f
 	mfspr	r3,PVR
@@ -1741,8 +1785,8 @@
 	bl	.stab_initialize
 	bl	.htab_initialize
 
-	addi  r3,0,0x4000     /* r3 = ptr to naca */
-	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	li	r3,SYSTEMCFG_PHYS_ADDR	/* r3 = ptr to systemcfg */
+	lwz	r3,PLATFORM(r3)		/* r3 = platform flags */
 	cmpldi r3,PLATFORM_PSERIES
 	bne    98f
 	LOADADDR(r6,_SDR1)		/* Only if NOT LPAR */
@@ -1791,11 +1835,14 @@
 	addi    r2,r2,0x4000
 	addi    r2,r2,0x4000
 
-	/* setup the naca pointer                                         */
-	LOADADDR(r9,naca)
+	/* setup the systemcfg pointer */
+	LOADADDR(r9,systemcfg)
+	SET_REG_TO_CONST(r8, SYSTEMCFG_VIRT_ADDR)
+	std	r8,0(r9)
 
-	SET_REG_TO_CONST(r8, KERNELBASE)
-	addi	r8,r8,0x4000
+	/* setup the naca pointer */
+	LOADADDR(r9,naca)
+	SET_REG_TO_CONST(r8, NACA_VIRT_ADDR)
 	std	r8,0(r9)		/* set the value of the naca ptr  */
 
 	LOADADDR(r26, boot_cpuid)
@@ -1946,7 +1993,7 @@
 hardware_int_paca0:
 	.space	8*4096
 
-/* 1 page segment table per cpu (max 48) */
+/* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
 	.globl	stab_array
 stab_array:
         .space	4096 * 48
diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
--- a/arch/ppc64/kernel/htab.c	Wed Mar 12 15:19:15 2003
+++ b/arch/ppc64/kernel/htab.c	Tue Mar 25 20:30:58 2003
@@ -101,7 +101,7 @@
 
 		hpteg = ((hash & htab_data.htab_hash_mask)*HPTES_PER_GROUP);
 
-		if (naca->platform == PLATFORM_PSERIES_LPAR)
+		if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
 			ret = pSeries_lpar_hpte_insert(hpteg, va,
 				(unsigned long)__v2a(addr) >> PAGE_SHIFT,
 				0, mode, 1, large);
@@ -140,7 +140,7 @@
 	htab_data.htab_num_ptegs = pteg_count;
 	htab_data.htab_hash_mask = pteg_count - 1;
 
-	if (naca->platform == PLATFORM_PSERIES) {
+	if (systemcfg->platform == PLATFORM_PSERIES) {
 		/* Find storage for the HPT.  Must be contiguous in
 		 * the absolute address space.
 		 */
@@ -165,15 +165,15 @@
 	mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
 
 	/* XXX we currently map kernel text rw, should fix this */
-	if (cpu_has_largepage() && naca->physicalMemorySize > 256*MB) {
+	if (cpu_has_largepage() && systemcfg->physicalMemorySize > 256*MB) {
 		create_pte_mapping((unsigned long)KERNELBASE, 
 				   KERNELBASE + 256*MB, mode_rw, 0);
 		create_pte_mapping((unsigned long)KERNELBASE + 256*MB, 
-				   KERNELBASE + (naca->physicalMemorySize), 
+				   KERNELBASE + (systemcfg->physicalMemorySize), 
 				   mode_rw, 1);
 	} else {
 		create_pte_mapping((unsigned long)KERNELBASE, 
-				   KERNELBASE+(naca->physicalMemorySize), 
+				   KERNELBASE+(systemcfg->physicalMemorySize), 
 				   mode_rw, 0);
 	}
 }
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c	Sun Apr 20 09:14:41 2003
+++ b/arch/ppc64/kernel/iSeries_setup.c	Wed Apr 23 23:53:25 2003
@@ -561,13 +561,13 @@
 	 * which should be equal to 
 	 *   nextPhysChunk
 	 */
-	naca->physicalMemorySize = chunk_to_addr(nextPhysChunk);
+	systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
 
 	/* Bolt kernel mappings for all of memory */
-	iSeries_bolt_kernel( 0, naca->physicalMemorySize );
+	iSeries_bolt_kernel( 0, systemcfg->physicalMemorySize );
 
 	lmb_init();
-	lmb_add( 0, naca->physicalMemorySize );
+	lmb_add( 0, systemcfg->physicalMemorySize );
 	lmb_analyze();	/* ?? */
 	lmb_reserve( 0, __pa(klimit));
 
@@ -584,29 +584,28 @@
 
 static void __init setup_iSeries_cache_sizes(void)
 {
-	unsigned i,n;
-	unsigned procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+	unsigned int i, n;
+	unsigned int procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+
+	systemcfg->iCacheL1Size = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
+	systemcfg->iCacheL1LineSize = xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
+	systemcfg->dCacheL1Size = xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
+	systemcfg->dCacheL1LineSize = xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
+	naca->iCacheL1LinesPerPage = PAGE_SIZE / systemcfg->iCacheL1LineSize;
+	naca->dCacheL1LinesPerPage = PAGE_SIZE / systemcfg->dCacheL1LineSize;
 
-	naca->iCacheL1LineSize = xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
-	naca->dCacheL1LineSize = xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
-	naca->iCacheL1LinesPerPage = PAGE_SIZE / naca->iCacheL1LineSize;
-	naca->dCacheL1LinesPerPage = PAGE_SIZE / naca->dCacheL1LineSize;
-	i = naca->iCacheL1LineSize;
+	i = systemcfg->iCacheL1LineSize;
 	n = 0;
 	while ((i=(i/2))) ++n;
 	naca->iCacheL1LogLineSize = n;
-	i = naca->dCacheL1LineSize;
+
+	i = systemcfg->dCacheL1LineSize;
 	n = 0;
 	while ((i=(i/2))) ++n;
 	naca->dCacheL1LogLineSize = n;
 
-	printk( "D-cache line size = %d  (log = %d)\n",
-			(unsigned)naca->dCacheL1LineSize,
-			(unsigned)naca->dCacheL1LogLineSize );
-	printk( "I-cache line size = %d  (log = %d)\n",
-			(unsigned)naca->iCacheL1LineSize,
-			(unsigned)naca->iCacheL1LogLineSize );
-	
+	printk( "D-cache line size = %d\n", (unsigned int)systemcfg->dCacheL1LineSize);
+	printk( "I-cache line size = %d\n", (unsigned int)systemcfg->iCacheL1LineSize);
 }
 
 /*
@@ -648,6 +647,11 @@
 	void *	eventStack;
 	unsigned procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
 
+	/* Add an eye catcher and the systemcfg layout version number */
+	strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+	systemcfg->version.major = SYSTEMCFG_MAJOR;
+	systemcfg->version.minor = SYSTEMCFG_MINOR;
+
 	/* Setup the Lp Event Queue */
 
 	/* Allocate a page for the Event Stack
@@ -696,8 +700,8 @@
 	printk("Time base frequency = %lu.%02lu\n",
 			tbFreqMhz,
 			tbFreqMhzHundreths );
-	printk("Processor version = %x\n",
-			xIoHriProcessorVpd[procIx].xPVR );
+	systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
+	printk("Processor version = %x\n", systemcfg->processor);
 
 }
 
@@ -726,9 +730,9 @@
 	seq_printf(m,"time base\t: %lu.%02luMHz\n",
 		tbFreqMhz, tbFreqMhzHundreths );
 	seq_printf(m,"i-cache\t\t: %d\n",
-		naca->iCacheL1LineSize);
+		systemcfg->iCacheL1LineSize);
 	seq_printf(m,"d-cache\t\t: %d\n",
-		naca->dCacheL1LineSize);
+		systemcfg->dCacheL1LineSize);
 
 }
 
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Wed Apr 30 08:47:36 2003
+++ b/arch/ppc64/kernel/ioctl32.c	Thu May  1 19:47:06 2003
@@ -23,6 +23,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/compat.h>
+#include <linux/ioctl32.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -50,6 +51,7 @@
 #include <linux/cdrom.h>
 #include <linux/loop.h>
 #include <linux/auto_fs.h>
+#include <linux/auto_fs4.h>
 #include <linux/devfs_fs.h>
 #include <linux/tty.h>
 #include <linux/vt_kern.h>
@@ -577,6 +579,17 @@
 		len += sizeof(struct ethtool_regs);
 		break;
 	}
+	case ETHTOOL_GEEPROM: 
+	case ETHTOOL_SEEPROM: { 
+		struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); 
+		/* darned variable size arguments */ 
+		if (get_user(len, (u32 *)&promaddr->len)) { 
+			err = -EFAULT; 
+			goto out; 
+		} 
+		len += sizeof(struct ethtool_eeprom); 
+		break; 
+	} 
 	case ETHTOOL_GSET:
 	case ETHTOOL_SSET:	len = sizeof(struct ethtool_cmd); break;
 	default:
@@ -659,6 +672,47 @@
 	return err;
 }
 
+static inline void *alloc_user_space(long len)
+{
+	struct pt_regs *regs = current->thread.regs;
+	unsigned long usp = regs->gpr[1];
+
+	/*
+	 * We cant access below the stack pointer in the 32bit ABI and
+	 * can access 288 bytes in the 64bit ABI
+	 */
+	if (!(test_thread_flag(TIF_32BIT)))
+		usp -= 288;
+
+	return (void *) (usp - len);
+}
+
+int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq *u_ifreq64;
+	struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg;
+	char tmp_buf[IFNAMSIZ];
+	void __user *data64;
+	u32 data32;
+
+	if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
+			   IFNAMSIZ))
+		return -EFAULT;
+	if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
+		return -EFAULT;
+	data64 = A(data32);
+
+	u_ifreq64 = alloc_user_space(sizeof(*u_ifreq64));
+
+	/* Don't check these user accesses, just let that get trapped
+	 * in the ioctl handler instead.
+	 */
+	copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
+	__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
+
+	return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
+}
+
 static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	struct ifreq ifr;
@@ -3643,670 +3697,32 @@
 #define BNEPGETCONNLIST	_IOR('B', 210, int)
 #define BNEPGETCONNINFO	_IOR('B', 211, int)
 
-struct ioctl_trans {
-	unsigned long cmd;
-	unsigned long handler;
-	unsigned long next;
-};
-
-#define COMPATIBLE_IOCTL(cmd) { cmd, (unsigned long)sys_ioctl, 0 },
+#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
+#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
 
-#define HANDLE_IOCTL(cmd,handler) { cmd, (unsigned long)handler, 0 },
+#define IOCTL_TABLE_START \
+	struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END \
+	}; struct ioctl_trans ioctl_end[0];
 
 #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
 #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
 
-static struct ioctl_trans ioctl_translations[] = {
-    /* List here explicitly which ioctl's need translation,
-     * all others default to calling sys_ioctl().
-     */
-/* Big T */
-COMPATIBLE_IOCTL(TCGETA)
-COMPATIBLE_IOCTL(TCSETA)
-COMPATIBLE_IOCTL(TCSETAW)
-COMPATIBLE_IOCTL(TCSETAF)
-COMPATIBLE_IOCTL(TCSBRK)
+IOCTL_TABLE_START
+#include <linux/compat_ioctl.h>
 COMPATIBLE_IOCTL(TCSBRKP)
-COMPATIBLE_IOCTL(TCXONC)
-COMPATIBLE_IOCTL(TCFLSH)
-COMPATIBLE_IOCTL(TCGETS)
-COMPATIBLE_IOCTL(TCSETS)
-COMPATIBLE_IOCTL(TCSETSW)
-COMPATIBLE_IOCTL(TCSETSF)
-COMPATIBLE_IOCTL(TIOCLINUX)
 COMPATIBLE_IOCTL(TIOCSTART)
 COMPATIBLE_IOCTL(TIOCSTOP)
-/* Little t */
-COMPATIBLE_IOCTL(TIOCGETD)
-COMPATIBLE_IOCTL(TIOCSETD)
-COMPATIBLE_IOCTL(TIOCEXCL)
-COMPATIBLE_IOCTL(TIOCNXCL)
-COMPATIBLE_IOCTL(TIOCCONS)
-COMPATIBLE_IOCTL(TIOCGSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSWINSZ)
-COMPATIBLE_IOCTL(TIOCGWINSZ)
-COMPATIBLE_IOCTL(TIOCMGET)
-COMPATIBLE_IOCTL(TIOCMBIC)
-COMPATIBLE_IOCTL(TIOCMBIS)
-COMPATIBLE_IOCTL(TIOCMSET)
-COMPATIBLE_IOCTL(TIOCPKT)
-COMPATIBLE_IOCTL(TIOCNOTTY)
-COMPATIBLE_IOCTL(TIOCSTI)
-COMPATIBLE_IOCTL(TIOCOUTQ)
-COMPATIBLE_IOCTL(TIOCSPGRP)
-COMPATIBLE_IOCTL(TIOCGPGRP)
-COMPATIBLE_IOCTL(TIOCSCTTY)
-COMPATIBLE_IOCTL(TIOCGPTN)
-COMPATIBLE_IOCTL(TIOCSPTLCK)
 COMPATIBLE_IOCTL(TIOCGSERIAL)
 COMPATIBLE_IOCTL(TIOCSSERIAL)
-COMPATIBLE_IOCTL(TIOCSERGETLSR)
 COMPATIBLE_IOCTL(TIOCSLTC)
-/* Big F */
-COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
-COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
-COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
 #if 0
 COMPATIBLE_IOCTL(FBIOBLANK)
 #endif
-/* Little f */
-COMPATIBLE_IOCTL(FIOCLEX)
-COMPATIBLE_IOCTL(FIONCLEX)
-COMPATIBLE_IOCTL(FIOASYNC)
-COMPATIBLE_IOCTL(FIONBIO)
-COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
-/* 0x00 */
-COMPATIBLE_IOCTL(FIBMAP)
-COMPATIBLE_IOCTL(FIGETBSZ)
-/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
- *         Some need translations, these do not.
- */
-COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
-COMPATIBLE_IOCTL(HDIO_SET_DMA)
-COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
-COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
-COMPATIBLE_IOCTL(HDIO_SET_32BIT)
-COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
-COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
-COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
-COMPATIBLE_IOCTL(HDIO_SET_NICE)
-/* 0x02 -- Floppy ioctls */
-COMPATIBLE_IOCTL(FDMSGON)
-COMPATIBLE_IOCTL(FDMSGOFF)
-COMPATIBLE_IOCTL(FDSETEMSGTRESH)
-COMPATIBLE_IOCTL(FDFLUSH)
-COMPATIBLE_IOCTL(FDWERRORCLR)
-COMPATIBLE_IOCTL(FDSETMAXERRS)
-COMPATIBLE_IOCTL(FDGETMAXERRS)
-COMPATIBLE_IOCTL(FDGETDRVTYP)
-COMPATIBLE_IOCTL(FDEJECT)
-COMPATIBLE_IOCTL(FDCLRPRM)
-COMPATIBLE_IOCTL(FDFMTBEG)
-COMPATIBLE_IOCTL(FDFMTEND)
-COMPATIBLE_IOCTL(FDRESET)
-COMPATIBLE_IOCTL(FDTWADDLE)
-COMPATIBLE_IOCTL(FDFMTTRK)
-COMPATIBLE_IOCTL(FDRAWCMD)
-/* 0x12 */
-COMPATIBLE_IOCTL(BLKROSET)
-COMPATIBLE_IOCTL(BLKROGET)
-COMPATIBLE_IOCTL(BLKRRPART)
-COMPATIBLE_IOCTL(BLKFLSBUF)
-COMPATIBLE_IOCTL(BLKSECTSET)
-COMPATIBLE_IOCTL(BLKSSZGET)
-COMPATIBLE_IOCTL(BLKRASET)
-COMPATIBLE_IOCTL(BLKFRASET)
-/* RAID */
-COMPATIBLE_IOCTL(RAID_VERSION)
-COMPATIBLE_IOCTL(GET_ARRAY_INFO)
-COMPATIBLE_IOCTL(GET_DISK_INFO)
-COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
-COMPATIBLE_IOCTL(CLEAR_ARRAY)
-COMPATIBLE_IOCTL(ADD_NEW_DISK)
-COMPATIBLE_IOCTL(HOT_REMOVE_DISK)
-COMPATIBLE_IOCTL(SET_ARRAY_INFO)
-COMPATIBLE_IOCTL(SET_DISK_INFO)
-COMPATIBLE_IOCTL(WRITE_RAID_INFO)
-COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
-COMPATIBLE_IOCTL(PROTECT_ARRAY)
-COMPATIBLE_IOCTL(HOT_ADD_DISK)
-COMPATIBLE_IOCTL(SET_DISK_FAULTY)
-COMPATIBLE_IOCTL(RUN_ARRAY)
-COMPATIBLE_IOCTL(START_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY_RO)
-COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
-/* Big K */
-COMPATIBLE_IOCTL(PIO_FONT)
-COMPATIBLE_IOCTL(GIO_FONT)
-COMPATIBLE_IOCTL(KDSIGACCEPT)
-COMPATIBLE_IOCTL(KDGETKEYCODE)
-COMPATIBLE_IOCTL(KDSETKEYCODE)
-COMPATIBLE_IOCTL(KIOCSOUND)
-COMPATIBLE_IOCTL(KDMKTONE)
-COMPATIBLE_IOCTL(KDGKBTYPE)
-COMPATIBLE_IOCTL(KDSETMODE)
-COMPATIBLE_IOCTL(KDGETMODE)
-COMPATIBLE_IOCTL(KDSKBMODE)
-COMPATIBLE_IOCTL(KDGKBMODE)
-COMPATIBLE_IOCTL(KDSKBMETA)
-COMPATIBLE_IOCTL(KDGKBMETA)
-COMPATIBLE_IOCTL(KDGKBENT)
-COMPATIBLE_IOCTL(KDSKBENT)
-COMPATIBLE_IOCTL(KDGKBSENT)
-COMPATIBLE_IOCTL(KDSKBSENT)
-COMPATIBLE_IOCTL(KDGKBDIACR)
-COMPATIBLE_IOCTL(KDKBDREP)
-COMPATIBLE_IOCTL(KDSKBDIACR)
-COMPATIBLE_IOCTL(KDGKBLED)
-COMPATIBLE_IOCTL(KDSKBLED)
-COMPATIBLE_IOCTL(KDGETLED)
-COMPATIBLE_IOCTL(KDSETLED)
-COMPATIBLE_IOCTL(GIO_SCRNMAP)
-COMPATIBLE_IOCTL(PIO_SCRNMAP)
-COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_FONTRESET)
-COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
-/* Big S */
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
-COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
-COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
-/* Big T */
-COMPATIBLE_IOCTL(TUNSETNOCSUM)
-COMPATIBLE_IOCTL(TUNSETDEBUG)
-COMPATIBLE_IOCTL(TUNSETIFF)
-COMPATIBLE_IOCTL(TUNSETPERSIST)
-COMPATIBLE_IOCTL(TUNSETOWNER)
-/* Big V */
-COMPATIBLE_IOCTL(VT_SETMODE)
-COMPATIBLE_IOCTL(VT_GETMODE)
-COMPATIBLE_IOCTL(VT_GETSTATE)
-COMPATIBLE_IOCTL(VT_OPENQRY)
-COMPATIBLE_IOCTL(VT_ACTIVATE)
-COMPATIBLE_IOCTL(VT_WAITACTIVE)
-COMPATIBLE_IOCTL(VT_RELDISP)
-COMPATIBLE_IOCTL(VT_DISALLOCATE)
-COMPATIBLE_IOCTL(VT_RESIZE)
-COMPATIBLE_IOCTL(VT_RESIZEX)
-COMPATIBLE_IOCTL(VT_LOCKSWITCH)
-COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-/* Little v, the video4linux ioctls */
-COMPATIBLE_IOCTL(VIDIOCGCAP)
-COMPATIBLE_IOCTL(VIDIOCGCHAN)
-COMPATIBLE_IOCTL(VIDIOCSCHAN)
-COMPATIBLE_IOCTL(VIDIOCGPICT)
-COMPATIBLE_IOCTL(VIDIOCSPICT)
-COMPATIBLE_IOCTL(VIDIOCCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCKEY)
-COMPATIBLE_IOCTL(VIDIOCGAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSYNC)
-COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCGMBUF)
-COMPATIBLE_IOCTL(VIDIOCGUNIT)
-COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
-/* BTTV specific... */
-COMPATIBLE_IOCTL(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]))
-COMPATIBLE_IOCTL(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
-COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
 COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
 COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)
-COMPATIBLE_IOCTL(RTC_ALM_READ)
-COMPATIBLE_IOCTL(RTC_RD_TIME)
-COMPATIBLE_IOCTL(RTC_SET_TIME)
-COMPATIBLE_IOCTL(RTC_WKALM_SET)
-COMPATIBLE_IOCTL(RTC_WKALM_RD)
-/* Little m */
-COMPATIBLE_IOCTL(MTIOCTOP)
-/* Socket level stuff */
-COMPATIBLE_IOCTL(FIOSETOWN)
-COMPATIBLE_IOCTL(SIOCSPGRP)
-COMPATIBLE_IOCTL(FIOGETOWN)
-COMPATIBLE_IOCTL(SIOCGPGRP)
-COMPATIBLE_IOCTL(SIOCATMARK)
-COMPATIBLE_IOCTL(SIOCSIFLINK)
-COMPATIBLE_IOCTL(SIOCSIFENCAP)
-COMPATIBLE_IOCTL(SIOCGIFENCAP)
-COMPATIBLE_IOCTL(SIOCSIFBR)
-COMPATIBLE_IOCTL(SIOCGIFBR)
-COMPATIBLE_IOCTL(SIOCSARP)
-COMPATIBLE_IOCTL(SIOCGARP)
-COMPATIBLE_IOCTL(SIOCDARP)
-COMPATIBLE_IOCTL(SIOCSRARP)
-COMPATIBLE_IOCTL(SIOCGRARP)
-COMPATIBLE_IOCTL(SIOCDRARP)
-COMPATIBLE_IOCTL(SIOCADDDLCI)
-COMPATIBLE_IOCTL(SIOCDELDLCI)
-COMPATIBLE_IOCTL(SIOCGMIIPHY)
-COMPATIBLE_IOCTL(SIOCGMIIREG)
-COMPATIBLE_IOCTL(SIOCSMIIREG)
-COMPATIBLE_IOCTL(SIOCGIFVLAN)
-COMPATIBLE_IOCTL(SIOCSIFVLAN)
-/* SG stuff */
-COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_EMULATED_HOST)
-COMPATIBLE_IOCTL(SG_SET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
-COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
-COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
-COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
-COMPATIBLE_IOCTL(SG_SET_DEBUG)
-COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
-COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
-COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
-COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
-COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
-COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
-/* PPP stuff */
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(LPGETSTATUS)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
-/* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
-/* CDROM stuff */
-COMPATIBLE_IOCTL(CDROMPAUSE)
-COMPATIBLE_IOCTL(CDROMRESUME)
-COMPATIBLE_IOCTL(CDROMPLAYMSF)
-COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
-COMPATIBLE_IOCTL(CDROMREADTOCHDR)
-COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
-COMPATIBLE_IOCTL(CDROMSTOP)
-COMPATIBLE_IOCTL(CDROMSTART)
-COMPATIBLE_IOCTL(CDROMEJECT)
-COMPATIBLE_IOCTL(CDROMVOLCTRL)
-COMPATIBLE_IOCTL(CDROMSUBCHNL)
-COMPATIBLE_IOCTL(CDROMEJECT_SW)
-COMPATIBLE_IOCTL(CDROMMULTISESSION)
-COMPATIBLE_IOCTL(CDROM_GET_MCN)
-COMPATIBLE_IOCTL(CDROMRESET)
-COMPATIBLE_IOCTL(CDROMVOLREAD)
-COMPATIBLE_IOCTL(CDROMSEEK)
-COMPATIBLE_IOCTL(CDROMPLAYBLK)
-COMPATIBLE_IOCTL(CDROMCLOSETRAY)
-COMPATIBLE_IOCTL(CDROM_SET_OPTIONS)
-COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS)
-COMPATIBLE_IOCTL(CDROM_SELECT_SPEED)
-COMPATIBLE_IOCTL(CDROM_SELECT_DISC)
-COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED)
-COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS)
-COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
-COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
-COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
-COMPATIBLE_IOCTL(CDROM_DEBUG)
-COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
-/* DVD ioctls */
-COMPATIBLE_IOCTL(DVD_READ_STRUCT)
-COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
-COMPATIBLE_IOCTL(DVD_AUTH)
-/* Big L */
-COMPATIBLE_IOCTL(LOOP_SET_FD)
-COMPATIBLE_IOCTL(LOOP_CLR_FD)
-/* Big Q for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
-COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
-COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
-/* Big T for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_START)
-COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
-COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
-/* Little m for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
-/* Big P for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
-COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
-/* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
-/* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
-COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
-/* Big C for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
-COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
-COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
-COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
-/* Big M for sound/OSS */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
-/* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
-/* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
-/* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
-/* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
-COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
-COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
-COMPATIBLE_IOCTL(OSS_GETVERSION)
-/* AUTOFS */
-COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
-COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
-COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
-/* DEVFS */
-COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
-COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
-/* Raw devices */
-COMPATIBLE_IOCTL(RAW_SETBIND)
-COMPATIBLE_IOCTL(RAW_GETBIND)
-/* SMB ioctls which do not need any translations */
-COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* NCP ioctls which do not need any translations */
-COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
-COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
-COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
-/* Little a */
-COMPATIBLE_IOCTL(ATMSIGD_CTRL)
-COMPATIBLE_IOCTL(ATMARPD_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_MCAST)
-COMPATIBLE_IOCTL(ATMLEC_DATA)
-COMPATIBLE_IOCTL(ATM_SETSC)
-COMPATIBLE_IOCTL(SIOCSIFATMTCP)
-COMPATIBLE_IOCTL(SIOCMKCLIP)
-COMPATIBLE_IOCTL(ATMARP_MKIP)
-COMPATIBLE_IOCTL(ATMARP_SETENTRY)
-COMPATIBLE_IOCTL(ATMARP_ENCAP)
-COMPATIBLE_IOCTL(ATMTCP_CREATE)
-COMPATIBLE_IOCTL(ATMTCP_REMOVE)
-COMPATIBLE_IOCTL(ATMMPC_CTRL)
-COMPATIBLE_IOCTL(ATMMPC_DATA)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
-COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
-#endif /* DRM */
-/* Big W */
-/* WIOC_GETSUPPORT not yet implemented -E */
-COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETTEMP)
-COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
-COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
-/* Big R */
-COMPATIBLE_IOCTL(RNDGETENTCNT)
-COMPATIBLE_IOCTL(RNDADDTOENTCNT)
-COMPATIBLE_IOCTL(RNDGETPOOL)
-COMPATIBLE_IOCTL(RNDADDENTROPY)
-COMPATIBLE_IOCTL(RNDZAPENTCNT)
-COMPATIBLE_IOCTL(RNDCLEARPOOL)
-/* Bluetooth ioctls */
-COMPATIBLE_IOCTL(HCIDEVUP)
-COMPATIBLE_IOCTL(HCIDEVDOWN)
-COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIDEVRESTAT)
-COMPATIBLE_IOCTL(HCIGETDEVLIST)
-COMPATIBLE_IOCTL(HCIGETDEVINFO)
-COMPATIBLE_IOCTL(HCIGETCONNLIST)
-COMPATIBLE_IOCTL(HCIGETCONNINFO)
-COMPATIBLE_IOCTL(HCISETRAW)
-COMPATIBLE_IOCTL(HCISETSCAN)
-COMPATIBLE_IOCTL(HCISETAUTH)
-COMPATIBLE_IOCTL(HCISETENCRYPT)
-COMPATIBLE_IOCTL(HCISETPTYPE)
-COMPATIBLE_IOCTL(HCISETLINKPOL)
-COMPATIBLE_IOCTL(HCISETLINKMODE)
-COMPATIBLE_IOCTL(HCISETACLMTU)
-COMPATIBLE_IOCTL(HCISETSCOMTU)
-COMPATIBLE_IOCTL(HCIINQUIRY)
-COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-COMPATIBLE_IOCTL(BNEPCONNADD)
-COMPATIBLE_IOCTL(BNEPCONNDEL)
-COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
-COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* USB */
-COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
-COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
-COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
-COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
-COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_RESET)
-COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
-/* MTD */
-COMPATIBLE_IOCTL(MEMGETINFO)
-COMPATIBLE_IOCTL(MEMERASE)
-COMPATIBLE_IOCTL(MEMLOCK)
-COMPATIBLE_IOCTL(MEMUNLOCK)
-COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
-COMPATIBLE_IOCTL(MEMGETREGIONINFO)
-/* NBD */
-COMPATIBLE_IOCTL(NBD_SET_SOCK)
-COMPATIBLE_IOCTL(NBD_SET_BLKSIZE)
-COMPATIBLE_IOCTL(NBD_SET_SIZE)
-COMPATIBLE_IOCTL(NBD_DO_IT)
-COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
-COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
-COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
-COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
-COMPATIBLE_IOCTL(NBD_DISCONNECT)
-/* device-mapper */
-COMPATIBLE_IOCTL(DM_VERSION)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL)
-COMPATIBLE_IOCTL(DM_DEV_CREATE)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE)
-COMPATIBLE_IOCTL(DM_DEV_RELOAD)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
-COMPATIBLE_IOCTL(DM_DEV_RENAME)
-COMPATIBLE_IOCTL(DM_DEV_DEPS)
-COMPATIBLE_IOCTL(DM_DEV_STATUS)
-COMPATIBLE_IOCTL(DM_TARGET_STATUS)
-COMPATIBLE_IOCTL(DM_TARGET_WAIT)
+
 /* And these ioctls need translation */
 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
@@ -4473,4 +3889,4 @@
 HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
 HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
 HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
-};
+IOCTL_TABLE_END
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c	Thu Mar 20 13:44:14 2003
+++ b/arch/ppc64/kernel/irq.c	Wed Apr 23 22:45:15 2003
@@ -212,7 +212,8 @@
 	return -ENOENT;
 }
 
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+int request_irq(unsigned int irq,
+	irqreturn_t (*handler)(int, void *, struct pt_regs *),
 	unsigned long irqflags, const char * devname, void *dev_id)
 {
 	struct irqaction *action;
@@ -695,7 +696,7 @@
 	struct proc_dir_entry *entry;
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+	if (!root_irq_dir || (irq_desc[irq].handler == NULL) || irq_dir[irq])
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
@@ -743,6 +744,7 @@
 	}
 }
 
-void no_action(int irq, void *dev, struct pt_regs *regs)
+irqreturn_t no_action(int irq, void *dev, struct pt_regs *regs)
 {
+	return IRQ_NONE;
 }
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Wed Apr 30 08:47:36 2003
+++ b/arch/ppc64/kernel/misc.S	Wed Apr 30 16:00:31 2003
@@ -170,12 +170,14 @@
  */
 	LOADADDR(r10,naca)		/* Get Naca address */
 	ld	r10,0(r10)
-	lhz	r7,DCACHEL1LINESIZE(r10)	/* Get cache line size */
+	LOADADDR(r11,systemcfg)		/* Get systemcfg address */
+	ld	r11,0(r11)
+	lwz	r7,DCACHEL1LINESIZE(r11)/* Get cache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lhz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
+	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -186,12 +188,12 @@
 
 /* Now invalidate the instruction cache */
 	
-	lhz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
+	lwz	r7,ICACHEL1LINESIZE(r11)	/* Get Icache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5
-	lhz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
+	lwz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -217,12 +219,14 @@
  */
 	LOADADDR(r10,naca)		/* Get Naca address */
 	ld	r10,0(r10)
-	lhz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
+	LOADADDR(r11,systemcfg)		/* Get systemcfg address */
+	ld	r11,0(r11)
+	lwz	r7,DCACHEL1LINESIZE(r11)	/* Get dcache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lhz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
+	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -249,9 +253,11 @@
 /* Flush the dcache */
 	LOADADDR(r7,naca)
 	ld	r7,0(r7)
+	LOADADDR(r8,systemcfg)			/* Get systemcfg address */
+	ld	r8,0(r8)
 	clrrdi	r3,r3,12           	    /* Page align */
-	lhz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
-	lhz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
+	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
+	lwz	r5,DCACHEL1LINESIZE(r8)		/* Get dcache line size */
 	mr	r6,r3
 	mtctr	r4
 0:	dcbst	0,r6
@@ -261,8 +267,8 @@
 
 /* Now invalidate the icache */	
 
-	lhz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
-	lhz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
+	lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
+	lwz	r5,ICACHEL1LINESIZE(r8)		/* Get icache line size */
 	mtctr	r4
 1:	icbi	0,r3
 	add	r3,r3,r5
@@ -574,7 +580,7 @@
 	.llong .sys32_ssetmask
 	.llong .sys_setreuid	        /* 70 */
 	.llong .sys_setregid
-	.llong .sys_sigsuspend
+	.llong .sys32_sigsuspend
 	.llong .compat_sys_sigpending
 	.llong .sys32_sethostname
 	.llong .compat_sys_setrlimit	        /* 75 */
@@ -737,7 +743,7 @@
 	.llong .sys_set_tid_address
 	.llong .ppc32_fadvise64
 	.llong .sys_exit_group
-	.llong .ppc32_lookup_dcookie	/* 245 */
+	.llong .ppc32_lookup_dcookie	/* 235 */
 	.llong .sys_epoll_create
 	.llong .sys_epoll_ctl
 	.llong .sys_epoll_wait
@@ -812,13 +818,13 @@
 	.llong .sys_getppid
 	.llong .sys_getpgrp		/* 65 */
 	.llong .sys_setsid
-	.llong .sys_sigaction
+	.llong .sys_ni_syscall
 	.llong .sys_sgetmask
 	.llong .sys_ssetmask
 	.llong .sys_setreuid		/* 70 */
 	.llong .sys_setregid
-	.llong .sys_sigsuspend
-	.llong .sys_sigpending
+	.llong .sys_ni_syscall
+	.llong .sys_ni_syscall
 	.llong .sys_sethostname
 	.llong .sys_setrlimit		/* 75 */
 	.llong .sys_ni_syscall		/* old getrlimit syscall */
@@ -864,14 +870,14 @@
 	.llong .sys_sysinfo
 	.llong .sys_ipc
 	.llong .sys_fsync
-	.llong .ppc64_sigreturn
+	.llong .sys_ni_syscall
 	.llong .sys_clone		/* 120 */
 	.llong .sys_setdomainname
 	.llong .ppc64_newuname
 	.llong .sys_ni_syscall		/* old modify_ldt syscall */
 	.llong .sys_adjtimex
 	.llong .sys_mprotect		/* 125 */
-	.llong .sys_sigprocmask
+	.llong .sys_ni_syscall
 	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys_init_module
 	.llong .sys_delete_module
diff -Nru a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
--- a/arch/ppc64/kernel/module.c	Mon Feb  3 23:20:10 2003
+++ b/arch/ppc64/kernel/module.c	Thu Apr 24 09:29:49 2003
@@ -20,6 +20,8 @@
 #include <linux/moduleloader.h>
 #include <linux/err.h>
 #include <linux/vmalloc.h>
+#include <asm/module.h>
+#include <asm/uaccess.h>
 
 /* FIXME: We don't do .init separately.  To do this, we'd need to have
    a separate r2 value in the init and core section, and stub between
@@ -374,15 +376,11 @@
 	return 0;
 }
 
-/* In arch/ppc64/mm/extable.c */
-extern void sort_ex_table(struct exception_table_entry *start,
-			  struct exception_table_entry *finish);
-
 int module_finalize(const Elf_Ehdr *hdr,
-		    const Elf_Shdr *sechdrs,
-		    struct module *me)
+		const Elf_Shdr *sechdrs, struct module *me)
 {
-	sort_ex_table(me->extable.entry,
-		      me->extable.entry + me->extable.num_entries);
+	sort_ex_table((struct exception_table_entry *)me->extable,
+		      (struct exception_table_entry *)me->extable +
+				me->num_exentries);
 	return 0;
 }
diff -Nru a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c
--- a/arch/ppc64/kernel/open_pic.c	Sun Feb 16 18:27:44 2003
+++ b/arch/ppc64/kernel/open_pic.c	Wed Apr 23 22:45:15 2003
@@ -111,7 +111,6 @@
  * data has probably been corrupted and we're going to panic or deadlock later
  * anyway --Troy
  */
-extern unsigned long* _get_SP(void);
 #define check_arg_irq(irq) \
     if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \
       printk(KERN_ERR "open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
@@ -765,9 +764,11 @@
 	openpic_eoi();
 }
 
-static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
+static irqreturn_t openpic_ipi_action(int cpl, void *dev_id,
+					struct pt_regs *regs)
 {
 	smp_message_recv(cpl-openpic_vec_ipi, regs);
+	return IRQ_HANDLED;
 }
 
 #endif /* CONFIG_SMP */
diff -Nru a/arch/ppc64/kernel/open_pic_defs.h b/arch/ppc64/kernel/open_pic_defs.h
--- a/arch/ppc64/kernel/open_pic_defs.h	Thu Feb 14 04:14:36 2002
+++ b/arch/ppc64/kernel/open_pic_defs.h	Wed Apr 23 22:45:15 2003
@@ -298,7 +298,8 @@
 #ifdef CONFIG_SMP
 /* Interprocessor Interrupts */
 static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
-static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+static irqreturn_t openpic_ipi_action(int cpl, void *dev_id,
+					struct pt_regs *regs);
 #endif
 
 /* Timer Interrupts */
diff -Nru a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
--- a/arch/ppc64/kernel/pSeries_lpar.c	Mon Mar 24 16:01:56 2003
+++ b/arch/ppc64/kernel/pSeries_lpar.c	Thu Mar 27 22:31:06 2003
@@ -110,29 +110,6 @@
 			   lbuf[0], lbuf[1], &dummy, &dummy, &dummy);
 }
 
-long plpar_eoi(unsigned long xirr)
-{
-	return plpar_hcall_norets(H_EOI, xirr);
-}
-
-long plpar_cppr(unsigned long cppr)
-{
-	return plpar_hcall_norets(H_CPPR, cppr);
-}
-
-long plpar_ipi(unsigned long servernum,
-	       unsigned long mfrr)
-{
-	return plpar_hcall_norets(H_IPI, servernum, mfrr);
-}
-
-long plpar_xirr(unsigned long *xirr_ret)
-{
-	unsigned long dummy;
-	return plpar_hcall(H_XIRR, 0, 0, 0, 0,
-			   xirr_ret, &dummy, &dummy);
-}
-
 static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum, 
 				unsigned long uaddr, int direction )
 {
@@ -179,66 +156,6 @@
 	}
 
 }
-
-/* PowerPC Interrupts for lpar. */
-/* NOTE: this typedef is duplicated (for now) from xics.c! */
-typedef struct {
-	int (*xirr_info_get)(int cpu);
-	void (*xirr_info_set)(int cpu, int val);
-	void (*cppr_info)(int cpu, u8 val);
-	void (*qirr_info)(int cpu, u8 val);
-} xics_ops;
-static int pSeriesLP_xirr_info_get(int n_cpu)
-{
-	unsigned long lpar_rc;
-	unsigned long return_value; 
-
-	lpar_rc = plpar_xirr(&return_value);
-	if (lpar_rc != H_Success) {
-		panic(" bad return code xirr - rc = %lx \n", lpar_rc); 
-	}
-	return ((int)(return_value));
-}
-
-static void pSeriesLP_xirr_info_set(int n_cpu, int value)
-{
-	unsigned long lpar_rc;
-	unsigned long val64 = value & 0xffffffff;
-
-	lpar_rc = plpar_eoi(val64);
-	if (lpar_rc != H_Success) {
-		panic(" bad return code EOI - rc = %ld, value=%lx \n", lpar_rc, val64); 
-	}
-}
-
-static void pSeriesLP_cppr_info(int n_cpu, u8 value)
-{
-	unsigned long lpar_rc;
-
-	lpar_rc = plpar_cppr(value);
-	if (lpar_rc != H_Success) {
-		panic(" bad return code cppr - rc = %lx \n", lpar_rc); 
-	}
-}
-
-static void pSeriesLP_qirr_info(int n_cpu , u8 value)
-{
-	unsigned long lpar_rc;
-
-	lpar_rc = plpar_ipi(n_cpu, value);
-	if (lpar_rc != H_Success) {
-		panic(" bad return code qirr -ipi  - rc = %lx \n", lpar_rc); 
-	}
-}
-
-xics_ops pSeriesLP_ops = {
-	pSeriesLP_xirr_info_get,
-	pSeriesLP_xirr_info_set,
-	pSeriesLP_cppr_info,
-	pSeriesLP_qirr_info
-};
-/* end TAI-LPAR */
-
 
 int vtermno;	/* virtual terminal# for udbg  */
 
diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
--- a/arch/ppc64/kernel/pacaData.c	Tue Jul 23 01:36:48 2002
+++ b/arch/ppc64/kernel/pacaData.c	Tue Mar 25 20:30:58 2003
@@ -20,6 +20,7 @@
 #include <asm/paca.h>
 
 struct naca_struct *naca;
+struct systemcfg *systemcfg;
 
 /* The Paca is an array with one entry per processor.  Each contains an 
  * ItLpPaca, which contains the information shared between the 
@@ -65,9 +66,9 @@
 
 struct paca_struct paca[MAX_PACAS] __page_aligned = {
 #ifdef CONFIG_PPC_ISERIES
-	PACAINITDATA( 0, 1, &xItLpQueue, 0, 0xc000000000005000),
+	PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR),
 #else
-	PACAINITDATA( 0, 1, 0, 0x5000, 0xc000000000005000),
+	PACAINITDATA( 0, 1, 0, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR),
 #endif
 	PACAINITDATA( 1, 0, 0, 0, 0),
 	PACAINITDATA( 2, 0, 0, 0, 0),
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c	Mon Mar 24 19:22:52 2003
+++ b/arch/ppc64/kernel/pci.c	Wed Apr 23 23:07:46 2003
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/bootmem.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 
 #include <asm/processor.h>
diff -Nru a/arch/ppc64/kernel/pci_dma.c b/arch/ppc64/kernel/pci_dma.c
--- a/arch/ppc64/kernel/pci_dma.c	Wed Mar 12 15:19:15 2003
+++ b/arch/ppc64/kernel/pci_dma.c	Wed Apr 23 23:53:25 2003
@@ -134,7 +134,7 @@
 		dev = ppc64_isabridge_dev;
 	if (!dev)
 		return NULL;
-	if (naca->platform == PLATFORM_ISERIES_LPAR) {
+	if (systemcfg->platform == PLATFORM_ISERIES_LPAR) {
  		return ISERIES_DEVNODE(dev)->DevTceTable;
 	} else {
 		return PCI_GET_DN(dev)->tce_table;
@@ -723,8 +723,8 @@
 			 */
 			busdn->bussubno = bus->number;
 			create_pci_bus_tce_table((unsigned long)busdn);
-		} else
-			create_tce_tables_for_busesLP(&bus->children);
+		}
+		create_tce_tables_for_busesLP(&bus->children);
 	}
 }
 
@@ -732,7 +732,7 @@
 	struct pci_dev *dev;
 	struct device_node *dn, *mydn;
 
-	if (naca->platform == PLATFORM_PSERIES_LPAR) {
+	if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
 		create_tce_tables_for_busesLP(&pci_root_buses);
 	}
 	else {
@@ -773,7 +773,7 @@
  	/* - Tce Table Share between buses,                              */
  	/* - Tce Table per logical slot.                                 */
 	/*****************************************************************/
-	if(naca->platform == PLATFORM_ISERIES_LPAR) {
+	if(systemcfg->platform == PLATFORM_ISERIES_LPAR) {
 
 		struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)token;
 		getTceTableParmsiSeries(DevNode,newTceTable);
@@ -797,7 +797,7 @@
 
 		dn = (struct device_node *)token;
 		phb = dn->phb;
-		if (naca->platform == PLATFORM_PSERIES)
+		if (systemcfg->platform == PLATFORM_PSERIES)
 			getTceTableParmsPSeries(phb, dn, newTceTable);
 		else
 			getTceTableParmsPSeriesLP(phb, dn, newTceTable);
@@ -1135,7 +1135,8 @@
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
- 		printk("PCI_DMA: pci_unmap_single 0x%lx size to large: 0x%lx \n",dma_handle,size);
+ 		printk("PCI_DMA: pci_unmap_single 0x%lx size too"
+			" large: 0x%lx \n", (long)dma_handle, (long)size);
  		return;
  	}
 	
diff -Nru a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/kernel/proc_ppc64.c	Tue Mar 25 20:30:59 2003
@@ -0,0 +1,177 @@
+/*
+ * arch/ppc64/kernel/proc_ppc64.c
+ *
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+/*
+ * Change Activity:
+ * 2001       : mikec    : Created
+ * 2001/06/05 : engebret : Software event count support.
+ * 2003/02/13 : bergner  : Move PMC code to pmc.c
+ * End Change Activity 
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+
+#include <asm/proc_fs.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/systemcfg.h>
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+
+struct proc_ppc64_t proc_ppc64;
+
+void proc_ppc64_create_paca(int num);
+
+static loff_t  page_map_seek( struct file *file, loff_t off, int whence);
+static ssize_t page_map_read( struct file *file, char *buf, size_t nbytes, loff_t *ppos);
+static int     page_map_mmap( struct file *file, struct vm_area_struct *vma );
+
+static struct file_operations page_map_fops = {
+	llseek:	page_map_seek,
+	read:	page_map_read,
+	mmap:	page_map_mmap
+};
+
+
+static int __init proc_ppc64_init(void)
+{
+
+	printk(KERN_INFO "proc_ppc64: Creating /proc/ppc64/\n");
+
+	proc_ppc64.root = proc_mkdir("ppc64", 0);
+	if (!proc_ppc64.root)
+		return 0;
+
+	proc_ppc64.naca = create_proc_entry("naca", S_IRUSR, proc_ppc64.root);
+	if ( proc_ppc64.naca ) {
+		proc_ppc64.naca->nlink = 1;
+		proc_ppc64.naca->data = naca;
+		proc_ppc64.naca->size = 4096;
+		proc_ppc64.naca->proc_fops = &page_map_fops;
+	}
+	
+	proc_ppc64.systemcfg = create_proc_entry("systemcfg", S_IFREG|S_IRUGO, proc_ppc64.root);
+	if ( proc_ppc64.systemcfg ) {
+		proc_ppc64.systemcfg->nlink = 1;
+		proc_ppc64.systemcfg->data = systemcfg;
+		proc_ppc64.systemcfg->size = 4096;
+		proc_ppc64.systemcfg->proc_fops = &page_map_fops;
+	}
+
+	/* /proc/ppc64/paca/XX -- raw paca contents.  Only readable to root */
+	proc_ppc64.paca = proc_mkdir("paca", proc_ppc64.root);
+	if (proc_ppc64.paca) {
+		unsigned long i;
+
+		for (i = 0; i < NR_CPUS; i++) {
+			if (!cpu_online(i))
+				continue;
+			proc_ppc64_create_paca(i);
+		}
+	}
+
+	/* Placeholder for rtas interfaces. */
+	proc_ppc64.rtas = proc_mkdir("rtas", proc_ppc64.root);
+
+	return 0;
+}
+
+
+/*
+ * NOTE: since paca data is always in flux the values will never be a consistant set.
+ * In theory it could be made consistent if we made the corresponding cpu
+ * copy the page for us (via an IPI).  Probably not worth it.
+ *
+ */
+void proc_ppc64_create_paca(int num)
+{
+	struct proc_dir_entry *ent;
+	struct paca_struct *lpaca = paca + num;
+	char buf[16];
+
+	sprintf(buf, "%02x", num);
+	ent = create_proc_entry(buf, S_IRUSR, proc_ppc64.paca);
+	if ( ent ) {
+		ent->nlink = 1;
+		ent->data = lpaca;
+		ent->size = 4096;
+		ent->proc_fops = &page_map_fops;
+	}
+}
+
+
+static loff_t page_map_seek( struct file *file, loff_t off, int whence)
+{
+	loff_t new;
+	struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+
+	switch(whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	case 2:
+		new = dp->size + off;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if ( new < 0 || new > dp->size )
+		return -EINVAL;
+	return (file->f_pos = new);
+}
+
+static ssize_t page_map_read( struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	unsigned pos = *ppos;
+	struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+
+	if ( pos >= dp->size )
+		return 0;
+	if ( nbytes >= dp->size )
+		nbytes = dp->size;
+	if ( pos + nbytes > dp->size )
+		nbytes = dp->size - pos;
+
+	copy_to_user( buf, (char *)dp->data + pos, nbytes );
+	*ppos = pos + nbytes;
+	return nbytes;
+}
+
+static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
+{
+	struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+
+	vma->vm_flags |= VM_SHM | VM_LOCKED;
+
+	if ((vma->vm_end - vma->vm_start) > dp->size)
+		return -EINVAL;
+
+	remap_page_range( vma, vma->vm_start, __pa(dp->data), dp->size, vma->vm_page_prot );
+	return 0;
+}
+
+fs_initcall(proc_ppc64_init);
+
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	Thu Mar 20 08:53:38 2003
+++ b/arch/ppc64/kernel/process.c	Thu Mar 27 22:09:13 2003
@@ -533,8 +533,6 @@
 	} while (count++ < 32);
 }
 
-extern unsigned long *_get_SP(void);
-
 void dump_stack(void)
 {
 	show_tsk_stack(current, (unsigned long)_get_SP());
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	Mon Mar 24 17:04:39 2003
+++ b/arch/ppc64/kernel/prom.c	Thu Apr 24 00:39:23 2003
@@ -118,7 +118,6 @@
 #define FB_MAX	8
 #endif
 
-static int ppc64_is_smp;
 
 struct prom_t prom = {
 	0,			/* entry */
@@ -301,7 +300,9 @@
         unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
         struct naca_struct *_naca = RELOC(naca);
+        struct systemcfg *_systemcfg = RELOC(systemcfg);
 
+	/* NOTE: _naca->debug_switch is already initialized. */
 #ifdef DEBUG_PROM
 	prom_print(RELOC("prom_initialize_naca: start...\n"));
 #endif
@@ -320,25 +321,35 @@
 			 * d-cache and i-cache sizes... -Peter
 			 */
 			if ( num_cpus == 1 ) {
-				u32 size;
+				u32 size, lsize;
 
 				call_prom(RELOC("getprop"), 4, 1, node,
-					  RELOC("d-cache-line-size"),
+					  RELOC("d-cache-size"),
 					  &size, sizeof(size));
 
-				_naca->dCacheL1LineSize     = size;
-				_naca->dCacheL1LogLineSize  = __ilog2(size);
-				_naca->dCacheL1LinesPerPage = PAGE_SIZE / size;
+				call_prom(RELOC("getprop"), 4, 1, node,
+					  RELOC("d-cache-line-size"),
+					  &lsize, sizeof(lsize));
+
+				_systemcfg->dCacheL1Size = size;
+				_systemcfg->dCacheL1LineSize = lsize;
+				_naca->dCacheL1LogLineSize = __ilog2(lsize);
+				_naca->dCacheL1LinesPerPage = PAGE_SIZE/lsize;
 
 				call_prom(RELOC("getprop"), 4, 1, node,
-					  RELOC("i-cache-line-size"),
+					  RELOC("i-cache-size"),
 					  &size, sizeof(size));
 
-				_naca->iCacheL1LineSize     = size;
-				_naca->iCacheL1LogLineSize  = __ilog2(size);
-				_naca->iCacheL1LinesPerPage = PAGE_SIZE / size;
+				call_prom(RELOC("getprop"), 4, 1, node,
+					  RELOC("i-cache-line-size"),
+					  &lsize, sizeof(lsize));
 
-				if (_naca->platform == PLATFORM_PSERIES_LPAR) {
+				_systemcfg->iCacheL1Size = size;
+				_systemcfg->iCacheL1LineSize = lsize;
+				_naca->iCacheL1LogLineSize = __ilog2(lsize);
+				_naca->iCacheL1LinesPerPage = PAGE_SIZE/lsize;
+
+				if (_systemcfg->platform == PLATFORM_PSERIES_LPAR) {
 					u32 pft_size[2];
 					call_prom(RELOC("getprop"), 4, 1, node, 
 						  RELOC("ibm,pft-size"),
@@ -408,20 +419,17 @@
 	}
 
 	/* We gotta have at least 1 cpu... */
-        if (num_cpus < 1)
+        if ( (_systemcfg->processorCount = num_cpus) < 1 )
                 PROM_BUG();
 
-	if (num_cpus > 1)
-		RELOC(ppc64_is_smp) = 1;
-
-	_naca->physicalMemorySize = lmb_phys_mem_size();
+	_systemcfg->physicalMemorySize = lmb_phys_mem_size();
 
-	if (_naca->platform == PLATFORM_PSERIES) {
+	if (_systemcfg->platform == PLATFORM_PSERIES) {
 		unsigned long rnd_mem_size, pteg_count;
 
 		/* round mem_size up to next power of 2 */
-		rnd_mem_size = 1UL << __ilog2(_naca->physicalMemorySize);
-		if (rnd_mem_size < _naca->physicalMemorySize)
+		rnd_mem_size = 1UL << __ilog2(_systemcfg->physicalMemorySize);
+		if (rnd_mem_size < _systemcfg->physicalMemorySize)
 			rnd_mem_size <<= 1;
 
 		/* # pages / 2 */
@@ -442,49 +450,43 @@
 	 */
 	_naca->slb_size = 64;
 
-#ifdef DEBUG_PROM
-        prom_print(RELOC("naca->physicalMemorySize   = 0x"));
-        prom_print_hex(_naca->physicalMemorySize);
-        prom_print_nl();
-
-        prom_print(RELOC("naca->pftSize              = 0x"));
-        prom_print_hex(_naca->pftSize);
-        prom_print_nl();
-
-        prom_print(RELOC("naca->dCacheL1LineSize     = 0x"));
-        prom_print_hex(_naca->dCacheL1LineSize);
-        prom_print_nl();
+	/* Add an eye catcher and the systemcfg layout version number */
+	strcpy(_systemcfg->eye_catcher, RELOC("SYSTEMCFG:PPC64"));
+	_systemcfg->version.major = SYSTEMCFG_MAJOR;
+	_systemcfg->version.minor = SYSTEMCFG_MINOR;
+	_systemcfg->processor = _get_PVR();
 
-        prom_print(RELOC("naca->dCacheL1LogLineSize  = 0x"));
-        prom_print_hex(_naca->dCacheL1LogLineSize);
+#ifdef DEBUG_PROM
+        prom_print(RELOC("systemcfg->processorCount       = 0x"));
+        prom_print_hex(_systemcfg->processorCount);
         prom_print_nl();
 
-        prom_print(RELOC("naca->dCacheL1LinesPerPage = 0x"));
-        prom_print_hex(_naca->dCacheL1LinesPerPage);
+        prom_print(RELOC("systemcfg->physicalMemorySize   = 0x"));
+        prom_print_hex(_systemcfg->physicalMemorySize);
         prom_print_nl();
 
-        prom_print(RELOC("naca->iCacheL1LineSize     = 0x"));
-        prom_print_hex(_naca->iCacheL1LineSize);
+        prom_print(RELOC("naca->pftSize                   = 0x"));
+        prom_print_hex(_naca->pftSize);
         prom_print_nl();
 
-        prom_print(RELOC("naca->iCacheL1LogLineSize  = 0x"));
-        prom_print_hex(_naca->iCacheL1LogLineSize);
+        prom_print(RELOC("systemcfg->dCacheL1LineSize     = 0x"));
+        prom_print_hex(_systemcfg->dCacheL1LineSize);
         prom_print_nl();
 
-        prom_print(RELOC("naca->iCacheL1LinesPerPage = 0x"));
-        prom_print_hex(_naca->iCacheL1LinesPerPage);
+        prom_print(RELOC("systemcfg->iCacheL1LineSize     = 0x"));
+        prom_print_hex(_systemcfg->iCacheL1LineSize);
         prom_print_nl();
 
-        prom_print(RELOC("naca->serialPortAddr       = 0x"));
+        prom_print(RELOC("naca->serialPortAddr            = 0x"));
         prom_print_hex(_naca->serialPortAddr);
         prom_print_nl();
 
-        prom_print(RELOC("naca->interrupt_controller = 0x"));
+        prom_print(RELOC("naca->interrupt_controller      = 0x"));
         prom_print_hex(_naca->interrupt_controller);
         prom_print_nl();
 
-        prom_print(RELOC("naca->platform             = 0x"));
-        prom_print_hex(_naca->platform);
+        prom_print(RELOC("systemcfg->platform             = 0x"));
+        prom_print_hex(_systemcfg->platform);
         prom_print_nl();
 
 	prom_print(RELOC("prom_initialize_naca: end...\n"));
@@ -549,7 +551,7 @@
 	unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
 	struct rtas_t *_rtas = PTRRELOC(&rtas);
-	struct naca_struct *_naca = RELOC(naca);
+	struct systemcfg *_systemcfg = RELOC(systemcfg);
 	ihandle prom_rtas;
         u32 getprop_rval;
 
@@ -565,7 +567,7 @@
 				  RELOC("ibm,hypertas-functions"), 
 				  hypertas_funcs, 
 				  sizeof(hypertas_funcs))) > 0) {
-			_naca->platform = PLATFORM_PSERIES_LPAR;
+			_systemcfg->platform = PLATFORM_PSERIES_LPAR;
 		}
 
 		call_prom(RELOC("getprop"), 
@@ -582,7 +584,7 @@
 			 * of physical memory (or within the RMO region) because RTAS
 			 * runs in 32-bit mode and relocate off.
 			 */
-			if ( _naca->platform == PLATFORM_PSERIES_LPAR ) {
+			if ( _systemcfg->platform == PLATFORM_PSERIES_LPAR ) {
 				struct lmb *_lmb  = PTRRELOC(&lmb);
 				rtas_region = min(_lmb->rmo_size, RTAS_INSTANTIATE_MAX);
 			}
@@ -767,13 +769,21 @@
 		 * By doing this, we avoid the pitfalls of trying to DMA to
 		 * MMIO space and the DMA alias hole.
 		 */
-		minsize = 4UL << 20;
+		/* 
+		 * On POWER4, firmware sets the TCE region by assuming
+		 * each TCE table is 8MB. Using this memory for anything
+		 * else will impact performance, so we always allocate 8MB.
+		 * Anton
+		 *
+		 * XXX FIXME use a cpu feature here
+		 */
+		minsize = 8UL << 20;
 
 		/* Align to the greater of the align or size */
-		align = (minalign < minsize) ? minsize : minalign;
+		align = max(minalign, minsize);
 
 		/* Carve out storage for the TCE table. */
-		base = lmb_alloc(8UL << 20, 8UL << 20);
+		base = lmb_alloc(minsize, align);
 
 		if ( !base ) {
 			prom_print(RELOC("ERROR, cannot find space for TCE table.\n"));
@@ -875,7 +885,7 @@
 prom_hold_cpus(unsigned long mem)
 {
 	unsigned long i;
-	unsigned int reg;
+	unsigned int cpuid;
 	phandle node;
 	unsigned long offset = reloc_offset();
 	char type[64], *path;
@@ -885,9 +895,13 @@
         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
+        struct systemcfg *_systemcfg = RELOC(systemcfg);
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
+	/* Initially, we must have one active CPU. */
+	_systemcfg->processorCount = 1;
+
 #ifdef DEBUG_PROM
 	prom_print(RELOC("prom_hold_cpus: start...\n"));
 	prom_print(RELOC("    1) spinloop       = 0x"));
@@ -933,12 +947,12 @@
 		if (strcmp(type, RELOC("okay")) != 0)
 			continue;
 
-                reg = -1;
+                cpuid = -1;
 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
-			  &reg, sizeof(reg));
+			  &cpuid, sizeof(cpuid));
 
 		/* Only need to start secondary procs, not ourself. */
-		if ( reg == _prom->cpu )
+		if ( cpuid == _prom->cpu )
 			continue;
 
 		path = (char *) mem;
@@ -950,7 +964,7 @@
 #ifdef DEBUG_PROM
 		prom_print_nl();
 		prom_print(RELOC("cpu hw idx   = 0x"));
-		prom_print_hex(reg);
+		prom_print_hex(cpuid);
 		prom_print_nl();
 #endif
 		prom_print(RELOC("starting cpu "));
@@ -978,9 +992,8 @@
 		prom_print(RELOC("    3) secondary_hold = 0x"));
 		prom_print_hex(secondary_hold);
 		prom_print_nl();
-		prom_print_nl();
 #endif
-		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, reg);
+		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
 		prom_print(RELOC("..."));
 		for ( i = 0 ; (i < 100000000) && 
 			      (*acknowledge == ((unsigned long)-1)); i++ ) ;
@@ -992,10 +1005,11 @@
 			prom_print_nl();
 		}
 #endif
-		if (*acknowledge == reg) {
+		if (*acknowledge == cpuid) {
 			prom_print(RELOC("ok\n"));
 			/* Set the number of active processors. */
-			_xPaca[reg].active = 1;
+			_systemcfg->processorCount++;
+			_xPaca[cpuid].active = 1;
 		} else {
 			prom_print(RELOC("failed: "));
 			prom_print_hex(*acknowledge);
@@ -1024,8 +1038,8 @@
 				}
 			}
 			_xPaca[i+1].active = 1;
-			RELOC(hmt_thread_data)[i].threadid = i+1;
 		}
+		_systemcfg->processorCount *= 2;
 	} else {
 		prom_print(RELOC("Processor is not HMT capable\n"));
 	}
@@ -1046,20 +1060,21 @@
 prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
 	  unsigned long r6, unsigned long r7)
 {
+	int chrp = 0;
 	unsigned long mem;
-	ihandle prom_root, prom_cpu;
+	ihandle prom_mmu, prom_op, prom_root, prom_cpu;
 	phandle cpu_pkg;
 	unsigned long offset = reloc_offset();
-	long l;
+	long l, sz;
 	char *p, *d;
  	unsigned long phys;
         u32 getprop_rval;
-        struct naca_struct *_naca = RELOC(naca);
+        struct systemcfg *_systemcfg = RELOC(systemcfg);
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
 	/* Default machine type. */
-	_naca->platform = PLATFORM_PSERIES;
+	_systemcfg->platform = PLATFORM_PSERIES;
 
 #if 0
 	/* Reset klimit to take into account the embedded system map */
@@ -1149,6 +1164,8 @@
 
 	mem = prom_bi_rec_reserve(mem);
 
+	mem = check_display(mem);
+
 	prom_instantiate_rtas();
         
         /* Initialize some system info into the Naca early... */
@@ -1158,11 +1175,9 @@
          * following, regardless of whether we have an SMP
          * kernel or not.
          */
-        if (RELOC(ppc64_is_smp))
+        if (_systemcfg->processorCount > 1)
 	        prom_hold_cpus(mem);
 
-	mem = check_display(mem);
-
 #ifdef DEBUG_PROM
 	prom_print(RELOC("copying OF device tree...\n"));
 #endif
@@ -1172,7 +1187,7 @@
 
 	lmb_reserve(0, __pa(RELOC(klimit)));
 
-	if (_naca->platform == PLATFORM_PSERIES)
+	if (_systemcfg->platform == PLATFORM_PSERIES)
 		prom_initialize_tce_table();
 
 	prom_print(RELOC("Calling quiesce ...\n"));
diff -Nru a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
--- a/arch/ppc64/kernel/ras.c	Mon Feb 24 10:14:15 2003
+++ b/arch/ppc64/kernel/ras.c	Wed Apr 23 22:45:15 2003
@@ -54,8 +54,10 @@
 #include <asm/rtas.h>
 #include <asm/ppcdebug.h>
 
-static void ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-static void ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t ras_epow_interrupt(int irq, void *dev_id,
+					struct pt_regs * regs);
+static irqreturn_t ras_error_interrupt(int irq, void *dev_id,
+					struct pt_regs * regs);
 void init_ras_IRQ(void);
 
 /* #define DEBUG */
@@ -73,7 +75,7 @@
 						&len))) {
 		for(i=0; i<(len / sizeof(*ireg)); i++) {
 			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
-				    &ras_error_interrupt, 0, 
+				    ras_error_interrupt, 0, 
 				    "RAS_ERROR", NULL);
 			ireg++;
 		}
@@ -84,7 +86,7 @@
 						&len))) {
 		for(i=0; i<(len / sizeof(*ireg)); i++) {
 			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
-				    &ras_epow_interrupt, 0, 
+				    ras_epow_interrupt, 0, 
 				    "RAS_EPOW", NULL);
 			ireg++;
 		}
@@ -98,7 +100,7 @@
  * to examine the type of power failure and take appropriate action where
  * the time horizon permits something useful to be done.
  */
-static void
+static irqreturn_t
 ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct rtas_error_log log_entry;
@@ -114,7 +116,8 @@
 	udbg_printf("EPOW <0x%lx 0x%lx>\n", 
 		    *((unsigned long *)&log_entry), status); 
 	printk(KERN_WARNING 
-	       "EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status);
+		"EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status);
+	return IRQ_HANDLED;
 }
 
 /*
@@ -125,7 +128,7 @@
  * For nonrecoverable errors, an error is logged and we stop all processing
  * as quickly as possible in order to prevent propagation of the failure.
  */
-static void
+static irqreturn_t
 ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct rtas_error_log log_entry;
@@ -158,7 +161,6 @@
 		printk(KERN_WARNING 
 		       "Warning: Recoverable hardware error <0x%lx 0x%lx>\n",
 		       *((unsigned long *)&log_entry), status);
-
-		return;
 	}
+	return IRQ_HANDLED;
 }
diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
--- a/arch/ppc64/kernel/rtas-proc.c	Wed Jan 29 00:59:02 2003
+++ b/arch/ppc64/kernel/rtas-proc.c	Mon Apr 21 12:42:07 2003
@@ -201,7 +201,7 @@
 	struct proc_dir_entry *entry;
 
 	rtas_node = find_devices("rtas");
-	if ((rtas_node == NULL) || (naca->platform == PLATFORM_ISERIES_LPAR)) {
+	if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
 		return;
 	}
 	
@@ -506,21 +506,27 @@
 		int error, char * buf) 
 {
 	/* Defined return vales */
-	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
+	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", 
+						"Maintenance" };
 	const char * enclosure_switch[]  = { "Closed", "Open" };
 	const char * lid_status[]        = { " ", "Open", "Closed" };
-	const char * power_source[]      = { "AC\t", "Battery", "AC & Battery" };
+	const char * power_source[]      = { "AC\t", "Battery", 
+		  				"AC & Battery" };
 	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
 	const char * epow_sensor[]       = { 
 		"EPOW Reset", "Cooling warning", "Power warning",
 		"System shutdown", "System halt", "EPOW main enclosure",
 		"EPOW power off" };
-	const char * battery_cyclestate[]  = { "None", "In progress", "Requested" };
-	const char * battery_charging[]    = { "Charging", "Discharching", "No current flow" };
-	const char * ibm_drconnector[]     = { "Empty", "Present" };
+	const char * battery_cyclestate[]  = { "None", "In progress", 
+						"Requested" };
+	const char * battery_charging[]    = { "Charging", "Discharching", 
+						"No current flow" };
+	const char * ibm_drconnector[]     = { "Empty", "Present", "Unusable", 
+						"Exchange" };
 	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };
 
 	int have_strings = 0;
+	int num_states = 0;
 	int temperature = 0;
 	int unknown = 0;
 	int n = 0;
@@ -530,13 +536,20 @@
 	switch (s.token) {
 		case KEY_SWITCH:
 			n += sprintf(buf+n, "Key switch:\t");
-			n += sprintf(buf+n, "%s\t", key_switch[state]);
-			have_strings = 1;
+			num_states = sizeof(key_switch) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", key_switch[state]);
+				have_strings = 1;
+			}
 			break;
 		case ENCLOSURE_SWITCH:
 			n += sprintf(buf+n, "Enclosure switch:\t");
-			n += sprintf(buf+n, "%s\t", enclosure_switch[state]);
-			have_strings = 1;
+			num_states = sizeof(enclosure_switch) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						enclosure_switch[state]);
+				have_strings = 1;
+			}
 			break;
 		case THERMAL_SENSOR:
 			n += sprintf(buf+n, "Temp. (°C/°F):\t");
@@ -544,39 +557,63 @@
 			break;
 		case LID_STATUS:
 			n += sprintf(buf+n, "Lid status:\t");
-			n += sprintf(buf+n, "%s\t", lid_status[state]);
-			have_strings = 1;
+			num_states = sizeof(lid_status) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", lid_status[state]);
+				have_strings = 1;
+			}
 			break;
 		case POWER_SOURCE:
 			n += sprintf(buf+n, "Power source:\t");
-			n += sprintf(buf+n, "%s\t", power_source[state]);
-			have_strings = 1;
+			num_states = sizeof(power_source) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						power_source[state]);
+				have_strings = 1;
+			}
 			break;
 		case BATTERY_VOLTAGE:
 			n += sprintf(buf+n, "Battery voltage:\t");
 			break;
 		case BATTERY_REMAINING:
 			n += sprintf(buf+n, "Battery remaining:\t");
-			n += sprintf(buf+n, "%s\t", battery_remaining[state]);
-			have_strings = 1;
+			num_states = sizeof(battery_remaining) / sizeof(char *);
+			if (state < num_states)
+			{
+				n += sprintf(buf+n, "%s\t", 
+						battery_remaining[state]);
+				have_strings = 1;
+			}
 			break;
 		case BATTERY_PERCENTAGE:
 			n += sprintf(buf+n, "Battery percentage:\t");
 			break;
 		case EPOW_SENSOR:
 			n += sprintf(buf+n, "EPOW Sensor:\t");
-			n += sprintf(buf+n, "%s\t", epow_sensor[state]);
-			have_strings = 1;
+			num_states = sizeof(epow_sensor) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", epow_sensor[state]);
+				have_strings = 1;
+			}
 			break;
 		case BATTERY_CYCLESTATE:
 			n += sprintf(buf+n, "Battery cyclestate:\t");
-			n += sprintf(buf+n, "%s\t", battery_cyclestate[state]);
-			have_strings = 1;
+			num_states = sizeof(battery_cyclestate) / 
+				     	sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						battery_cyclestate[state]);
+				have_strings = 1;
+			}
 			break;
 		case BATTERY_CHARGING:
 			n += sprintf(buf+n, "Battery Charging:\t");
-			n += sprintf(buf+n, "%s\t", battery_charging[state]);
-			have_strings = 1;
+			num_states = sizeof(battery_charging) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						battery_charging[state]);
+				have_strings = 1;
+			}
 			break;
 		case IBM_SURVEILLANCE:
 			n += sprintf(buf+n, "Surveillance:\t");
@@ -589,16 +626,24 @@
 			break;
 		case IBM_DRCONNECTOR:
 			n += sprintf(buf+n, "DR connector:\t");
-			n += sprintf(buf+n, "%s\t", ibm_drconnector[state]);
-			have_strings = 1;
+			num_states = sizeof(ibm_drconnector) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						ibm_drconnector[state]);
+				have_strings = 1;
+			}
 			break;
 		case IBM_POWERSUPPLY:
 			n += sprintf(buf+n, "Powersupply:\t");
 			break;
 		case IBM_INTQUEUE:
 			n += sprintf(buf+n, "Interrupt queue:\t");
-			n += sprintf(buf+n, "%s\t", ibm_intqueue[state]);
-			have_strings = 1;
+			num_states = sizeof(ibm_intqueue) / sizeof(char *);
+			if (state < num_states) {
+				n += sprintf(buf+n, "%s\t", 
+						ibm_intqueue[state]);
+				have_strings = 1;
+			}
 			break;
 		default:
 			n += sprintf(buf+n,  "Unkown sensor (type %d), ignoring it\n",
diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
--- a/arch/ppc64/kernel/rtas.c	Thu Feb 13 00:57:29 2003
+++ b/arch/ppc64/kernel/rtas.c	Thu May  1 20:23:50 2003
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 
 #include <asm/prom.h>
+#include <asm/proc_fs.h>
 #include <asm/rtas.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
@@ -27,7 +28,6 @@
 #include <asm/abs_addr.h>
 #include <asm/udbg.h>
 
-struct proc_dir_entry *rtas_proc_dir;	/* /proc/ppc64/rtas dir */
 struct flash_block_list_header rtas_firmware_flash_list = {0, 0};
 
 /*
@@ -216,7 +216,11 @@
 			image_size += f->blocks[i].length;
 		}
 		next = f->next;
-		f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next);
+		/* Don't translate NULL pointer for last entry */
+		if(f->next)
+			f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next);
+		else
+			f->next = 0LL;
 		/* make num_blocks into the version/length field */
 		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
 	}
@@ -283,7 +287,7 @@
         rtas_power_off();
 }
 
-EXPORT_SYMBOL(rtas_proc_dir);
+EXPORT_SYMBOL(proc_ppc64);
 EXPORT_SYMBOL(rtas_firmware_flash_list);
 EXPORT_SYMBOL(rtas_token);
 EXPORT_SYMBOL(rtas_call);
diff -Nru a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c
--- a/arch/ppc64/kernel/rtas_flash.c	Mon Nov 11 05:21:11 2002
+++ b/arch/ppc64/kernel/rtas_flash.c	Tue Mar 25 20:30:59 2003
@@ -210,7 +210,7 @@
 {
 	struct proc_dir_entry *ent = NULL;
 
-	if (!rtas_proc_dir) {
+	if (!proc_ppc64.rtas) {
 		printk(KERN_WARNING "rtas proc dir does not already exist");
 		return -ENOENT;
 	}
@@ -218,7 +218,7 @@
 	if (rtas_token("ibm,update-flash-64-and-reboot") != RTAS_UNKNOWN_SERVICE)
 		flash_possible = 1;
 
-	if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, rtas_proc_dir)) != NULL) {
+	if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, proc_ppc64.rtas)) != NULL) {
 		ent->nlink = 1;
 		ent->proc_fops = &rtas_flash_operations;
 		ent->owner = THIS_MODULE;
@@ -228,9 +228,9 @@
 
 void __exit rtas_flash_cleanup(void)
 {
-	if (!rtas_proc_dir)
+	if (!proc_ppc64.rtas)
 		return;
-	remove_proc_entry(FIRMWARE_FLASH_NAME, rtas_proc_dir);
+	remove_proc_entry(FIRMWARE_FLASH_NAME, proc_ppc64.rtas);
 }
 
 module_init(rtas_flash_init);
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c	Sun Apr 20 09:14:41 2003
+++ b/arch/ppc64/kernel/setup.c	Sun Apr 27 14:32:15 2003
@@ -142,9 +142,6 @@
 void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
 		  unsigned long r6, unsigned long r7)
 {
-	/* This should be fixed properly in kernel/resource.c */
-	iomem_resource.end = MEM_SPACE_LIMIT;
-
 #ifdef CONFIG_XMON_DEFAULT
 	debugger = xmon;
 	debugger_bpt = xmon_bpt;
@@ -156,10 +153,10 @@
 #ifdef CONFIG_PPC_ISERIES
 	/* pSeries systems are identified in prom.c via OF. */
 	if ( itLpNaca.xLparInstalled == 1 )
-		naca->platform = PLATFORM_ISERIES_LPAR;
+		systemcfg->platform = PLATFORM_ISERIES_LPAR;
 #endif
 	
-	switch (naca->platform) {
+	switch (systemcfg->platform) {
 #ifdef CONFIG_PPC_ISERIES
 	case PLATFORM_ISERIES_LPAR:
 		iSeries_init_early();
@@ -185,7 +182,7 @@
 #endif
 	}
 
-	if (naca->platform & PLATFORM_PSERIES) {
+	if (systemcfg->platform & PLATFORM_PSERIES) {
 		early_console_initialized = 1;
 		register_console(&udbg_console);
 	}
@@ -193,32 +190,27 @@
 	printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
 
 	printk("-----------------------------------------------------\n");
-	printk("naca                       = 0x%p\n", naca);
-#if 0
-	printk("naca->processorCount       = 0x%x\n", naca->processorCount);
-#endif
-	printk("naca->physicalMemorySize   = 0x%lx\n", naca->physicalMemorySize);
-	printk("naca->dCacheL1LineSize     = 0x%x\n", naca->dCacheL1LineSize);
-	printk("naca->dCacheL1LogLineSize  = 0x%x\n", naca->dCacheL1LogLineSize);
-	printk("naca->dCacheL1LinesPerPage = 0x%x\n", naca->dCacheL1LinesPerPage);
-	printk("naca->iCacheL1LineSize     = 0x%x\n", naca->iCacheL1LineSize);
-	printk("naca->iCacheL1LogLineSize  = 0x%x\n", naca->iCacheL1LogLineSize);
-	printk("naca->iCacheL1LinesPerPage = 0x%x\n", naca->iCacheL1LinesPerPage);
-	printk("naca->pftSize              = 0x%lx\n", naca->pftSize);
-	printk("naca->debug_switch         = 0x%lx\n", naca->debug_switch);
-	printk("naca->interrupt_controller = 0x%d\n", naca->interrupt_controller);
-	printk("htab_data.htab             = 0x%p\n", htab_data.htab);
-	printk("htab_data.num_ptegs        = 0x%lx\n", htab_data.htab_num_ptegs);
+	printk("naca                          = 0x%p\n", naca);
+	printk("naca->pftSize                 = 0x%lx\n", naca->pftSize);
+	printk("naca->debug_switch            = 0x%lx\n", naca->debug_switch);
+	printk("naca->interrupt_controller    = 0x%d\n", naca->interrupt_controller);
+	printk("systemcf                      = 0x%p\n", systemcfg);
+	printk("systemcfg->processorCount     = 0x%x\n", systemcfg->processorCount);
+	printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
+	printk("systemcfg->dCacheL1LineSize   = 0x%x\n", systemcfg->dCacheL1LineSize);
+	printk("systemcfg->iCacheL1LineSize   = 0x%x\n", systemcfg->iCacheL1LineSize);
+	printk("htab_data.htab                = 0x%p\n", htab_data.htab);
+	printk("htab_data.num_ptegs           = 0x%lx\n", htab_data.htab_num_ptegs);
 	printk("-----------------------------------------------------\n");
 
-	if (naca->platform & PLATFORM_PSERIES) {
+	if (systemcfg->platform & PLATFORM_PSERIES) {
 		finish_device_tree();
 		chrp_init(r3, r4, r5, r6, r7);
 	}
 
 	mm_init_ppc64();
 
-	switch (naca->platform) {
+	switch (systemcfg->platform) {
 #ifdef CONFIG_PPC_ISERIES
 	case PLATFORM_ISERIES_LPAR:
 		iSeries_init();
@@ -312,7 +304,7 @@
 	 * Assume here that all clock rates are the same in a
 	 * smp system.  -- Cort
 	 */
-	if (naca->platform != PLATFORM_ISERIES_LPAR) {
+	if (systemcfg->platform != PLATFORM_ISERIES_LPAR) {
 		struct device_node *cpu_node;
 		int *fp;
 
@@ -516,8 +508,8 @@
 	 * Systems with OF can look in the properties on the cpu node(s)
 	 * for a possibly more accurate value.
 	 */
-	dcache_bsize = naca->dCacheL1LineSize; 
-	icache_bsize = naca->iCacheL1LineSize; 
+	dcache_bsize = systemcfg->dCacheL1LineSize; 
+	icache_bsize = systemcfg->iCacheL1LineSize; 
 
 	/* reboot on panic */
 	panic_timeout = 180;
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Tue Feb 11 04:25:30 2003
+++ b/arch/ppc64/kernel/signal.c	Tue Mar 25 19:38:55 2003
@@ -43,57 +43,29 @@
 #endif
 
 #define GP_REGS_SIZE	MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+#define FP_REGS_SIZE	sizeof(elf_fpregset_t)
 
-/* 
- * These are the flags in the MSR that the user is allowed to change
- * by modifying the saved value of the MSR on the stack.  SE and BE
- * should not be in this list since gdb may want to change these.  I.e,
- * you should be able to step out of a signal handler to see what
- * instruction executes next after the signal handler completes.
- * Alternately, if you stepped into a signal handler, you should be
- * able to continue 'til the next breakpoint from within the signal
- * handler, even if the handler returns.
- */
-#if 0
-#define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
-#else
-/*
- * glibc tries to set FE0/FE1 via a signal handler. Since it only ever
- * sets both bits and this is the default setting we now disable this
- * behaviour. This is done to insure the new prctl which alters FE0/FE1 does
- * not get overriden by glibc. Setting and clearing FE0/FE1 via signal
- * handler has always been bogus since load_up_fpu used to set FE0/FE1
- * unconditionally.
- */
-#define MSR_USERCHANGE	0
-#endif
+#define TRAMP_TRACEBACK	3
+#define TRAMP_SIZE	6
 
 /*
- * When we have signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- *	a sigregs struct
- *	one or more sigcontext structs with
- *	a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
+ * When we have signals to deliver, we set up on the user stack,
+ * going down from the original stack pointer:
+ *	1) a rt_sigframe struct which contains the ucontext	
+ *	2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller
+ *	   frame for the signal handler.
  */
-struct sigregs {
-	elf_gregset_t	gp_regs;
-	double		fp_regs[ELF_NFPREG];
-	unsigned int	tramp[2];
-	/* 64 bit API allows for 288 bytes below sp before 
-	   decrementing it. */
-	int		abigap[72];
-};
 
-struct rt_sigframe
-{
-	unsigned long	_unused[2];
+struct rt_sigframe {
+	/* sys_rt_sigreturn requires the ucontext be the first field */
+	struct ucontext uc;
+	unsigned long _unused[2];
+	unsigned int tramp[TRAMP_SIZE];
 	struct siginfo *pinfo;
 	void *puc;
 	struct siginfo info;
-	struct ucontext uc;
+	/* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
+	char abigap[288];
 };
 
 
@@ -102,37 +74,6 @@
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
-	       struct pt_regs *regs)
-{
-	sigset_t saveset;
-
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs))
-			/*
-			 * If a signal handler needs to be called,
-			 * do_signal() has set R3 to the signal number (the
-			 * first argument of the signal handler), so don't
-			 * overwrite that with EINTR !
-			 * In the other cases, do_signal() doesn't touch 
-			 * R3, so it's still set to -EINTR (see above).
-			 */
-			return regs->gpr[3];
-	}
-}
-
 long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
 		  int p7, struct pt_regs *regs)
 {
@@ -170,339 +111,232 @@
 	return do_sigaltstack(uss, uoss, regs->gpr[1]);
 }
 
-long sys_sigaction(int sig, const struct old_sigaction *act,
-	      struct old_sigaction *oact)
+
+/*
+ * Set up the sigcontext for the signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		 int signr, sigset_t *set, unsigned long handler)
 {
-	struct k_sigaction new_ka, old_ka;
-	int ret;
+	int err = 0;
 
-	if (act) {
-		old_sigset_t mask;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
 
-		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
-			return -EFAULT;
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
-		siginitset(&new_ka.sa.sa_mask, mask);
-	}
+	current->thread.saved_msr = regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
+	regs->msr = current->thread.saved_msr | current->thread.fpexc_mode;
+	current->thread.saved_softe = regs->softe;
+
+	err |= __put_user(&sc->gp_regs, &sc->regs);
+	err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
+	err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
+	err |= __put_user(signr, &sc->signal);
+	err |= __put_user(handler, &sc->handler);
+	if (set != NULL)
+		err |=  __put_user(set->sig[0], &sc->oldmask);
 
-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-	if (!ret && oact) {
-		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
-			return -EFAULT;
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-	}
+	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+	current->thread.fpscr = 0;
 
-	return ret;
+	return err;
 }
 
 /*
- *  When we have rt signals to deliver, we set up on the
- *  user stack, going down from the original stack pointer:
- *	   a sigregs struct
- *	   one rt_sigframe struct (siginfo + ucontext)
- *	   a gap of __SIGNAL_FRAMESIZE bytes
- *
- *  Each of these things must be a multiple of 16 bytes in size.
- *
+ * Restore the sigcontext from the signal frame.
  */
 
-int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
-		     unsigned long r6, unsigned long r7, unsigned long r8,
-		     struct pt_regs *regs)
+static int
+restore_sigcontext(struct pt_regs *regs, sigset_t *set, struct sigcontext *sc)
 {
-	struct rt_sigframe *rt_sf;
-	struct sigcontext sigctx;
-	struct sigregs *sr;
-	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
-	sigset_t set;
-	stack_t st;
+	unsigned int err = 0;
 
-	rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
-	if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
-	    || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
-	    || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
-		goto badframe;
-	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
-	/* restore registers -
-	 * sigctx is initialized to point to the 
-	 * preamble frame (where registers are stored) 
-	 * see handle_signal()
-	 */
-	sr = (struct sigregs *)sigctx.regs;
-	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
-		goto badframe;
-	saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
-		| (saved_regs[PT_MSR] & MSR_USERCHANGE);
-	saved_regs[PT_SOFTE] = regs->softe;
-	memcpy(regs, saved_regs, GP_REGS_SIZE);
-	if (copy_from_user(current->thread.fpr, &sr->fp_regs,
-			   sizeof(sr->fp_regs)))
-		goto badframe;
-	/* This function sets back the stack flags into
-	   the current task structure.  */
-	sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
+	err |= __copy_from_user(regs, &sc->gp_regs, GP_REGS_SIZE);
+	err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
+	current->thread.fpexc_mode = regs->msr & (MSR_FE0 | MSR_FE1);
+	if (set != NULL)
+		err |=  __get_user(set->sig[0], &sc->oldmask);
+
+	/* Don't allow the signal handler to change these modulo FE{0,1} */
+	regs->msr = current->thread.saved_msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
+	regs->softe = current->thread.saved_softe;
 
-	return regs->result;
-
-badframe:
-	do_exit(SIGSEGV);
+	return err;
 }
 
-static void setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
-	       signed long newsp)
+/*
+ * Allocate space for the signal frame
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 {
-	struct rt_sigframe *rt_sf = (struct rt_sigframe *)newsp;
-	/* Handler is *really* a pointer to the function descriptor for
-	 * the signal routine.  The first entry in the function
-	 * descriptor is the entry address of signal and the second
-	 * entry is the TOC value we need to use.
-	 */
-        struct funct_descr_entry {
-                     unsigned long entry;
-                     unsigned long toc;
-	};
-  
-	struct funct_descr_entry * funct_desc_ptr;
-	unsigned long temp_ptr;
+        unsigned long newsp;
 
-	/* Set up preamble frame */
-	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
-		goto badframe;
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
-	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
-			      ELF_NFPREG * sizeof(double))
-	    /* li r0, __NR_rt_sigreturn */
-	    || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
-	    /* sc */
-	    || __put_user(0x44000002UL, &frame->tramp[1]))
-		goto badframe;
-	flush_icache_range((unsigned long)&frame->tramp[0],
-			   (unsigned long)&frame->tramp[2]);
-	current->thread.fpscr = 0;	/* turn off all fp exceptions */
-
-	/* Retrieve rt_sigframe from stack and
-	   set up registers for signal handler
-	*/
-	newsp -= __SIGNAL_FRAMESIZE;
+        /* Default to using normal stack */
+        newsp = regs->gpr[1];
 
-        if (get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
-		goto badframe;
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (! on_sig_stack(regs->gpr[1]))
+			newsp = (current->sas_ss_sp + current->sas_ss_size);
 	}
 
-        funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
-        
-	if (put_user(regs->gpr[1], (unsigned long *)newsp)
-	    || get_user(regs->nip, &funct_desc_ptr->entry)
-            || get_user(regs->gpr[2], &funct_desc_ptr->toc)
-	    || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
-	    || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo)
-	    || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc))
-		goto badframe;
+        return (void *)((newsp - frame_size) & -8ul);
+}
 
-	regs->gpr[1] = newsp;
-	regs->gpr[6] = (unsigned long)rt_sf;
-	regs->link = (unsigned long)frame->tramp;
+static int
+setup_trampoline(unsigned int syscall, unsigned int *tramp)
+{
+	int i, err = 0;
 
-	return;
+	/* addi r1, r1, __SIGNAL_FRAMESIZE  # Pop the dummy stackframe */
+	err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
+	/* li r0, __NR_[rt_]sigreturn| */
+	err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
+	/* sc */
+	err |= __put_user(0x44000002UL, &tramp[2]);
+
+	/* Minimal traceback info */
+	for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
+		err |= __put_user(0, &tramp[i]);
+
+	if (!err)
+		flush_icache_range((unsigned long) &tramp[0],
+			   (unsigned long) &tramp[TRAMP_SIZE]);
 
-badframe:
-#if DEBUG_SIG
-	printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
-	       regs, frame, newsp);
-#endif
-	do_exit(SIGSEGV);
+	return err;
 }
 
 /*
  * Do a signal return; undo the signal stack.
  */
-long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
-		   unsigned long r6, unsigned long r7, unsigned long r8,
-		   struct pt_regs *regs)
-{
-	struct sigcontext *sc, sigctx;
-	struct sigregs *sr;
-	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+
+int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+		     unsigned long r6, unsigned long r7, unsigned long r8,
+		     struct pt_regs *regs)
+{
+	struct ucontext *uc = (struct ucontext *)regs->gpr[1];
 	sigset_t set;
+	stack_t st;
 
-	sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
-	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+	if (verify_area(VERIFY_READ, uc, sizeof(*uc)))
 		goto badframe;
 
-	set.sig[0] = sigctx.oldmask;
-#if _NSIG_WORDS > 1
-	set.sig[1] = sigctx._unused[3];
-#endif
+	if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
+		goto badframe;
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
 
-	/* restore registers */
-	sr = (struct sigregs *)sigctx.regs;
-	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+	if (restore_sigcontext(regs, NULL, &uc->uc_mcontext))
 		goto badframe;
-	saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
-		| (saved_regs[PT_MSR] & MSR_USERCHANGE);
-	saved_regs[PT_SOFTE] = regs->softe;
-	memcpy(regs, saved_regs, GP_REGS_SIZE);
 
-	if (copy_from_user(current->thread.fpr, &sr->fp_regs,
-			   sizeof(sr->fp_regs)))
+	if (__copy_from_user(&st, &uc->uc_stack, sizeof(st)))
 		goto badframe;
+	/* This function sets back the stack flags into
+	   the current task structure.  */
+	sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
 
 	return regs->result;
 
 badframe:
+#if DEBUG_SIG
+	printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
+	       regs, uc, &uc->uc_mcontext);
+#endif
 	do_exit(SIGSEGV);
-}	
+}
 
-/*
- * Set up a signal frame.
- */
-static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
-	    unsigned long newsp)
+static void
+setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
+		sigset_t *set, struct pt_regs *regs)
 {
-
 	/* Handler is *really* a pointer to the function descriptor for
 	 * the signal routine.  The first entry in the function
 	 * descriptor is the entry address of signal and the second
 	 * entry is the TOC value we need to use.
 	 */
-	struct funct_descr_entry {
-		unsigned long entry;
-		unsigned long toc;
-	};
-  
-	struct funct_descr_entry * funct_desc_ptr;
-	unsigned long temp_ptr;
+	func_descr_t *funct_desc_ptr;
+	struct rt_sigframe *frame;
+	unsigned long newsp = 0;
+	int err = 0;
 
-	struct sigcontext *sc = (struct sigcontext *)newsp;
-  
-	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
-		goto badframe;
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
-	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
-			      ELF_NFPREG * sizeof(double))
-	    /* li r0, __NR_sigreturn */
-	    || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
-	    /* sc */
-	    || __put_user(0x44000002UL, &frame->tramp[1]))
-		goto badframe;
-	flush_icache_range((unsigned long)&frame->tramp[0],
-			   (unsigned long)&frame->tramp[2]);
-	current->thread.fpscr = 0;	/* turn off all fp exceptions */
+	frame = get_sigframe(ka, regs, sizeof(*frame));
 
-	newsp -= __SIGNAL_FRAMESIZE;
-	if (get_user(temp_ptr, &sc->handler))
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto badframe;
-  
-	funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
 
-	if (put_user(regs->gpr[1], (unsigned long *)newsp)
-	    || get_user(regs->nip, &funct_desc_ptr ->entry)
-	    || get_user(regs->gpr[2],&funct_desc_ptr->toc)
-	    || get_user(regs->gpr[3], &sc->signal))
-		goto badframe;
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+	if (err)
+		goto badframe;
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->gpr[1]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
+				(unsigned long)ka->sa.sa_handler);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+	if (err)
+		goto badframe;
+
+	/* Set up to return from userspace. */
+	err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
+	if (err)
+		goto badframe;
+
+	funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
+
+	/* Allocate a dummy caller frame for the signal handler. */
+	newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
+	err |= put_user(0, (unsigned long *)newsp);
+
+	/* Set up "regs" so we "return" to the signal handler. */
+	err |= get_user(regs->nip, &funct_desc_ptr->entry);
+	regs->link = (unsigned long) &frame->tramp[0];
 	regs->gpr[1] = newsp;
-	regs->gpr[4] = (unsigned long)sc;
-	regs->link = (unsigned long)frame->tramp;
+	err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+	regs->gpr[3] = signr;
+	if (ka->sa.sa_flags & SA_SIGINFO) {
+		err |= get_user(regs->gpr[4], (unsigned long *)&frame->pinfo);
+		err |= get_user(regs->gpr[5], (unsigned long *)&frame->puc);
+		regs->gpr[6] = (unsigned long) frame;
+	} else {
+		regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext;
+	}
+	if (err)
+		goto badframe;
 
 	return;
 
 badframe:
 #if DEBUG_SIG
-	printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+	printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
 	do_exit(SIGSEGV);
 }
 
+
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
-	struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
-	struct sigcontext *sc;
-	struct rt_sigframe *rt_sf;
-	struct k_sigaction *ka = &current->sighand->action[sig-1];
-
-	if (regs->trap == 0x0C00 /* System Call! */
-	    && ((int)regs->result == -ERESTARTNOHAND ||
-		(int)regs->result == -ERESTART_RESTARTBLOCK ||
-		((int)regs->result == -ERESTARTSYS &&
-		 !(ka->sa.sa_flags & SA_RESTART)))) {
-		if ((int)regs->result == -ERESTART_RESTARTBLOCK)
-			current_thread_info()->restart_block.fn
-				= do_no_restart_syscall;
-		regs->result = -EINTR;
-	}
-
 	/* Set up Signal Frame */
-	if (ka->sa.sa_flags & SA_SIGINFO) {
-		/* Put a Real Time Context onto stack */
-		*newspp -= sizeof(*rt_sf);
-		rt_sf = (struct rt_sigframe *)*newspp;
-		if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
-			goto badframe;
-
-		if (__put_user((unsigned long)ka->sa.sa_handler,
-					&rt_sf->uc.uc_mcontext.handler)
-		    || __put_user(&rt_sf->info, &rt_sf->pinfo)
-		    || __put_user(&rt_sf->uc, &rt_sf->puc)
-		    /* Put the siginfo */
-		    || copy_siginfo_to_user(&rt_sf->info, info)
-		    /* Create the ucontext */
-		    || __put_user(0, &rt_sf->uc.uc_flags)
-		    || __put_user(0, &rt_sf->uc.uc_link)
-		    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
-		    || __put_user(sas_ss_flags(regs->gpr[1]), 
-			    &rt_sf->uc.uc_stack.ss_flags)
-		    || __put_user(current->sas_ss_size,
-			    &rt_sf->uc.uc_stack.ss_size)
-		    || __copy_to_user(&rt_sf->uc.uc_sigmask,
-			    oldset, sizeof(*oldset))
-		    /* mcontext.regs points to preamble register frame */
-		    || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
-		    || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
-			goto badframe;
-	} else {
-		/* Put a sigcontext on the stack */
-		*newspp -= sizeof(*sc);
-		sc = (struct sigcontext *)*newspp;
-		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
-			goto badframe;
-		
-		if (__put_user((unsigned long)ka->sa.sa_handler, &sc->handler)
-		    || __put_user(oldset->sig[0], &sc->oldmask)
-#if _NSIG_WORDS > 1
-		    || __put_user(oldset->sig[1], &sc->_unused[3])
-#endif
-		    || __put_user((struct pt_regs *)frame, &sc->regs)
-		    || __put_user(sig, &sc->signal))
-			goto badframe;
-	}
+	setup_rt_frame(sig, ka, info, oldset, regs);
 
 	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
@@ -515,14 +349,40 @@
 		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return;
+}
 
-badframe:
-#if DEBUG_SIG
-	printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
-	       regs, frame, *newspp);
-	printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
-#endif
-	do_exit(SIGSEGV);
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+	switch ((int)regs->result) {
+	case -ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+		/* fallthrough */
+	case -ERESTARTNOHAND:
+		/* ERESTARTNOHAND means that the syscall should only be
+		 * restarted if there was no handler for the signal, and since
+		 * we only get here if there is a handler, we dont restart.
+		 */
+		regs->result = -EINTR;
+		break;
+	case -ERESTARTSYS:
+		/* ERESTARTSYS means to restart the syscall if there is no
+		 * handler or the handler was registered with SA_RESTART
+		 */
+		if (!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->result = -EINTR;
+			break;
+		}
+		/* fallthrough */
+	case -ERESTARTNOINTR:
+		/* ERESTARTNOINTR means that the syscall should be
+		 * called again after the signal handler returns.
+		 */
+		regs->gpr[3] = regs->orig_gpr3;
+		regs->nip -= 4;
+		regs->result = 0;
+		break;
+	}
 }
 
 /*
@@ -535,8 +395,6 @@
 int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
 	siginfo_t info;
-	struct k_sigaction *ka;
-	unsigned long frame, newsp;
 	int signr;
 
 	/*
@@ -549,20 +407,15 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	newsp = frame = 0;
-
 	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
-		ka = &current->sighand->action[signr-1];
-		if ((ka->sa.sa_flags & SA_ONSTACK)
-		     && (!on_sig_stack(regs->gpr[1])))
-			newsp = (current->sas_ss_sp + current->sas_ss_size);
-		else
-			newsp = regs->gpr[1];
-		newsp = frame = newsp - sizeof(struct sigregs);
+		struct k_sigaction *ka = &current->sighand->action[signr-1];
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, oldset, regs, &newsp, frame);
+		if (regs->trap == 0x0C00)
+			syscall_restart(regs, ka);
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
 	}
 
 	if (regs->trap == 0x0C00) {	/* System Call! */
@@ -579,13 +432,8 @@
 		}
 	}
 
-	if (newsp == frame)
-		return 0;		/* no signals delivered */
-
-	/* Invoke correct stack setup routine */
-	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(regs, (struct sigregs *)frame, newsp);
-	else
-		setup_frame(regs, (struct sigregs *)frame, newsp);
-	return 1;
+	return 0;
 }
+
+
+
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Sun Feb 16 19:22:35 2003
+++ b/arch/ppc64/kernel/signal32.c	Tue Mar 25 19:38:55 2003
@@ -114,6 +114,40 @@
  *        setup_frame32
  */
 
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+	       struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->result = -EINTR;
+	regs->gpr[3] = EINTR;
+	regs->ccr |= 0x10000000;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal32(&saveset, regs))
+			/*
+			 * If a signal handler needs to be called,
+			 * do_signal32() has set R3 to the signal number (the
+			 * first argument of the signal handler), so don't
+			 * overwrite that with EINTR !
+			 * In the other cases, do_signal32() doesn't touch 
+			 * R3, so it's still set to -EINTR (see above).
+			 */
+			return regs->gpr[3];
+	}
+}
+
 long sys32_sigaction(int sig, struct old_sigaction32 *act,
 		struct old_sigaction32 *oact)
 {
@@ -792,13 +826,13 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&saveset, regs))
+		if (do_signal32(&saveset, regs))
 			/*
 			 * If a signal handler needs to be called,
-			 * do_signal() has set R3 to the signal number (the
+			 * do_signal32() has set R3 to the signal number (the
 			 * first argument of the signal handler), so don't
 			 * overwrite that with EINTR !
-			 * In the other cases, do_signal() doesn't touch 
+			 * In the other cases, do_signal32() doesn't touch 
 			 * R3, so it's still set to -EINTR (see above).
 			 */
 			return regs->gpr[3];
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	Mon Mar 31 14:29:49 2003
+++ b/arch/ppc64/kernel/smp.c	Mon Apr 21 12:42:07 2003
@@ -46,8 +46,9 @@
 #include <asm/ppcdebug.h>
 #include "open_pic.h"
 #include <asm/machdep.h>
+#include <asm/xics.h>
 
-int smp_threads_ready = 0;
+int smp_threads_ready;
 unsigned long cache_decay_ticks;
 
 /* initialised so it doesn't end up in bss */
@@ -63,18 +64,6 @@
 void smp_call_function_interrupt(void);
 void smp_message_pass(int target, int msg, unsigned long data, int wait);
 
-void xics_setup_cpu(void);
-void xics_cause_IPI(int cpu);
-
-/*
- * XICS only has a single IPI, so encode the messages per CPU
- */
-struct xics_ipi_struct {
-	        volatile unsigned long value;
-} ____cacheline_aligned;
-
-struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-
 #define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
 
 static inline void set_tb(unsigned int upper, unsigned int lower)
@@ -189,7 +178,7 @@
 	smp_ops->kick_cpu     = smp_iSeries_kick_cpu;
 	smp_ops->setup_cpu    = smp_iSeries_setup_cpu;
 #warning fix for iseries
-	naca->processorCount	= smp_iSeries_numProcs();
+	systemcfg->processorCount	= smp_iSeries_numProcs();
 }
 #endif
 
@@ -353,7 +342,7 @@
 		smp_ops->probe		= smp_xics_probe;
 	}
 
-	if (naca->platform == PLATFORM_PSERIES) {
+	if (systemcfg->platform == PLATFORM_PSERIES) {
 		smp_ops->give_timebase = pSeries_give_timebase;
 		smp_ops->take_timebase = pSeries_take_timebase;
 	}
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	Sat Apr 19 23:22:56 2003
+++ b/arch/ppc64/kernel/sys_ppc32.c	Wed Apr 23 22:20:43 2003
@@ -1801,7 +1801,7 @@
 		err = do_sys32_shmctl(first, second, (void *)AA(ptr));
 		break;
 	default:
-		err = -EINVAL;
+		err = -ENOSYS;
 		break;
 	}
 	return err;
diff -Nru a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
--- a/arch/ppc64/kernel/syscalls.c	Fri Feb 21 23:55:40 2003
+++ b/arch/ppc64/kernel/syscalls.c	Mon Apr  7 14:09:20 2003
@@ -68,7 +68,7 @@
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	ret = -EINVAL;
+	ret = -ENOSYS;
 	switch (call) {
 	case SEMOP:
 		ret = sys_semop (first, (struct sembuf *)ptr, second);
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	Mon Mar 17 21:32:24 2003
+++ b/arch/ppc64/kernel/traps.c	Mon Apr 21 12:42:07 2003
@@ -55,14 +55,12 @@
  * Trap & Exception support
  */
 
-/* Should we panic on bad kernel exceptions or try to recover */
-#undef PANIC_ON_ERROR
-
 static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char *str, struct pt_regs *regs, long err)
 {
 	static int die_counter;
+
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
@@ -71,11 +69,16 @@
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
 
-#ifdef PANIC_ON_ERROR
-	panic(str);
-#else
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops) {
+		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(5 * HZ);
+		panic("Fatal exception");
+	}
 	do_exit(SIGSEGV);
-#endif
 }
 
 static void
@@ -139,15 +142,13 @@
 #ifdef CONFIG_DEBUG_KERNEL
 	if (debugger)
 		debugger(regs);
+	else
 #endif
+		panic("System Reset");
 
-#ifdef PANIC_ON_ERROR
-	panic("System Reset");
-#else
 	/* Must die if the interrupt is not recoverable */
 	if (!(regs->msr & MSR_RI))
 		panic("Unrecoverable System Reset");
-#endif
 
 	/* What should we do here? We could issue a shutdown or hard reset. */
 }
@@ -343,6 +344,14 @@
 		info.si_addr = (void *)regs->nip;
 		_exception(SIGILL, &info, regs);
 	}
+}
+
+ void
+KernelFPUnavailableException(struct pt_regs *regs)
+{
+	printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n",
+		current, regs->nip, regs->trap);
+	panic("Unrecoverable FP Unavailable Exception in Kernel");
 }
 
 void
diff -Nru a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
--- a/arch/ppc64/kernel/udbg.c	Mon Nov  4 17:37:19 2002
+++ b/arch/ppc64/kernel/udbg.c	Tue Mar 25 20:30:59 2003
@@ -176,7 +176,7 @@
 void
 udbg_printSP(const char *s)
 {
-	if (naca->platform == PLATFORM_PSERIES) {
+	if (systemcfg->platform == PLATFORM_PSERIES) {
 		unsigned long sp;
 		asm("mr %0,1" : "=r" (sp) :);
 		if (s)
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c	Sun Feb 16 18:27:44 2003
+++ b/arch/ppc64/kernel/xics.c	Wed Apr 23 23:53:25 2003
@@ -1,5 +1,5 @@
 /* 
- * arch/ppc/kernel/xics.c
+ * arch/ppc64/kernel/xics.c
  *
  * Copyright 2000 IBM Corporation.
  *
@@ -22,10 +22,11 @@
 #include <asm/smp.h>
 #include <asm/naca.h>
 #include <asm/rtas.h>
-#include "i8259.h"
 #include <asm/xics.h>
 #include <asm/ppcdebug.h>
-#include <asm/machdep.h>
+#include <asm/hvcall.h>
+
+#include "i8259.h"
 
 void xics_enable_irq(u_int irq);
 void xics_disable_irq(u_int irq);
@@ -61,33 +62,39 @@
 /* Want a priority other than 0.  Various HW issues require this. */
 #define	DEFAULT_PRIORITY	5
 
+/* 
+ * Mark IPIs as higher priority so we can take them inside interrupts that
+ * arent marked SA_INTERRUPT
+ */
+#define IPI_PRIORITY		4
+
 struct xics_ipl {
 	union {
-		u32	word;
-		u8	bytes[4];
+		u32 word;
+		u8 bytes[4];
 	} xirr_poll;
 	union {
 		u32 word;
-		u8	bytes[4];
+		u8 bytes[4];
 	} xirr;
-	u32	dummy;
+	u32 dummy;
 	union {
-		u32	word;
-		u8	bytes[4];
+		u32 word;
+		u8 bytes[4];
 	} qirr;
 };
 
-struct xics_info {
-	volatile struct xics_ipl *	per_cpu[NR_CPUS];
-};
+static struct xics_ipl *xics_per_cpu[NR_CPUS];
 
-struct xics_info	xics_info;
+static int xics_irq_8259_cascade = 0;
+static int xics_irq_8259_cascade_real = 0;
+static unsigned int default_server = 0xFF;
+static unsigned int default_distrib_server = 0;
 
-unsigned long long intr_base = 0;
-int xics_irq_8259_cascade = 0;
-int xics_irq_8259_cascade_real = 0;
-unsigned int default_server = 0xFF;
-unsigned int default_distrib_server = 0;
+/*
+ * XICS only has a single IPI, so encode the messages per CPU
+ */
+struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
 
 /* RTAS service tokens */
 int ibm_get_xive;
@@ -95,11 +102,6 @@
 int ibm_int_on;
 int ibm_int_off;
 
-struct xics_interrupt_node {
-	unsigned long long addr;
-	unsigned long long size;
-} inodes[NR_CPUS*2];	 
-
 typedef struct {
 	int (*xirr_info_get)(int cpu);
 	void (*xirr_info_set)(int cpu, int val);
@@ -108,24 +110,26 @@
 } xics_ops;
 
 
+/* SMP */
+
 static int pSeries_xirr_info_get(int n_cpu)
 {
-	return (xics_info.per_cpu[n_cpu]->xirr.word);
+	return xics_per_cpu[n_cpu]->xirr.word;
 }
 
 static void pSeries_xirr_info_set(int n_cpu, int value)
 {
-	xics_info.per_cpu[n_cpu]->xirr.word = value;
+	xics_per_cpu[n_cpu]->xirr.word = value;
 }
 
 static void pSeries_cppr_info(int n_cpu, u8 value)
 {
-	xics_info.per_cpu[n_cpu]->xirr.bytes[0] = value;
+	xics_per_cpu[n_cpu]->xirr.bytes[0] = value;
 }
 
-static void pSeries_qirr_info(int n_cpu , u8 value)
+static void pSeries_qirr_info(int n_cpu, u8 value)
 {
-	xics_info.per_cpu[n_cpu]->qirr.bytes[0] = value;
+	xics_per_cpu[n_cpu]->qirr.bytes[0] = value;
 }
 
 static xics_ops pSeries_ops = {
@@ -136,113 +140,174 @@
 };
 
 static xics_ops *ops = &pSeries_ops;
-extern xics_ops pSeriesLP_ops;
 
 
-void
-xics_enable_irq(
-	u_int	virq
-	)
+/* LPAR */
+
+static inline long plpar_eoi(unsigned long xirr)
 {
-	u_int		irq;
-	unsigned long	status;
-	long	        call_status;
+	return plpar_hcall_norets(H_EOI, xirr);
+}
+
+static inline long plpar_cppr(unsigned long cppr)
+{
+	return plpar_hcall_norets(H_CPPR, cppr);
+}
+
+static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
+{
+	return plpar_hcall_norets(H_IPI, servernum, mfrr);
+}
+
+static inline long plpar_xirr(unsigned long *xirr_ret)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
+}
+
+static int pSeriesLP_xirr_info_get(int n_cpu)
+{
+	unsigned long lpar_rc;
+	unsigned long return_value; 
+
+	lpar_rc = plpar_xirr(&return_value);
+	if (lpar_rc != H_Success)
+		panic(" bad return code xirr - rc = %lx \n", lpar_rc); 
+	return (int)return_value;
+}
+
+static void pSeriesLP_xirr_info_set(int n_cpu, int value)
+{
+	unsigned long lpar_rc;
+	unsigned long val64 = value & 0xffffffff;
+
+	lpar_rc = plpar_eoi(val64);
+	if (lpar_rc != H_Success)
+		panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
+		      val64); 
+}
+
+static void pSeriesLP_cppr_info(int n_cpu, u8 value)
+{
+	unsigned long lpar_rc;
+
+	lpar_rc = plpar_cppr(value);
+	if (lpar_rc != H_Success)
+		panic("bad return code cppr - rc = %lx\n", lpar_rc); 
+}
+
+static void pSeriesLP_qirr_info(int n_cpu , u8 value)
+{
+	unsigned long lpar_rc;
+
+	lpar_rc = plpar_ipi(n_cpu, value);
+	if (lpar_rc != H_Success)
+		panic("bad return code qirr - rc = %lx\n", lpar_rc); 
+}
+
+xics_ops pSeriesLP_ops = {
+	pSeriesLP_xirr_info_get,
+	pSeriesLP_xirr_info_set,
+	pSeriesLP_cppr_info,
+	pSeriesLP_qirr_info
+};
+
+void xics_enable_irq(u_int virq)
+{
+	u_int irq;
+	long call_status;
+	unsigned int server;
 
 	virq -= XICS_IRQ_OFFSET;
 	irq = virt_irq_to_real(virq);
 	if (irq == XICS_IPI)
 		return;
+
 #ifdef CONFIG_IRQ_ALL_CPUS
-	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
-				irq, smp_threads_ready ? default_distrib_server : default_server, DEFAULT_PRIORITY);
+	if (smp_threads_ready)
+		server = default_distrib_server;
+	else
+		server = default_server;
 #else
-	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
-				irq, default_server, DEFAULT_PRIORITY);
+	server = default_server;
 #endif
-	if( call_status != 0 ) {
-		printk("xics_enable_irq: irq=%x: rtas_call failed; retn=%lx, status=%lx\n",
-		       irq, call_status, status);
+
+	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
+				DEFAULT_PRIORITY);
+	if (call_status != 0) {
+		printk("xics_enable_irq: irq=%x: ibm_set_xive returned %lx\n",
+		       irq, call_status);
 		return;
 	}
+
 	/* Now unmask the interrupt (often a no-op) */
-	call_status = rtas_call(ibm_int_on, 1, 1, (unsigned long*)&status, 
-				irq);
-	if( call_status != 0 ) {
-		printk("xics_disable_irq on: irq=%x: rtas_call failed, retn=%lx\n",
+	call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
+	if (call_status != 0) {
+		printk("xics_enable_irq: irq=%x: ibm_int_on returned %lx\n",
 		       irq, call_status);
 		return;
 	}
 }
 
-void
-xics_disable_irq(
-	u_int	virq
-	)
-{
-	u_int		irq;
-	unsigned long 	status;
-	long 	        call_status;
+void xics_disable_irq(u_int virq)
+{
+	u_int irq;
+	long call_status;
 
 	virq -= XICS_IRQ_OFFSET;
 	irq = virt_irq_to_real(virq);
-	call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, 
-				irq);
-	if( call_status != 0 ) {
-		printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n",
+	if (irq == XICS_IPI)
+		return;
+
+	call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
+	if (call_status != 0) {
+		printk("xics_disable_irq: irq=%x: ibm_int_off returned %lx\n",
 		       irq, call_status);
 		return;
 	}
 }
 
-void
-xics_end_irq(
-	u_int	irq
-	)
+void xics_end_irq(u_int	irq)
 {
 	int cpu = smp_processor_id();
 
-	ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */
-	iosync();
-	ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
 	iosync();
+	ops->xirr_info_set(cpu, ((0xff<<24) |
+				 (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
 }
 
-void
-xics_mask_and_ack_irq(u_int	irq)
+void xics_mask_and_ack_irq(u_int irq)
 {
 	int cpu = smp_processor_id();
 
-	if( irq < XICS_IRQ_OFFSET ) {
+	if (irq < XICS_IRQ_OFFSET) {
 		i8259_pic.ack(irq);
 		iosync();
-		ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real));
-		iosync();
-	}
-	else {
-		ops->cppr_info(cpu, 0xff);
+		ops->xirr_info_set(cpu, ((0xff<<24) |
+					 xics_irq_8259_cascade_real));
 		iosync();
 	}
 }
 
-int
-xics_get_irq(struct pt_regs *regs)
+int xics_get_irq(struct pt_regs *regs)
 {
-	u_int	cpu = smp_processor_id();
-	u_int	vec;
+	u_int cpu = smp_processor_id();
+	u_int vec;
 	int irq;
 
 	vec = ops->xirr_info_get(cpu);
 	/*  (vec >> 24) == old priority */
 	vec &= 0x00ffffff;
+
 	/* for sanity, this had better be < NR_IRQS - 16 */
-	if( vec == xics_irq_8259_cascade_real ) {
+	if (vec == xics_irq_8259_cascade_real) {
 		irq = i8259_irq(cpu);
-		if(irq == -1) {
+		if (irq == -1) {
 			/* Spurious cascaded interrupt.  Still must ack xics */
                         xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade);
 			irq = -1;
 		}
-	} else if( vec == XICS_IRQ_SPURIOUS ) {
+	} else if (vec == XICS_IRQ_SPURIOUS) {
 		irq = -1;
 	} else {
 		irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET;
@@ -250,45 +315,49 @@
 	return irq;
 }
 
-struct xics_ipi_struct {
-	volatile unsigned long value;
-} ____cacheline_aligned;
+#ifdef CONFIG_SMP
 
 extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
 
-#ifdef CONFIG_SMP
-void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
+	int handled = 0;
 
 	ops->qirr_info(cpu, 0xff);
 	while (xics_ipi_message[cpu].value) {
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, &xics_ipi_message[cpu].value)) {
+		handled = 1;
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
+				       &xics_ipi_message[cpu].value)) {
 			mb();
 			smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
 		}
-		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
+				       &xics_ipi_message[cpu].value)) {
 			mb();
 			smp_message_recv(PPC_MSG_RESCHEDULE, regs);
 		}
 #if 0
-		if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK, &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
+				       &xics_ipi_message[cpu].value)) {
 			mb();
 			smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
 		}
 #endif
 #ifdef CONFIG_XMON
-		if (test_and_clear_bit(PPC_MSG_XMON_BREAK, &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_XMON_BREAK,
+				       &xics_ipi_message[cpu].value)) {
 			mb();
 			smp_message_recv(PPC_MSG_XMON_BREAK, regs);
 		}
 #endif
 	}
+	return IRQ_RETVAL(handled);
 }
 
 void xics_cause_IPI(int cpu)
 {
-	ops->qirr_info(cpu,0) ;
+	ops->qirr_info(cpu, IPI_PRIORITY);
 }
 
 void xics_setup_cpu(void)
@@ -298,15 +367,20 @@
 	ops->cppr_info(cpu, 0xff);
 	iosync();
 }
+
 #endif /* CONFIG_SMP */
 
-void
-xics_init_IRQ( void )
+void xics_init_IRQ(void)
 {
 	int i;
 	unsigned long intr_size = 0;
 	struct device_node *np;
 	uint *ireg, ilen, indx=0;
+	unsigned long intr_base = 0;
+	struct xics_interrupt_node {
+		unsigned long long addr;
+		unsigned long long size;
+	} inodes[NR_CPUS*2]; 
 
 	ppc64_boot_msg(0x20, "XICS Init");
 
@@ -386,23 +460,24 @@
 		xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
 	}
 
-	if (naca->platform == PLATFORM_PSERIES) {
+	if (systemcfg->platform == PLATFORM_PSERIES) {
 #ifdef CONFIG_SMP
 		for (i = 0; i < NR_CPUS; ++i) {
 			if (!cpu_possible(i))
 				continue;
-			xics_info.per_cpu[i] =
-			  __ioremap((ulong)inodes[i].addr, 
-				  (ulong)inodes[i].size, _PAGE_NO_CACHE);
+			xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr, 
+						    (ulong)inodes[i].size,
+						    _PAGE_NO_CACHE);
 		}
 #else
-		xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE);
+		xics_per_cpu[0] = __ioremap((ulong)intr_base, intr_size,
+					    _PAGE_NO_CACHE);
 #endif /* CONFIG_SMP */
 #ifdef CONFIG_PPC_PSERIES
 	/* actually iSeries does not use any of xics...but it has link dependencies
 	 * for now, except this new one...
 	 */
-	} else if (naca->platform == PLATFORM_PSERIES_LPAR) {
+	} else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
 		ops = &pSeriesLP_ops;
 #endif
 	}
@@ -417,8 +492,8 @@
 	ops->cppr_info(boot_cpuid, 0xff);
 	iosync();
 	if (xics_irq_8259_cascade != -1) {
-		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
-				0, "8259 cascade", 0))
+		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET,
+				no_action, 0, "8259 cascade", 0))
 			printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
 		i8259_init();
 	}
diff -Nru a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c
--- a/arch/ppc64/mm/fault.c	Wed Jan  8 14:25:43 2003
+++ b/arch/ppc64/mm/fault.c	Wed Apr  9 14:06:53 2003
@@ -75,8 +75,8 @@
 	}
 #endif
 
-	/* On an SLB miss we can only check for a valid exception entry */
-	if (regs->trap == 0x380) {
+	/* On a kernel SLB miss we can only check for a valid exception entry */
+	if (!user_mode(regs) && (regs->trap == 0x380)) {
 		bad_page_fault(regs, address, SIGSEGV);
 		return;
 	}
diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c	Sun Feb 16 20:11:50 2003
+++ b/arch/ppc64/mm/init.c	Thu Apr 24 13:05:36 2003
@@ -69,8 +69,6 @@
 int mem_init_done;
 unsigned long ioremap_bot = IMALLOC_BASE;
 
-static int boot_mapsize;
-
 extern pgd_t swapper_pg_dir[];
 extern char __init_begin, __init_end;
 extern char _start[], _end[];
@@ -454,6 +452,7 @@
 	unsigned long i;
 	unsigned long start, bootmap_pages;
 	unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
+	int boot_mapsize;
 
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
@@ -532,7 +531,7 @@
 	int nid;
 
         for (nid = 0; nid < numnodes; nid++) {
-		if (numa_node_exists[nid]) {
+		if (node_data[nid].node_size != 0) {
 			printk("freeing bootmem node %x\n", nid);
 			totalram_pages +=
 				free_all_bootmem_node(NODE_DATA(nid));
diff -Nru a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
--- a/arch/ppc64/mm/numa.c	Sun Nov  3 23:47:58 2002
+++ b/arch/ppc64/mm/numa.c	Thu Apr 24 13:05:36 2003
@@ -24,11 +24,18 @@
 int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = -1};
 int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] =
 	{ [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = -1};
-int numa_node_exists[MAX_NUMNODES];
+unsigned long numa_cpumask_lookup_table[MAX_NUMNODES];
 
 struct pglist_data node_data[MAX_NUMNODES];
 bootmem_data_t plat_node_bdata[MAX_NUMNODES];
 
+static inline void map_cpu_to_node(int cpu, int node)
+{
+	dbg("cpu %d maps to domain %d\n", cpu, node);
+	numa_cpu_lookup_table[cpu] = node;
+	numa_cpumask_lookup_table[node] |= 1UL << cpu;
+}
+
 static int __init parse_numa_properties(void)
 {
 	struct device_node *cpu;
@@ -88,9 +95,7 @@
 		if (max_domain < numa_domain)
 			max_domain = numa_domain;
 
-		numa_cpu_lookup_table[cpu_nr] = numa_domain;
-
-		dbg("cpu %d maps to domain %d\n", cpu_nr, numa_domain);
+		map_cpu_to_node(cpu_nr, numa_domain);
 	}
 
 	for (memory = find_type_devices("memory"); memory;
@@ -135,7 +140,7 @@
 
 		/* FIXME */
 		if (numa_domain == 0xffff) {
-			dbg("cpu has no numa doman\n");
+			dbg("memory has no numa doman\n");
 			numa_domain = 0;
 		}
 
@@ -145,7 +150,8 @@
 		if (max_domain < numa_domain)
 			max_domain = numa_domain;
 
-		numa_node_exists[numa_domain] = 1;
+		node_data[numa_domain].node_start_pfn = start / PAGE_SIZE;
+		node_data[numa_domain].node_size = size / PAGE_SIZE;
 
 		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
 			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
@@ -176,27 +182,17 @@
 		BUG();
 
 	for (nid = 0; nid < numnodes; nid++) {
-		unsigned long start, end;
 		unsigned long start_paddr, end_paddr;
 		int i;
 		unsigned long bootmem_paddr;
 		unsigned long bootmap_pages;
 
-		if (!numa_node_exists[nid])
+		if (node_data[nid].node_size == 0)
 			continue;
 
-		/* Find start and end of this zone */
-		start = 0;
-		while (numa_memory_lookup_table[start] != nid)
-			start++;
-
-		end = (MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1;
-		while (numa_memory_lookup_table[end] != nid)
-			end--;
-		end++;
-
-		start_paddr = start << MEMORY_INCREMENT_SHIFT;
-		end_paddr = end << MEMORY_INCREMENT_SHIFT;
+		start_paddr = node_data[nid].node_start_pfn * PAGE_SIZE;
+		end_paddr = start_paddr + 
+				(node_data[nid].node_size * PAGE_SIZE);
 
 		dbg("node %d\n", nid);
 		dbg("start_paddr = %lx\n", start_paddr);
@@ -278,7 +274,7 @@
 		unsigned long start_pfn;
 		unsigned long end_pfn;
 
-		if (!numa_node_exists[nid])
+		if (node_data[nid].node_size == 0)
 			continue;
 
 		start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT;
diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
--- a/arch/ppc64/xmon/xmon.c	Sun Mar  9 15:17:38 2003
+++ b/arch/ppc64/xmon/xmon.c	Mon Mar 31 11:43:45 2003
@@ -453,7 +453,7 @@
 	int i;
 	struct bpt *bp;
 
-	if (naca->platform != PLATFORM_PSERIES)
+	if (systemcfg->platform != PLATFORM_PSERIES)
 		return;
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
@@ -469,12 +469,10 @@
 		}
 	}
 
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
-		if (dabr.enabled)
-			set_dabr(dabr.address);
-		if (iabr.enabled)
-			set_iabr(iabr.address);
-	}
+	if (cpu_has_dabr() && dabr.enabled)
+		set_dabr(dabr.address);
+	if (cpu_has_iabr() && iabr.enabled)
+		set_iabr(iabr.address);
 }
 
 static void
@@ -484,12 +482,13 @@
 	struct bpt *bp;
 	unsigned instr;
 
-	if (naca->platform != PLATFORM_PSERIES)
+	if (systemcfg->platform != PLATFORM_PSERIES)
 		return;
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
+
+	if (cpu_has_dabr())
 		set_dabr(0);
+	if (cpu_has_iabr())
 		set_iabr(0);
-	}
 
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
@@ -778,8 +777,8 @@
 	cmd = inchar();
 	switch (cmd) {
 	case 'd':	/* bd - hardware data breakpoint */
-		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
-			printf("Not implemented on POWER4\n");
+		if (cpu_has_dabr()) {
+			printf("Not implemented on this cpu\n");
 			break;
 		}
 		mode = 7;
@@ -798,7 +797,7 @@
 			dabr.address = (dabr.address & ~7) | mode;
 		break;
 	case 'i':	/* bi - hardware instr breakpoint */
-		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+		if (cpu_has_iabr()) {
 			printf("Not implemented on POWER4\n");
 			break;
 		}
diff -Nru a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
--- a/drivers/char/hvc_console.c	Thu Apr 24 03:30:40 2003
+++ b/drivers/char/hvc_console.c	Thu May  1 20:10:05 2003
@@ -227,7 +227,12 @@
 	spin_unlock_irqrestore(&hp->lock, flags);
 }
 
+#if defined (CONFIG_XMON)
 extern unsigned long cpus_in_xmon;
+#else
+unsigned long cpus_in_xmon=0;
+#endif
+
 
 int khvcd(void *unused)
 {
diff -Nru a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
--- a/include/asm-ppc64/io.h	Sat Dec  7 20:23:44 2002
+++ b/include/asm-ppc64/io.h	Sun Apr 27 14:32:15 2003
@@ -107,7 +107,6 @@
 
 
 #define IO_SPACE_LIMIT ~(0UL)
-#define MEM_SPACE_LIMIT ~(0UL)
 
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
--- a/include/asm-ppc64/mmu.h	Fri Sep 13 04:19:46 2002
+++ b/include/asm-ppc64/mmu.h	Tue Mar 25 20:30:59 2003
@@ -221,6 +221,13 @@
 
 #endif /* __ASSEMBLY__ */
 
+/*
+ * Location of cpu0's segment table
+ */
+#define STAB0_PAGE	0x9
+#define STAB0_PHYS_ADDR	(STAB0_PAGE<<PAGE_SHIFT)
+#define STAB0_VIRT_ADDR	(KERNELBASE+STAB0_PHYS_ADDR)
+
 /* Block size masks */
 #define BL_128K	0x000
 #define BL_256K 0x001
diff -Nru a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
--- a/include/asm-ppc64/mmzone.h	Wed Sep 25 17:40:59 2002
+++ b/include/asm-ppc64/mmzone.h	Thu Apr 24 13:05:36 2003
@@ -18,9 +18,9 @@
  * Following are specific to this numa platform.
  */
 
-extern int numa_node_exists[];
 extern int numa_cpu_lookup_table[];
 extern int numa_memory_lookup_table[];
+extern unsigned long numa_cpumask_lookup_table[];
 
 #define MAX_MEMORY (1UL << 41)
 /* 256MB regions */
diff -Nru a/include/asm-ppc64/module.h b/include/asm-ppc64/module.h
--- a/include/asm-ppc64/module.h	Tue Jan 14 00:46:13 2003
+++ b/include/asm-ppc64/module.h	Thu Apr 24 09:29:49 2003
@@ -19,4 +19,8 @@
 asm(".section .stubs,\"ax\",@nobits; .align 3; .previous");
 #endif
 
+struct exception_table_entry;
+void sort_ex_table(struct exception_table_entry *start,
+			struct exception_table_entry *finish);
+
 #endif /* _ASM_PPC64_MODULE_H */
diff -Nru a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h
--- a/include/asm-ppc64/naca.h	Thu Jun 20 16:29:14 2002
+++ b/include/asm-ppc64/naca.h	Tue Mar 25 20:30:59 2003
@@ -11,29 +11,41 @@
  */
 
 #include <asm/types.h>
+#include <asm/systemcfg.h>
+
+#ifndef __ASSEMBLY__
 
 struct naca_struct {
-	void *xItVpdAreas;
-	void *xRamDisk;
-	u64 xRamDiskSize;		/* In pages */
-	struct paca_struct *paca;	/* Ptr to an array of pacas */
-	u64 debug_switch;		/* Bits to control debug printing */
-	u16 dCacheL1LineSize;		/* Line size of L1 DCache in bytes */
-	u16 dCacheL1LogLineSize;	/* Log-2 of DCache line size */
-	u16 dCacheL1LinesPerPage;	/* DCache lines per page */
-	u16 iCacheL1LineSize;		/* Line size of L1 ICache in bytes */
-	u16 iCacheL1LogLineSize;	/* Log-2 of ICache line size */
-	u16 iCacheL1LinesPerPage;	/* ICache lines per page */
-	u16 slb_size;			/* SLB size in entries */
-	u64 physicalMemorySize;		/* Size of real memory in bytes */
-	u64 pftSize;			/* Log base 2 of page table size */
-	u64 serialPortAddr;		/* Phyical address of serial port */
-	u8 interrupt_controller;	/* Type of interrupt controller */ 
-	u8 resv0;    			/* Type of interrupt controller */
-	u16 platform;			/* Platform flags */
-	u8 resv1[12];			/* Padding */
+	/*==================================================================
+	 * Cache line 1: 0x0000 - 0x007F
+	 * Kernel only data - undefined for user space
+	 *==================================================================
+	 */
+	void *xItVpdAreas;              /* VPD Data                  0x00 */
+	void *xRamDisk;                 /* iSeries ramdisk           0x08 */
+	u64   xRamDiskSize;		/* In pages                  0x10 */
+	struct paca_struct *paca;	/* Ptr to an array of pacas  0x18 */
+	u64 debug_switch;		/* Debug print control       0x20 */
+	u64 banner;                     /* Ptr to banner string      0x28 */
+	u64 log;                        /* Ptr to log buffer         0x30 */
+	u64 serialPortAddr;		/* Phy addr of serial port   0x38 */
+	u64 interrupt_controller;	/* Type of int controller    0x40 */ 
+	u64 slb_size;			/* SLB size in entries       0x48 */
+	u64 pftSize;			/* Log 2 of page table size  0x50 */
+	void *systemcfg;		/* Pointer to systemcfg data 0x58 */
+	u32 dCacheL1LogLineSize;	/* L1 d-cache line size Log2 0x60 */
+	u32 dCacheL1LinesPerPage;	/* L1 d-cache lines / page   0x64 */
+	u32 iCacheL1LogLineSize;	/* L1 i-cache line size Log2 0x68 */
+	u32 iCacheL1LinesPerPage;	/* L1 i-cache lines / page   0x6c */
+	u64 resv0[2];                   /* Reserved           0x70 - 0x7F */
 };
 
 extern struct naca_struct *naca;
+
+#endif /* __ASSEMBLY__ */
+
+#define NACA_PAGE      0x4
+#define NACA_PHYS_ADDR (NACA_PAGE<<PAGE_SHIFT)
+#define NACA_VIRT_ADDR (KERNELBASE+NACA_PHYS_ADDR)
 
 #endif /* _NACA_H */
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	Tue Feb 25 09:57:19 2003
+++ b/include/asm-ppc64/page.h	Tue Mar 25 20:30:59 2003
@@ -14,7 +14,11 @@
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT	12
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#ifndef __ASSEMBLY__
+# define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#else
+# define PAGE_SIZE	(1 << PAGE_SHIFT)
+#endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 #define PAGE_OFFSET_MASK (PAGE_SIZE-1)
 
@@ -22,6 +26,19 @@
 #define SID_MASK        0xfffffffff
 #define GET_ESID(x)     (((x) >> SID_SHIFT) & SID_MASK)
 
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
+
+/* to align the pointer to the (next) double word boundary */
+#define DOUBLEWORD_ALIGN(addr)	_ALIGN(addr,sizeof(unsigned long))
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
+
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 #include <asm/naca.h>
@@ -37,7 +54,7 @@
 {
 	unsigned long lines, line_size;
 
-	line_size = naca->dCacheL1LineSize; 
+	line_size = systemcfg->dCacheL1LineSize; 
 	lines = naca->dCacheL1LinesPerPage;
 
 	__asm__ __volatile__(
@@ -113,19 +130,6 @@
 #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
 
 #endif /* __ASSEMBLY__ */
-
-/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
-
-/* align addr on a size boundary - adjust address up if needed */
-#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
-
-/* to align the pointer to the (next) double word boundary */
-#define DOUBLEWORD_ALIGN(addr)	_ALIGN(addr,sizeof(unsigned long))
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
 
 #ifdef MODULE
 #define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
diff -Nru a/include/asm-ppc64/proc_fs.h b/include/asm-ppc64/proc_fs.h
--- a/include/asm-ppc64/proc_fs.h	Thu Feb 14 04:14:36 2002
+++ b/include/asm-ppc64/proc_fs.h	Tue Mar 25 20:30:59 2003
@@ -25,9 +25,14 @@
 
 #include <linux/proc_fs.h>
 
-void pmc_proc_init(struct proc_dir_entry *iSeries_proc);
-void proc_ppc64_init(void);
+struct proc_ppc64_t {
+	struct proc_dir_entry *root;
+	struct proc_dir_entry *naca;
+	struct proc_dir_entry *paca;
+	struct proc_dir_entry *systemcfg;
+	struct proc_dir_entry *rtas;
+};
 
-#include <asm/iSeries/iSeries_proc.h>
+extern struct proc_ppc64_t proc_ppc64;
 
-#endif
+#endif /* _PPC64_PROC_FS_H */
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	Mon Mar 10 10:20:31 2003
+++ b/include/asm-ppc64/processor.h	Mon Mar 31 11:43:45 2003
@@ -469,8 +469,6 @@
 #define	  IOCR_SPC	0x00000001
 
 
-/* Processor Version Register */
-
 /* Processor Version Register (PVR) field extraction */
 
 #define	PVR_VER(pvr)  (((pvr) >>  16) & 0xFFFF)	/* Version field */
@@ -595,6 +593,8 @@
 			asm volatile("mfasr %0" : "=r" (rval)); rval;})
 
 #ifndef __ASSEMBLY__
+extern unsigned long *_get_SP(void);
+
 extern int have_of;
 
 struct task_struct;
@@ -654,8 +654,10 @@
 	struct pt_regs	*regs;		/* Pointer to saved register state */
 	mm_segment_t	fs;		/* for get_fs() validation */
 	double		fpr[32];	/* Complete floating point set */
-	unsigned long	fpscr;		/* Floating point status */
-	unsigned int	fpexc_mode;	/* Floating-point exception mode */
+	unsigned long	fpscr;		/* Floating point status (plus pad) */
+	unsigned long	fpexc_mode;	/* Floating-point exception mode */
+	unsigned long	saved_msr;	/* Save MSR across signal handlers */
+	unsigned long	saved_softe;	/* Ditto for Soft Enable/Disable */
 };
 
 #define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
@@ -702,7 +704,7 @@
 	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
 }
 
-static inline unsigned int __pack_fe01(unsigned int fpmode)
+static inline unsigned long __pack_fe01(unsigned int fpmode)
 {
 	return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
 }
@@ -739,6 +741,15 @@
 
 #define cpu_has_noexecute()	(processor_type() == PV_POWER4 || \
 				 processor_type() == PV_POWER4p)
+
+/* XXX we have to call HV to set when in LPAR */
+#define cpu_has_dabr()		(1)
+
+#define cpu_has_iabr()		(processor_type() != PV_POWER4 && \
+				 processor_type() != PV_POWER4p)
+
+#define cpu_alignexc_sets_dsisr() (processor_type() != PV_POWER4 && \
+				 processor_type() != PV_POWER4p)
 
 #endif /* ASSEMBLY */
 
diff -Nru a/include/asm-ppc64/ptrace.h b/include/asm-ppc64/ptrace.h
--- a/include/asm-ppc64/ptrace.h	Thu Feb 14 04:14:36 2002
+++ b/include/asm-ppc64/ptrace.h	Tue Mar 25 19:38:55 2003
@@ -64,9 +64,8 @@
 
 #define STACK_FRAME_OVERHEAD	112	/* size of minimum stack frame */
 
-/* Size of stack frame allocated when calling signal handler. */
-/* FIXME: What should this be on 64-bit kernel (64 for 32-bit) */
-#define __SIGNAL_FRAMESIZE	64
+/* Size of dummy stack frame allocated when calling signal handler. */
+#define __SIGNAL_FRAMESIZE	128
 #define __SIGNAL_FRAMESIZE32	64
 
 #define instruction_pointer(regs) ((regs)->nip)
diff -Nru a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
--- a/include/asm-ppc64/rtas.h	Thu Feb 13 00:47:26 2003
+++ b/include/asm-ppc64/rtas.h	Tue Mar 25 20:30:59 2003
@@ -166,8 +166,6 @@
 extern void rtas_power_off(void);
 extern void rtas_halt(void);
 
-extern struct proc_dir_entry *rtas_proc_dir;
-
 /* Some RTAS ops require a data buffer and that buffer must be < 4G.
  * Rather than having a memory allocator, just use this buffer
  * (get the lock first), make the RTAS call.  Copy the data instead
diff -Nru a/include/asm-ppc64/sigcontext.h b/include/asm-ppc64/sigcontext.h
--- a/include/asm-ppc64/sigcontext.h	Mon Oct  7 23:57:08 2002
+++ b/include/asm-ppc64/sigcontext.h	Tue Mar 25 19:38:55 2003
@@ -9,6 +9,8 @@
  */
 
 #include <asm/ptrace.h>
+#include <asm/elf.h>
+
 
 struct sigcontext {
 	unsigned long	_unused[4];
@@ -16,7 +18,9 @@
 	int		_pad0;
 	unsigned long	handler;
 	unsigned long	oldmask;
-	struct pt_regs 	*regs;
+	struct pt_regs	*regs;
+	elf_gregset_t	gp_regs;
+	elf_fpregset_t	fp_regs;
 };
 
 #endif /* _ASM_PPC64_SIGCONTEXT_H */
diff -Nru a/include/asm-ppc64/systemcfg.h b/include/asm-ppc64/systemcfg.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/systemcfg.h	Tue Mar 25 20:31:00 2003
@@ -0,0 +1,109 @@
+#ifndef _SYSTEMCFG_H
+#define _SYSTEMCFG_H
+
+/* 
+ * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Change Activity:
+ * 2002/09/30 : bergner  : Created
+ * End Change Activity 
+ */
+
+
+#ifndef __KERNEL__
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <linux/types.h>
+#endif
+
+/*
+ * If the major version changes we are incompatible.
+ * Minor version changes are a hint.
+ */
+#define SYSTEMCFG_MAJOR 1
+#define SYSTEMCFG_MINOR 0
+
+#ifndef __ASSEMBLY__
+
+struct systemcfg {
+	__u8  eye_catcher[16];		/* Eyecatcher: SYSTEMCFG:PPC64	0x00 */
+	struct {			/* Systemcfg version numbers	     */
+		__u32 major;		/* Major number			0x10 */
+		__u32 minor;		/* Minor number			0x14 */
+	} version;
+
+	__u32 platform;			/* Platform flags		0x18 */
+	__u32 processor;		/* Processor type		0x1C */
+	__u64 processorCount;		/* # of physical processors	0x20 */
+	__u64 physicalMemorySize;	/* Size of real memory(B)	0x28 */
+	__u64 tb_orig_stamp;		/* Timebase at boot		0x30 */
+	__u64 tb_ticks_per_sec;		/* Timebase tics / sec		0x38 */
+	__u64 tb_to_xs;			/* Inverse of TB to 2^20	0x40 */
+	__u64 stamp_xsec;		/*				0x48 */
+	__u64 tb_update_count;		/* Timebase atomicity ctr	0x50 */
+	__u32 tz_minuteswest;		/* Minutes west of Greenwich	0x58 */
+	__u32 tz_dsttime;		/* Type of dst correction	0x5C */
+	__u32 dCacheL1Size;		/* L1 d-cache size		0x60 */
+	__u32 dCacheL1LineSize;		/* L1 d-cache line size		0x64 */
+	__u32 iCacheL1Size;		/* L1 i-cache size		0x68 */
+	__u32 iCacheL1LineSize;		/* L1 i-cache line size		0x6C */
+	__u8  reserved0[3984];		/* Reserve rest of page		0x70 */
+};
+
+#ifdef __KERNEL__
+extern struct systemcfg *systemcfg;
+#else
+
+/* Processor Version Register (PVR) field extraction */
+#define PVR_VER(pvr)  (((pvr) >>  16) & 0xFFFF) /* Version field */
+#define PVR_REV(pvr)  (((pvr) >>   0) & 0xFFFF) /* Revison field */
+
+/* Processor Version Numbers */
+#define PV_NORTHSTAR    0x0033
+#define PV_PULSAR       0x0034
+#define PV_POWER4       0x0035
+#define PV_ICESTAR      0x0036
+#define PV_SSTAR        0x0037
+#define PV_POWER4p      0x0038
+#define PV_630          0x0040
+#define PV_630p         0x0041
+
+/* Platforms supported by PPC64 */
+#define PLATFORM_PSERIES      0x0100
+#define PLATFORM_PSERIES_LPAR 0x0101
+#define PLATFORM_ISERIES_LPAR 0x0201
+
+
+static inline volatile struct systemcfg *systemcfg_init(void)
+{
+	int fd = open("/proc/ppc64/systemcfg", O_RDONLY);
+	volatile struct systemcfg *ret;
+
+	if (fd == -1)
+		return 0;
+	ret = mmap(0, sizeof(struct systemcfg), PROT_READ, MAP_SHARED, fd, 0);
+	close(fd);
+	if (!ret)
+		return 0;
+	if (ret->version.major != SYSTEMCFG_MAJOR || ret->version.minor < SYSTEMCFG_MINOR) {
+		munmap((void *)ret, sizeof(struct systemcfg));
+		return 0;
+	}
+	return ret;
+}
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#define SYSTEMCFG_PAGE      0x5
+#define SYSTEMCFG_PHYS_ADDR (SYSTEMCFG_PAGE<<PAGE_SHIFT)
+#define SYSTEMCFG_VIRT_ADDR (KERNELBASE+SYSTEMCFG_PHYS_ADDR)
+
+#endif /* _SYSTEMCFG_H */
diff -Nru a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h	Wed Mar 12 15:19:15 2003
+++ b/include/asm-ppc64/topology.h	Thu Apr 24 13:05:36 2003
@@ -20,32 +20,23 @@
 	return node;
 }
 
-static inline int node_to_first_cpu(int node)
-{
-	int cpu;
+#define memblk_to_node(memblk)	(memblk)
 
-	for(cpu = 0; cpu < NR_CPUS; cpu++)
-		if (numa_cpu_lookup_table[cpu] == node)
-			return cpu;
-
-	BUG(); /* couldn't find a cpu on given node */
-	return -1;
-}
+#define parent_node(node)	(node)
 
 static inline unsigned long node_to_cpumask(int node)
 {
-	int cpu;
-	unsigned long mask = 0UL;
+	return numa_cpumask_lookup_table[node];
+}
 
-	if (sizeof(unsigned long) * 8 < NR_CPUS)
-		BUG();
+static inline int node_to_first_cpu(int node)
+{
+	return __ffs(node_to_cpumask(node));
+}
 
-	for(cpu = 0; cpu < NR_CPUS; cpu++)
-		if (numa_cpu_lookup_table[cpu] == node)
-			mask |= 1UL << cpu;
+#define node_to_memblk(node)	(node)
 
-	return mask;
-}
+#define pcibus_to_cpumask(bus)	(cpu_online_map)
 
 /* Cross-node load balancing interval. */
 #define NODE_BALANCE_RATE 10
diff -Nru a/include/asm-ppc64/types.h b/include/asm-ppc64/types.h
--- a/include/asm-ppc64/types.h	Mon Dec 30 20:14:21 2002
+++ b/include/asm-ppc64/types.h	Tue Mar 25 19:38:55 2003
@@ -66,6 +66,11 @@
 typedef u32 dma_addr_t;
 typedef u64 dma64_addr_t;
 
+typedef struct {
+	unsigned long entry;
+	unsigned long toc;
+	unsigned long env;
+} func_descr_t;
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc64/ucontext.h b/include/asm-ppc64/ucontext.h
--- a/include/asm-ppc64/ucontext.h	Wed Sep 25 07:02:10 2002
+++ b/include/asm-ppc64/ucontext.h	Tue Mar 25 19:38:55 2003
@@ -1,8 +1,9 @@
 #ifndef _ASMPPC64_UCONTEXT_H
 #define _ASMPPC64_UCONTEXT_H
 
-/* Copied from i386. 
- *
+#include <asm/sigcontext.h>
+
+/*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
@@ -13,8 +14,9 @@
 	unsigned long	  uc_flags;
 	struct ucontext  *uc_link;
 	stack_t		  uc_stack;
-	struct sigcontext uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+	sigset_t	  uc_sigmask;
+	sigset_t	  __unsued[15];	/* Allow for uc_sigmask growth */
+	struct sigcontext uc_mcontext;  /* last for extensibility */
 };
 
 #endif /* _ASMPPC64_UCONTEXT_H */
diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h	Sat Feb 22 00:17:10 2003
+++ b/include/asm-ppc64/unistd.h	Fri Mar 28 10:58:33 2003
@@ -260,7 +260,7 @@
 #define __NR_clock_getres	247
 #define __NR_clock_nanosleep	248
 
-#define __NR_syscalls		249
+#define __NR_syscalls		239
 #ifdef __KERNEL__
 #define NR_syscalls	__NR_syscalls
 #endif
diff -Nru a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
--- a/include/asm-ppc64/xics.h	Sun Dec 15 17:18:19 2002
+++ b/include/asm-ppc64/xics.h	Thu Mar 27 22:31:06 2003
@@ -12,7 +12,17 @@
 #ifndef _PPC64_KERNEL_XICS_H
 #define _PPC64_KERNEL_XICS_H
 
+#include <linux/cache.h>
+
 void xics_init_IRQ(void);
 int xics_get_irq(struct pt_regs *);
+void xics_setup_cpu(void);
+void xics_cause_IPI(int cpu);
+
+struct xics_ipi_struct {
+	volatile unsigned long value;
+} ____cacheline_aligned;
+
+extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
 
 #endif /* _PPC64_KERNEL_XICS_H */
