v4.19.13 snapshot.
diff --git a/arch/parisc/kernel/.gitignore b/arch/parisc/kernel/.gitignore
new file mode 100644
index 0000000..c5f676c
--- /dev/null
+++ b/arch/parisc/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
new file mode 100644
index 0000000..e5de34d
--- /dev/null
+++ b/arch/parisc/kernel/Makefile
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for arch/parisc/kernel
+#
+
+extra-y			:= head.o vmlinux.lds
+
+obj-y	     	:= cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
+		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
+		   ptrace.o hardware.o inventory.o drivers.o \
+		   signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
+		   process.o processor.o pdc_cons.o pdc_chassis.o unwind.o
+
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_cache.o = -pg
+CFLAGS_REMOVE_perf.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
+endif
+
+obj-$(CONFIG_SMP)	+= smp.o
+obj-$(CONFIG_PA11)	+= pci-dma.o
+obj-$(CONFIG_PCI)	+= pci.o
+obj-$(CONFIG_MODULES)	+= module.o
+obj-$(CONFIG_64BIT)	+= sys_parisc32.o signal32.o
+obj-$(CONFIG_STACKTRACE)+= stacktrace.o
+obj-$(CONFIG_AUDIT)	+= audit.o
+obj64-$(CONFIG_AUDIT)	+= compat_audit.o
+# only supported for PCX-W/U in 64-bit mode at the moment
+obj-$(CONFIG_64BIT)	+= perf.o perf_asm.o $(obj64-y)
+obj-$(CONFIG_PARISC_CPU_TOPOLOGY)	+= topology.o
+obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
new file mode 100644
index 0000000..dfff8a0
--- /dev/null
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -0,0 +1,304 @@
+/* 
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ *
+ *    Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000 Sam Creasey <sammy@sammy.net>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001 Richard Hirst <rhirst at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
+ *
+ *    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
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/thread_info.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/kbuild.h>
+
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/pdc.h>
+#include <linux/uaccess.h>
+
+#ifdef CONFIG_64BIT
+#define FRAME_SIZE	128
+#else
+#define FRAME_SIZE	64
+#endif
+#define FRAME_ALIGN	64
+
+/* Add FRAME_SIZE to the size x and align it to y. All definitions
+ * that use align_frame will include space for a frame.
+ */
+#define align_frame(x,y) (((x)+FRAME_SIZE+(y)-1) - (((x)+(y)-1)%(y)))
+
+int main(void)
+{
+	DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
+	DEFINE(TASK_PID, offsetof(struct task_struct, pid));
+	BLANK();
+	DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
+	DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
+	DEFINE(TASK_PT_GR1, offsetof(struct task_struct, thread.regs.gr[ 1]));
+	DEFINE(TASK_PT_GR2, offsetof(struct task_struct, thread.regs.gr[ 2]));
+	DEFINE(TASK_PT_GR3, offsetof(struct task_struct, thread.regs.gr[ 3]));
+	DEFINE(TASK_PT_GR4, offsetof(struct task_struct, thread.regs.gr[ 4]));
+	DEFINE(TASK_PT_GR5, offsetof(struct task_struct, thread.regs.gr[ 5]));
+	DEFINE(TASK_PT_GR6, offsetof(struct task_struct, thread.regs.gr[ 6]));
+	DEFINE(TASK_PT_GR7, offsetof(struct task_struct, thread.regs.gr[ 7]));
+	DEFINE(TASK_PT_GR8, offsetof(struct task_struct, thread.regs.gr[ 8]));
+	DEFINE(TASK_PT_GR9, offsetof(struct task_struct, thread.regs.gr[ 9]));
+	DEFINE(TASK_PT_GR10, offsetof(struct task_struct, thread.regs.gr[10]));
+	DEFINE(TASK_PT_GR11, offsetof(struct task_struct, thread.regs.gr[11]));
+	DEFINE(TASK_PT_GR12, offsetof(struct task_struct, thread.regs.gr[12]));
+	DEFINE(TASK_PT_GR13, offsetof(struct task_struct, thread.regs.gr[13]));
+	DEFINE(TASK_PT_GR14, offsetof(struct task_struct, thread.regs.gr[14]));
+	DEFINE(TASK_PT_GR15, offsetof(struct task_struct, thread.regs.gr[15]));
+	DEFINE(TASK_PT_GR16, offsetof(struct task_struct, thread.regs.gr[16]));
+	DEFINE(TASK_PT_GR17, offsetof(struct task_struct, thread.regs.gr[17]));
+	DEFINE(TASK_PT_GR18, offsetof(struct task_struct, thread.regs.gr[18]));
+	DEFINE(TASK_PT_GR19, offsetof(struct task_struct, thread.regs.gr[19]));
+	DEFINE(TASK_PT_GR20, offsetof(struct task_struct, thread.regs.gr[20]));
+	DEFINE(TASK_PT_GR21, offsetof(struct task_struct, thread.regs.gr[21]));
+	DEFINE(TASK_PT_GR22, offsetof(struct task_struct, thread.regs.gr[22]));
+	DEFINE(TASK_PT_GR23, offsetof(struct task_struct, thread.regs.gr[23]));
+	DEFINE(TASK_PT_GR24, offsetof(struct task_struct, thread.regs.gr[24]));
+	DEFINE(TASK_PT_GR25, offsetof(struct task_struct, thread.regs.gr[25]));
+	DEFINE(TASK_PT_GR26, offsetof(struct task_struct, thread.regs.gr[26]));
+	DEFINE(TASK_PT_GR27, offsetof(struct task_struct, thread.regs.gr[27]));
+	DEFINE(TASK_PT_GR28, offsetof(struct task_struct, thread.regs.gr[28]));
+	DEFINE(TASK_PT_GR29, offsetof(struct task_struct, thread.regs.gr[29]));
+	DEFINE(TASK_PT_GR30, offsetof(struct task_struct, thread.regs.gr[30]));
+	DEFINE(TASK_PT_GR31, offsetof(struct task_struct, thread.regs.gr[31]));
+	DEFINE(TASK_PT_FR0, offsetof(struct task_struct, thread.regs.fr[ 0]));
+	DEFINE(TASK_PT_FR1, offsetof(struct task_struct, thread.regs.fr[ 1]));
+	DEFINE(TASK_PT_FR2, offsetof(struct task_struct, thread.regs.fr[ 2]));
+	DEFINE(TASK_PT_FR3, offsetof(struct task_struct, thread.regs.fr[ 3]));
+	DEFINE(TASK_PT_FR4, offsetof(struct task_struct, thread.regs.fr[ 4]));
+	DEFINE(TASK_PT_FR5, offsetof(struct task_struct, thread.regs.fr[ 5]));
+	DEFINE(TASK_PT_FR6, offsetof(struct task_struct, thread.regs.fr[ 6]));
+	DEFINE(TASK_PT_FR7, offsetof(struct task_struct, thread.regs.fr[ 7]));
+	DEFINE(TASK_PT_FR8, offsetof(struct task_struct, thread.regs.fr[ 8]));
+	DEFINE(TASK_PT_FR9, offsetof(struct task_struct, thread.regs.fr[ 9]));
+	DEFINE(TASK_PT_FR10, offsetof(struct task_struct, thread.regs.fr[10]));
+	DEFINE(TASK_PT_FR11, offsetof(struct task_struct, thread.regs.fr[11]));
+	DEFINE(TASK_PT_FR12, offsetof(struct task_struct, thread.regs.fr[12]));
+	DEFINE(TASK_PT_FR13, offsetof(struct task_struct, thread.regs.fr[13]));
+	DEFINE(TASK_PT_FR14, offsetof(struct task_struct, thread.regs.fr[14]));
+	DEFINE(TASK_PT_FR15, offsetof(struct task_struct, thread.regs.fr[15]));
+	DEFINE(TASK_PT_FR16, offsetof(struct task_struct, thread.regs.fr[16]));
+	DEFINE(TASK_PT_FR17, offsetof(struct task_struct, thread.regs.fr[17]));
+	DEFINE(TASK_PT_FR18, offsetof(struct task_struct, thread.regs.fr[18]));
+	DEFINE(TASK_PT_FR19, offsetof(struct task_struct, thread.regs.fr[19]));
+	DEFINE(TASK_PT_FR20, offsetof(struct task_struct, thread.regs.fr[20]));
+	DEFINE(TASK_PT_FR21, offsetof(struct task_struct, thread.regs.fr[21]));
+	DEFINE(TASK_PT_FR22, offsetof(struct task_struct, thread.regs.fr[22]));
+	DEFINE(TASK_PT_FR23, offsetof(struct task_struct, thread.regs.fr[23]));
+	DEFINE(TASK_PT_FR24, offsetof(struct task_struct, thread.regs.fr[24]));
+	DEFINE(TASK_PT_FR25, offsetof(struct task_struct, thread.regs.fr[25]));
+	DEFINE(TASK_PT_FR26, offsetof(struct task_struct, thread.regs.fr[26]));
+	DEFINE(TASK_PT_FR27, offsetof(struct task_struct, thread.regs.fr[27]));
+	DEFINE(TASK_PT_FR28, offsetof(struct task_struct, thread.regs.fr[28]));
+	DEFINE(TASK_PT_FR29, offsetof(struct task_struct, thread.regs.fr[29]));
+	DEFINE(TASK_PT_FR30, offsetof(struct task_struct, thread.regs.fr[30]));
+	DEFINE(TASK_PT_FR31, offsetof(struct task_struct, thread.regs.fr[31]));
+	DEFINE(TASK_PT_SR0, offsetof(struct task_struct, thread.regs.sr[ 0]));
+	DEFINE(TASK_PT_SR1, offsetof(struct task_struct, thread.regs.sr[ 1]));
+	DEFINE(TASK_PT_SR2, offsetof(struct task_struct, thread.regs.sr[ 2]));
+	DEFINE(TASK_PT_SR3, offsetof(struct task_struct, thread.regs.sr[ 3]));
+	DEFINE(TASK_PT_SR4, offsetof(struct task_struct, thread.regs.sr[ 4]));
+	DEFINE(TASK_PT_SR5, offsetof(struct task_struct, thread.regs.sr[ 5]));
+	DEFINE(TASK_PT_SR6, offsetof(struct task_struct, thread.regs.sr[ 6]));
+	DEFINE(TASK_PT_SR7, offsetof(struct task_struct, thread.regs.sr[ 7]));
+	DEFINE(TASK_PT_IASQ0, offsetof(struct task_struct, thread.regs.iasq[0]));
+	DEFINE(TASK_PT_IASQ1, offsetof(struct task_struct, thread.regs.iasq[1]));
+	DEFINE(TASK_PT_IAOQ0, offsetof(struct task_struct, thread.regs.iaoq[0]));
+	DEFINE(TASK_PT_IAOQ1, offsetof(struct task_struct, thread.regs.iaoq[1]));
+	DEFINE(TASK_PT_CR27, offsetof(struct task_struct, thread.regs.cr27));
+	DEFINE(TASK_PT_ORIG_R28, offsetof(struct task_struct, thread.regs.orig_r28));
+	DEFINE(TASK_PT_KSP, offsetof(struct task_struct, thread.regs.ksp));
+	DEFINE(TASK_PT_KPC, offsetof(struct task_struct, thread.regs.kpc));
+	DEFINE(TASK_PT_SAR, offsetof(struct task_struct, thread.regs.sar));
+	DEFINE(TASK_PT_IIR, offsetof(struct task_struct, thread.regs.iir));
+	DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr));
+	DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior));
+	BLANK();
+	DEFINE(TASK_SZ, sizeof(struct task_struct));
+	/* TASK_SZ_ALGN includes space for a stack frame. */
+	DEFINE(TASK_SZ_ALGN, align_frame(sizeof(struct task_struct), FRAME_ALIGN));
+	BLANK();
+	DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0]));
+	DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1]));
+	DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2]));
+	DEFINE(PT_GR3, offsetof(struct pt_regs, gr[ 3]));
+	DEFINE(PT_GR4, offsetof(struct pt_regs, gr[ 4]));
+	DEFINE(PT_GR5, offsetof(struct pt_regs, gr[ 5]));
+	DEFINE(PT_GR6, offsetof(struct pt_regs, gr[ 6]));
+	DEFINE(PT_GR7, offsetof(struct pt_regs, gr[ 7]));
+	DEFINE(PT_GR8, offsetof(struct pt_regs, gr[ 8]));
+	DEFINE(PT_GR9, offsetof(struct pt_regs, gr[ 9]));
+	DEFINE(PT_GR10, offsetof(struct pt_regs, gr[10]));
+	DEFINE(PT_GR11, offsetof(struct pt_regs, gr[11]));
+	DEFINE(PT_GR12, offsetof(struct pt_regs, gr[12]));
+	DEFINE(PT_GR13, offsetof(struct pt_regs, gr[13]));
+	DEFINE(PT_GR14, offsetof(struct pt_regs, gr[14]));
+	DEFINE(PT_GR15, offsetof(struct pt_regs, gr[15]));
+	DEFINE(PT_GR16, offsetof(struct pt_regs, gr[16]));
+	DEFINE(PT_GR17, offsetof(struct pt_regs, gr[17]));
+	DEFINE(PT_GR18, offsetof(struct pt_regs, gr[18]));
+	DEFINE(PT_GR19, offsetof(struct pt_regs, gr[19]));
+	DEFINE(PT_GR20, offsetof(struct pt_regs, gr[20]));
+	DEFINE(PT_GR21, offsetof(struct pt_regs, gr[21]));
+	DEFINE(PT_GR22, offsetof(struct pt_regs, gr[22]));
+	DEFINE(PT_GR23, offsetof(struct pt_regs, gr[23]));
+	DEFINE(PT_GR24, offsetof(struct pt_regs, gr[24]));
+	DEFINE(PT_GR25, offsetof(struct pt_regs, gr[25]));
+	DEFINE(PT_GR26, offsetof(struct pt_regs, gr[26]));
+	DEFINE(PT_GR27, offsetof(struct pt_regs, gr[27]));
+	DEFINE(PT_GR28, offsetof(struct pt_regs, gr[28]));
+	DEFINE(PT_GR29, offsetof(struct pt_regs, gr[29]));
+	DEFINE(PT_GR30, offsetof(struct pt_regs, gr[30]));
+	DEFINE(PT_GR31, offsetof(struct pt_regs, gr[31]));
+	DEFINE(PT_FR0, offsetof(struct pt_regs, fr[ 0]));
+	DEFINE(PT_FR1, offsetof(struct pt_regs, fr[ 1]));
+	DEFINE(PT_FR2, offsetof(struct pt_regs, fr[ 2]));
+	DEFINE(PT_FR3, offsetof(struct pt_regs, fr[ 3]));
+	DEFINE(PT_FR4, offsetof(struct pt_regs, fr[ 4]));
+	DEFINE(PT_FR5, offsetof(struct pt_regs, fr[ 5]));
+	DEFINE(PT_FR6, offsetof(struct pt_regs, fr[ 6]));
+	DEFINE(PT_FR7, offsetof(struct pt_regs, fr[ 7]));
+	DEFINE(PT_FR8, offsetof(struct pt_regs, fr[ 8]));
+	DEFINE(PT_FR9, offsetof(struct pt_regs, fr[ 9]));
+	DEFINE(PT_FR10, offsetof(struct pt_regs, fr[10]));
+	DEFINE(PT_FR11, offsetof(struct pt_regs, fr[11]));
+	DEFINE(PT_FR12, offsetof(struct pt_regs, fr[12]));
+	DEFINE(PT_FR13, offsetof(struct pt_regs, fr[13]));
+	DEFINE(PT_FR14, offsetof(struct pt_regs, fr[14]));
+	DEFINE(PT_FR15, offsetof(struct pt_regs, fr[15]));
+	DEFINE(PT_FR16, offsetof(struct pt_regs, fr[16]));
+	DEFINE(PT_FR17, offsetof(struct pt_regs, fr[17]));
+	DEFINE(PT_FR18, offsetof(struct pt_regs, fr[18]));
+	DEFINE(PT_FR19, offsetof(struct pt_regs, fr[19]));
+	DEFINE(PT_FR20, offsetof(struct pt_regs, fr[20]));
+	DEFINE(PT_FR21, offsetof(struct pt_regs, fr[21]));
+	DEFINE(PT_FR22, offsetof(struct pt_regs, fr[22]));
+	DEFINE(PT_FR23, offsetof(struct pt_regs, fr[23]));
+	DEFINE(PT_FR24, offsetof(struct pt_regs, fr[24]));
+	DEFINE(PT_FR25, offsetof(struct pt_regs, fr[25]));
+	DEFINE(PT_FR26, offsetof(struct pt_regs, fr[26]));
+	DEFINE(PT_FR27, offsetof(struct pt_regs, fr[27]));
+	DEFINE(PT_FR28, offsetof(struct pt_regs, fr[28]));
+	DEFINE(PT_FR29, offsetof(struct pt_regs, fr[29]));
+	DEFINE(PT_FR30, offsetof(struct pt_regs, fr[30]));
+	DEFINE(PT_FR31, offsetof(struct pt_regs, fr[31]));
+	DEFINE(PT_SR0, offsetof(struct pt_regs, sr[ 0]));
+	DEFINE(PT_SR1, offsetof(struct pt_regs, sr[ 1]));
+	DEFINE(PT_SR2, offsetof(struct pt_regs, sr[ 2]));
+	DEFINE(PT_SR3, offsetof(struct pt_regs, sr[ 3]));
+	DEFINE(PT_SR4, offsetof(struct pt_regs, sr[ 4]));
+	DEFINE(PT_SR5, offsetof(struct pt_regs, sr[ 5]));
+	DEFINE(PT_SR6, offsetof(struct pt_regs, sr[ 6]));
+	DEFINE(PT_SR7, offsetof(struct pt_regs, sr[ 7]));
+	DEFINE(PT_IASQ0, offsetof(struct pt_regs, iasq[0]));
+	DEFINE(PT_IASQ1, offsetof(struct pt_regs, iasq[1]));
+	DEFINE(PT_IAOQ0, offsetof(struct pt_regs, iaoq[0]));
+	DEFINE(PT_IAOQ1, offsetof(struct pt_regs, iaoq[1]));
+	DEFINE(PT_CR27, offsetof(struct pt_regs, cr27));
+	DEFINE(PT_ORIG_R28, offsetof(struct pt_regs, orig_r28));
+	DEFINE(PT_KSP, offsetof(struct pt_regs, ksp));
+	DEFINE(PT_KPC, offsetof(struct pt_regs, kpc));
+	DEFINE(PT_SAR, offsetof(struct pt_regs, sar));
+	DEFINE(PT_IIR, offsetof(struct pt_regs, iir));
+	DEFINE(PT_ISR, offsetof(struct pt_regs, isr));
+	DEFINE(PT_IOR, offsetof(struct pt_regs, ior));
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	/* PT_SZ_ALGN includes space for a stack frame. */
+	DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN));
+	BLANK();
+	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+	DEFINE(TI_SEGMENT, offsetof(struct thread_info, addr_limit));
+	DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+	DEFINE(THREAD_SZ, sizeof(struct thread_info));
+	/* THREAD_SZ_ALGN includes space for a stack frame. */
+	DEFINE(THREAD_SZ_ALGN, align_frame(sizeof(struct thread_info), FRAME_ALIGN));
+	BLANK();
+	DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
+	DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
+	DEFINE(ICACHE_COUNT, offsetof(struct pdc_cache_info, ic_count));
+	DEFINE(ICACHE_LOOP, offsetof(struct pdc_cache_info, ic_loop));
+	DEFINE(DCACHE_BASE, offsetof(struct pdc_cache_info, dc_base));
+	DEFINE(DCACHE_STRIDE, offsetof(struct pdc_cache_info, dc_stride));
+	DEFINE(DCACHE_COUNT, offsetof(struct pdc_cache_info, dc_count));
+	DEFINE(DCACHE_LOOP, offsetof(struct pdc_cache_info, dc_loop));
+	DEFINE(ITLB_SID_BASE, offsetof(struct pdc_cache_info, it_sp_base));
+	DEFINE(ITLB_SID_STRIDE, offsetof(struct pdc_cache_info, it_sp_stride));
+	DEFINE(ITLB_SID_COUNT, offsetof(struct pdc_cache_info, it_sp_count));
+	DEFINE(ITLB_OFF_BASE, offsetof(struct pdc_cache_info, it_off_base));
+	DEFINE(ITLB_OFF_STRIDE, offsetof(struct pdc_cache_info, it_off_stride));
+	DEFINE(ITLB_OFF_COUNT, offsetof(struct pdc_cache_info, it_off_count));
+	DEFINE(ITLB_LOOP, offsetof(struct pdc_cache_info, it_loop));
+	DEFINE(DTLB_SID_BASE, offsetof(struct pdc_cache_info, dt_sp_base));
+	DEFINE(DTLB_SID_STRIDE, offsetof(struct pdc_cache_info, dt_sp_stride));
+	DEFINE(DTLB_SID_COUNT, offsetof(struct pdc_cache_info, dt_sp_count));
+	DEFINE(DTLB_OFF_BASE, offsetof(struct pdc_cache_info, dt_off_base));
+	DEFINE(DTLB_OFF_STRIDE, offsetof(struct pdc_cache_info, dt_off_stride));
+	DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
+	DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
+	BLANK();
+	DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP);
+	DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP);
+	BLANK();
+	DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
+	DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
+	DEFINE(ASM_BITS_PER_PGD, BITS_PER_PGD);
+	DEFINE(ASM_BITS_PER_PMD, BITS_PER_PMD);
+	DEFINE(ASM_BITS_PER_PTE, BITS_PER_PTE);
+	DEFINE(ASM_PGD_PMD_OFFSET, -(PAGE_SIZE << PGD_ORDER));
+	DEFINE(ASM_PMD_ENTRY, ((PAGE_OFFSET & PMD_MASK) >> PMD_SHIFT));
+	DEFINE(ASM_PGD_ENTRY, PAGE_OFFSET >> PGDIR_SHIFT);
+	DEFINE(ASM_PGD_ENTRY_SIZE, PGD_ENTRY_SIZE);
+	DEFINE(ASM_PMD_ENTRY_SIZE, PMD_ENTRY_SIZE);
+	DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
+	DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
+	DEFINE(ASM_PT_INITIAL, PT_INITIAL);
+	BLANK();
+	/* HUGEPAGE_SIZE is only used in vmlinux.lds.S to align kernel text
+	 * and kernel data on physical huge pages */
+#ifdef CONFIG_HUGETLB_PAGE
+	DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT);
+#else
+	DEFINE(HUGEPAGE_SIZE, PAGE_SIZE);
+#endif
+	BLANK();
+	DEFINE(ASM_PDC_RESULT_SIZE, NUM_PDC_RESULT * sizeof(unsigned long));
+	BLANK();
+	return 0;
+}
diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c
new file mode 100644
index 0000000..9eb47b2
--- /dev/null
+++ b/arch/parisc/kernel/audit.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_COMPAT
+	if (arch == AUDIT_ARCH_PARISC)
+		return 1;
+#endif
+	return 0;
+}
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_COMPAT
+	extern int parisc32_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_PARISC)
+		return parisc32_classify_syscall(syscall);
+#endif
+	switch (syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_COMPAT
+	extern __u32 parisc32_dir_class[];
+	extern __u32 parisc32_write_class[];
+	extern __u32 parisc32_read_class[];
+	extern __u32 parisc32_chattr_class[];
+	extern __u32 parisc32_signal_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, parisc32_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, parisc32_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, parisc32_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, parisc32_chattr_class);
+	audit_register_class(AUDIT_CLASS_SIGNAL_32, parisc32_signal_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
new file mode 100644
index 0000000..bddd2ac
--- /dev/null
+++ b/arch/parisc/kernel/cache.c
@@ -0,0 +1,662 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> (07-13-1999)
+ * Copyright (C) 1999 SuSE GmbH Nuernberg
+ * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org)
+ *
+ * Cache and TLB management
+ *
+ */
+ 
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/pagemap.h>
+#include <linux/sched.h>
+#include <linux/sched/mm.h>
+#include <asm/pdc.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/shmparam.h>
+
+int split_tlb __read_mostly;
+int dcache_stride __read_mostly;
+int icache_stride __read_mostly;
+EXPORT_SYMBOL(dcache_stride);
+
+void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+EXPORT_SYMBOL(flush_dcache_page_asm);
+void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+
+
+/* On some machines (e.g. ones with the Merced bus), there can be
+ * only a single PxTLB broadcast at a time; this must be guaranteed
+ * by software.  We put a spinlock around all TLB flushes  to
+ * ensure this.
+ */
+DEFINE_SPINLOCK(pa_tlb_lock);
+
+struct pdc_cache_info cache_info __read_mostly;
+#ifndef CONFIG_PA20
+static struct pdc_btlb_info btlb_info __read_mostly;
+#endif
+
+#ifdef CONFIG_SMP
+void
+flush_data_cache(void)
+{
+	on_each_cpu(flush_data_cache_local, NULL, 1);
+}
+void 
+flush_instruction_cache(void)
+{
+	on_each_cpu(flush_instruction_cache_local, NULL, 1);
+}
+#endif
+
+void
+flush_cache_all_local(void)
+{
+	flush_instruction_cache_local(NULL);
+	flush_data_cache_local(NULL);
+}
+EXPORT_SYMBOL(flush_cache_all_local);
+
+/* Virtual address of pfn.  */
+#define pfn_va(pfn)	__va(PFN_PHYS(pfn))
+
+void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+{
+	unsigned long pfn = pte_pfn(*ptep);
+	struct page *page;
+
+	/* We don't have pte special.  As a result, we can be called with
+	   an invalid pfn and we don't need to flush the kernel dcache page.
+	   This occurs with FireGL card in C8000.  */
+	if (!pfn_valid(pfn))
+		return;
+
+	page = pfn_to_page(pfn);
+	if (page_mapping_file(page) &&
+	    test_bit(PG_dcache_dirty, &page->flags)) {
+		flush_kernel_dcache_page_addr(pfn_va(pfn));
+		clear_bit(PG_dcache_dirty, &page->flags);
+	} else if (parisc_requires_coherency())
+		flush_kernel_dcache_page_addr(pfn_va(pfn));
+}
+
+void
+show_cache_info(struct seq_file *m)
+{
+	char buf[32];
+
+	seq_printf(m, "I-cache\t\t: %ld KB\n", 
+		cache_info.ic_size/1024 );
+	if (cache_info.dc_loop != 1)
+		snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop);
+	seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n",
+		cache_info.dc_size/1024,
+		(cache_info.dc_conf.cc_wt ? "WT":"WB"),
+		(cache_info.dc_conf.cc_sh ? ", shared I/D":""),
+		((cache_info.dc_loop == 1) ? "direct mapped" : buf));
+	seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
+		cache_info.it_size,
+		cache_info.dt_size,
+		cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
+	);
+		
+#ifndef CONFIG_PA20
+	/* BTLB - Block TLB */
+	if (btlb_info.max_size==0) {
+		seq_printf(m, "BTLB\t\t: not supported\n" );
+	} else {
+		seq_printf(m, 
+		"BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
+		"BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
+		"BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
+		btlb_info.max_size, (int)4096,
+		btlb_info.max_size>>8,
+		btlb_info.fixed_range_info.num_i,
+		btlb_info.fixed_range_info.num_d,
+		btlb_info.fixed_range_info.num_comb, 
+		btlb_info.variable_range_info.num_i,
+		btlb_info.variable_range_info.num_d,
+		btlb_info.variable_range_info.num_comb
+		);
+	}
+#endif
+}
+
+void __init 
+parisc_cache_init(void)
+{
+	if (pdc_cache_info(&cache_info) < 0)
+		panic("parisc_cache_init: pdc_cache_info failed");
+
+#if 0
+	printk("ic_size %lx dc_size %lx it_size %lx\n",
+		cache_info.ic_size,
+		cache_info.dc_size,
+		cache_info.it_size);
+
+	printk("DC  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+		cache_info.dc_base,
+		cache_info.dc_stride,
+		cache_info.dc_count,
+		cache_info.dc_loop);
+
+	printk("dc_conf = 0x%lx  alias %d blk %d line %d shift %d\n",
+		*(unsigned long *) (&cache_info.dc_conf),
+		cache_info.dc_conf.cc_alias,
+		cache_info.dc_conf.cc_block,
+		cache_info.dc_conf.cc_line,
+		cache_info.dc_conf.cc_shift);
+	printk("	wt %d sh %d cst %d hv %d\n",
+		cache_info.dc_conf.cc_wt,
+		cache_info.dc_conf.cc_sh,
+		cache_info.dc_conf.cc_cst,
+		cache_info.dc_conf.cc_hv);
+
+	printk("IC  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+		cache_info.ic_base,
+		cache_info.ic_stride,
+		cache_info.ic_count,
+		cache_info.ic_loop);
+
+	printk("IT  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx off_base 0x%lx off_stride 0x%lx off_count 0x%lx\n",
+		cache_info.it_sp_base,
+		cache_info.it_sp_stride,
+		cache_info.it_sp_count,
+		cache_info.it_loop,
+		cache_info.it_off_base,
+		cache_info.it_off_stride,
+		cache_info.it_off_count);
+
+	printk("DT  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx off_base 0x%lx off_stride 0x%lx off_count 0x%lx\n",
+		cache_info.dt_sp_base,
+		cache_info.dt_sp_stride,
+		cache_info.dt_sp_count,
+		cache_info.dt_loop,
+		cache_info.dt_off_base,
+		cache_info.dt_off_stride,
+		cache_info.dt_off_count);
+
+	printk("ic_conf = 0x%lx  alias %d blk %d line %d shift %d\n",
+		*(unsigned long *) (&cache_info.ic_conf),
+		cache_info.ic_conf.cc_alias,
+		cache_info.ic_conf.cc_block,
+		cache_info.ic_conf.cc_line,
+		cache_info.ic_conf.cc_shift);
+	printk("	wt %d sh %d cst %d hv %d\n",
+		cache_info.ic_conf.cc_wt,
+		cache_info.ic_conf.cc_sh,
+		cache_info.ic_conf.cc_cst,
+		cache_info.ic_conf.cc_hv);
+
+	printk("D-TLB conf: sh %d page %d cst %d aid %d sr %d\n",
+		cache_info.dt_conf.tc_sh,
+		cache_info.dt_conf.tc_page,
+		cache_info.dt_conf.tc_cst,
+		cache_info.dt_conf.tc_aid,
+		cache_info.dt_conf.tc_sr);
+
+	printk("I-TLB conf: sh %d page %d cst %d aid %d sr %d\n",
+		cache_info.it_conf.tc_sh,
+		cache_info.it_conf.tc_page,
+		cache_info.it_conf.tc_cst,
+		cache_info.it_conf.tc_aid,
+		cache_info.it_conf.tc_sr);
+#endif
+
+	split_tlb = 0;
+	if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
+		if (cache_info.dt_conf.tc_sh == 2)
+			printk(KERN_WARNING "Unexpected TLB configuration. "
+			"Will flush I/D separately (could be optimized).\n");
+
+		split_tlb = 1;
+	}
+
+	/* "New and Improved" version from Jim Hull 
+	 *	(1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
+	 * The following CAFL_STRIDE is an optimized version, see
+	 * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023625.html
+	 * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023671.html
+	 */
+#define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
+	dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
+	icache_stride = CAFL_STRIDE(cache_info.ic_conf);
+#undef CAFL_STRIDE
+
+#ifndef CONFIG_PA20
+	if (pdc_btlb_info(&btlb_info) < 0) {
+		memset(&btlb_info, 0, sizeof btlb_info);
+	}
+#endif
+
+	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) ==
+						PDC_MODEL_NVA_UNSUPPORTED) {
+		printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n");
+#if 0
+		panic("SMP kernel required to avoid non-equivalent aliasing");
+#endif
+	}
+}
+
+void __init disable_sr_hashing(void)
+{
+	int srhash_type, retval;
+	unsigned long space_bits;
+
+	switch (boot_cpu_data.cpu_type) {
+	case pcx: /* We shouldn't get this far.  setup.c should prevent it. */
+		BUG();
+		return;
+
+	case pcxs:
+	case pcxt:
+	case pcxt_:
+		srhash_type = SRHASH_PCXST;
+		break;
+
+	case pcxl:
+		srhash_type = SRHASH_PCXL;
+		break;
+
+	case pcxl2: /* pcxl2 doesn't support space register hashing */
+		return;
+
+	default: /* Currently all PA2.0 machines use the same ins. sequence */
+		srhash_type = SRHASH_PA20;
+		break;
+	}
+
+	disable_sr_hashing_asm(srhash_type);
+
+	retval = pdc_spaceid_bits(&space_bits);
+	/* If this procedure isn't implemented, don't panic. */
+	if (retval < 0 && retval != PDC_BAD_OPTION)
+		panic("pdc_spaceid_bits call failed.\n");
+	if (space_bits != 0)
+		panic("SpaceID hashing is still on!\n");
+}
+
+static inline void
+__flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
+		   unsigned long physaddr)
+{
+	preempt_disable();
+	flush_dcache_page_asm(physaddr, vmaddr);
+	if (vma->vm_flags & VM_EXEC)
+		flush_icache_page_asm(physaddr, vmaddr);
+	preempt_enable();
+}
+
+void flush_dcache_page(struct page *page)
+{
+	struct address_space *mapping = page_mapping_file(page);
+	struct vm_area_struct *mpnt;
+	unsigned long offset;
+	unsigned long addr, old_addr = 0;
+	pgoff_t pgoff;
+
+	if (mapping && !mapping_mapped(mapping)) {
+		set_bit(PG_dcache_dirty, &page->flags);
+		return;
+	}
+
+	flush_kernel_dcache_page(page);
+
+	if (!mapping)
+		return;
+
+	pgoff = page->index;
+
+	/* We have carefully arranged in arch_get_unmapped_area() that
+	 * *any* mappings of a file are always congruently mapped (whether
+	 * declared as MAP_PRIVATE or MAP_SHARED), so we only need
+	 * to flush one address here for them all to become coherent */
+
+	flush_dcache_mmap_lock(mapping);
+	vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
+		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
+		addr = mpnt->vm_start + offset;
+
+		/* The TLB is the engine of coherence on parisc: The
+		 * CPU is entitled to speculate any page with a TLB
+		 * mapping, so here we kill the mapping then flush the
+		 * page along a special flush only alias mapping.
+		 * This guarantees that the page is no-longer in the
+		 * cache for any process and nor may it be
+		 * speculatively read in (until the user or kernel
+		 * specifically accesses it, of course) */
+
+		flush_tlb_page(mpnt, addr);
+		if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+				      != (addr & (SHM_COLOUR - 1))) {
+			__flush_cache_page(mpnt, addr, page_to_phys(page));
+			if (old_addr)
+				printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", old_addr, addr, mpnt->vm_file);
+			old_addr = addr;
+		}
+	}
+	flush_dcache_mmap_unlock(mapping);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+/* Defined in arch/parisc/kernel/pacache.S */
+EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
+EXPORT_SYMBOL(flush_kernel_dcache_page_asm);
+EXPORT_SYMBOL(flush_data_cache_local);
+EXPORT_SYMBOL(flush_kernel_icache_range_asm);
+
+#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
+static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
+
+#define FLUSH_TLB_THRESHOLD (2*1024*1024) /* 2MB initial TLB threshold */
+static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD;
+
+void __init parisc_setup_cache_timing(void)
+{
+	unsigned long rangetime, alltime;
+	unsigned long size, start;
+	unsigned long threshold;
+
+	alltime = mfctl(16);
+	flush_data_cache();
+	alltime = mfctl(16) - alltime;
+
+	size = (unsigned long)(_end - _text);
+	rangetime = mfctl(16);
+	flush_kernel_dcache_range((unsigned long)_text, size);
+	rangetime = mfctl(16) - rangetime;
+
+	printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
+		alltime, size, rangetime);
+
+	threshold = L1_CACHE_ALIGN(size * alltime / rangetime);
+	if (threshold > cache_info.dc_size)
+		threshold = cache_info.dc_size;
+	if (threshold)
+		parisc_cache_flush_threshold = threshold;
+	printk(KERN_INFO "Cache flush threshold set to %lu KiB\n",
+		parisc_cache_flush_threshold/1024);
+
+	/* calculate TLB flush threshold */
+
+	/* On SMP machines, skip the TLB measure of kernel text which
+	 * has been mapped as huge pages. */
+	if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
+		threshold = max(cache_info.it_size, cache_info.dt_size);
+		threshold *= PAGE_SIZE;
+		threshold /= num_online_cpus();
+		goto set_tlb_threshold;
+	}
+
+	alltime = mfctl(16);
+	flush_tlb_all();
+	alltime = mfctl(16) - alltime;
+
+	size = 0;
+	start = (unsigned long) _text;
+	rangetime = mfctl(16);
+	while (start < (unsigned long) _end) {
+		flush_tlb_kernel_range(start, start + PAGE_SIZE);
+		start += PAGE_SIZE;
+		size += PAGE_SIZE;
+	}
+	rangetime = mfctl(16) - rangetime;
+
+	printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n",
+		alltime, size, rangetime);
+
+	threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
+
+set_tlb_threshold:
+	if (threshold)
+		parisc_tlb_flush_threshold = threshold;
+	printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
+		parisc_tlb_flush_threshold/1024);
+}
+
+extern void purge_kernel_dcache_page_asm(unsigned long);
+extern void clear_user_page_asm(void *, unsigned long);
+extern void copy_user_page_asm(void *, void *, unsigned long);
+
+void flush_kernel_dcache_page_addr(void *addr)
+{
+	unsigned long flags;
+
+	flush_kernel_dcache_page_asm(addr);
+	purge_tlb_start(flags);
+	pdtlb_kernel(addr);
+	purge_tlb_end(flags);
+}
+EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+	struct page *pg)
+{
+       /* Copy using kernel mapping.  No coherency is needed (all in
+	  kunmap) for the `to' page.  However, the `from' page needs to
+	  be flushed through a mapping equivalent to the user mapping
+	  before it can be accessed through the kernel mapping. */
+	preempt_disable();
+	flush_dcache_page_asm(__pa(vfrom), vaddr);
+	copy_page_asm(vto, vfrom);
+	preempt_enable();
+}
+EXPORT_SYMBOL(copy_user_page);
+
+/* __flush_tlb_range()
+ *
+ * returns 1 if all TLBs were flushed.
+ */
+int __flush_tlb_range(unsigned long sid, unsigned long start,
+		      unsigned long end)
+{
+	unsigned long flags;
+
+	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+	    end - start >= parisc_tlb_flush_threshold) {
+		flush_tlb_all();
+		return 1;
+	}
+
+	/* Purge TLB entries for small ranges using the pdtlb and
+	   pitlb instructions.  These instructions execute locally
+	   but cause a purge request to be broadcast to other TLBs.  */
+	if (likely(!split_tlb)) {
+		while (start < end) {
+			purge_tlb_start(flags);
+			mtsp(sid, 1);
+			pdtlb(start);
+			purge_tlb_end(flags);
+			start += PAGE_SIZE;
+		}
+		return 0;
+	}
+
+	/* split TLB case */
+	while (start < end) {
+		purge_tlb_start(flags);
+		mtsp(sid, 1);
+		pdtlb(start);
+		pitlb(start);
+		purge_tlb_end(flags);
+		start += PAGE_SIZE;
+	}
+	return 0;
+}
+
+static void cacheflush_h_tmp_function(void *dummy)
+{
+	flush_cache_all_local();
+}
+
+void flush_cache_all(void)
+{
+	on_each_cpu(cacheflush_h_tmp_function, NULL, 1);
+}
+
+static inline unsigned long mm_total_size(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma;
+	unsigned long usize = 0;
+
+	for (vma = mm->mmap; vma; vma = vma->vm_next)
+		usize += vma->vm_end - vma->vm_start;
+	return usize;
+}
+
+static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
+{
+	pte_t *ptep = NULL;
+
+	if (!pgd_none(*pgd)) {
+		pud_t *pud = pud_offset(pgd, addr);
+		if (!pud_none(*pud)) {
+			pmd_t *pmd = pmd_offset(pud, addr);
+			if (!pmd_none(*pmd))
+				ptep = pte_offset_map(pmd, addr);
+		}
+	}
+	return ptep;
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma;
+	pgd_t *pgd;
+
+	/* Flushing the whole cache on each cpu takes forever on
+	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
+	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+	    mm_total_size(mm) >= parisc_cache_flush_threshold) {
+		if (mm->context)
+			flush_tlb_all();
+		flush_cache_all();
+		return;
+	}
+
+	if (mm->context == mfsp(3)) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
+			if (vma->vm_flags & VM_EXEC)
+				flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
+			flush_tlb_range(vma, vma->vm_start, vma->vm_end);
+		}
+		return;
+	}
+
+	pgd = mm->pgd;
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		unsigned long addr;
+
+		for (addr = vma->vm_start; addr < vma->vm_end;
+		     addr += PAGE_SIZE) {
+			unsigned long pfn;
+			pte_t *ptep = get_ptep(pgd, addr);
+			if (!ptep)
+				continue;
+			pfn = pte_pfn(*ptep);
+			if (!pfn_valid(pfn))
+				continue;
+			if (unlikely(mm->context))
+				flush_tlb_page(vma, addr);
+			__flush_cache_page(vma, addr, PFN_PHYS(pfn));
+		}
+	}
+}
+
+void flush_cache_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end)
+{
+	pgd_t *pgd;
+	unsigned long addr;
+
+	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+	    end - start >= parisc_cache_flush_threshold) {
+		if (vma->vm_mm->context)
+			flush_tlb_range(vma, start, end);
+		flush_cache_all();
+		return;
+	}
+
+	if (vma->vm_mm->context == mfsp(3)) {
+		flush_user_dcache_range_asm(start, end);
+		if (vma->vm_flags & VM_EXEC)
+			flush_user_icache_range_asm(start, end);
+		flush_tlb_range(vma, start, end);
+		return;
+	}
+
+	pgd = vma->vm_mm->pgd;
+	for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
+		unsigned long pfn;
+		pte_t *ptep = get_ptep(pgd, addr);
+		if (!ptep)
+			continue;
+		pfn = pte_pfn(*ptep);
+		if (pfn_valid(pfn)) {
+			if (unlikely(vma->vm_mm->context))
+				flush_tlb_page(vma, addr);
+			__flush_cache_page(vma, addr, PFN_PHYS(pfn));
+		}
+	}
+}
+
+void
+flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
+{
+	if (pfn_valid(pfn)) {
+		if (likely(vma->vm_mm->context))
+			flush_tlb_page(vma, vmaddr);
+		__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
+	}
+}
+
+void flush_kernel_vmap_range(void *vaddr, int size)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end = start + size;
+
+	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+	    (unsigned long)size >= parisc_cache_flush_threshold) {
+		flush_tlb_kernel_range(start, end);
+		flush_data_cache();
+		return;
+	}
+
+	flush_kernel_dcache_range_asm(start, end);
+	flush_tlb_kernel_range(start, end);
+}
+EXPORT_SYMBOL(flush_kernel_vmap_range);
+
+void invalidate_kernel_vmap_range(void *vaddr, int size)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end = start + size;
+
+	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+	    (unsigned long)size >= parisc_cache_flush_threshold) {
+		flush_tlb_kernel_range(start, end);
+		flush_data_cache();
+		return;
+	}
+
+	purge_kernel_dcache_range_asm(start, end);
+	flush_tlb_kernel_range(start, end);
+}
+EXPORT_SYMBOL(invalidate_kernel_vmap_range);
diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c
new file mode 100644
index 0000000..20c39c9
--- /dev/null
+++ b/arch/parisc/kernel/compat_audit.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <asm/unistd.h>
+
+unsigned int parisc32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned int parisc32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned int parisc32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned int parisc32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+unsigned int parisc32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int parisc32_classify_syscall(unsigned syscall)
+{
+	switch (syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
new file mode 100644
index 0000000..5eb979d
--- /dev/null
+++ b/arch/parisc/kernel/drivers.c
@@ -0,0 +1,1083 @@
+/*
+ * drivers.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1999 The Puffin Group
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
+ * Copyright (c) 2001 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2001,2002 Ryan Bradetich 
+ * Copyright (c) 2004-2005 Thibaut VARENE <varenet@parisc-linux.org>
+ * 
+ * The file handles registering devices and drivers, then matching them.
+ * It's the closest we get to a dating agency.
+ *
+ * If you're thinking about modifying this file, here are some gotchas to
+ * bear in mind:
+ *  - 715/Mirage device paths have a dummy device between Lasi and its children
+ *  - The EISA adapter may show up as a sibling or child of Wax
+ *  - Dino has an optionally functional serial port.  If firmware enables it,
+ *    it shows up as a child of Dino.  If firmware disables it, the buswalk
+ *    finds it and it shows up as a child of Cujo
+ *  - Dino has both parisc and pci devices as children
+ *  - parisc devices are discovered in a random order, including children
+ *    before parents in some cases.
+ */
+
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/export.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pdc.h>
+#include <asm/parisc-device.h>
+
+/* See comments in include/asm-parisc/pci.h */
+const struct dma_map_ops *hppa_dma_ops __read_mostly;
+EXPORT_SYMBOL(hppa_dma_ops);
+
+static struct device root = {
+	.init_name = "parisc",
+};
+
+static inline int check_dev(struct device *dev)
+{
+	if (dev->bus == &parisc_bus_type) {
+		struct parisc_device *pdev;
+		pdev = to_parisc_device(dev);
+		return pdev->id.hw_type != HPHW_FAULTY;
+	}
+	return 1;
+}
+
+static struct device *
+parse_tree_node(struct device *parent, int index, struct hardware_path *modpath);
+
+struct recurse_struct {
+	void * obj;
+	int (*fn)(struct device *, void *);
+};
+
+static int descend_children(struct device * dev, void * data)
+{
+	struct recurse_struct * recurse_data = (struct recurse_struct *)data;
+
+	if (recurse_data->fn(dev, recurse_data->obj))
+		return 1;
+	else
+		return device_for_each_child(dev, recurse_data, descend_children);
+}
+
+/**
+ *	for_each_padev - Iterate over all devices in the tree
+ *	@fn:	Function to call for each device.
+ *	@data:	Data to pass to the called function.
+ *
+ *	This performs a depth-first traversal of the tree, calling the
+ *	function passed for each node.  It calls the function for parents
+ *	before children.
+ */
+
+static int for_each_padev(int (*fn)(struct device *, void *), void * data)
+{
+	struct recurse_struct recurse_data = {
+		.obj	= data,
+		.fn	= fn,
+	};
+	return device_for_each_child(&root, &recurse_data, descend_children);
+}
+
+/**
+ * match_device - Report whether this driver can handle this device
+ * @driver: the PA-RISC driver to try
+ * @dev: the PA-RISC device to try
+ */
+static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
+{
+	const struct parisc_device_id *ids;
+
+	for (ids = driver->id_table; ids->sversion; ids++) {
+		if ((ids->sversion != SVERSION_ANY_ID) &&
+		    (ids->sversion != dev->id.sversion))
+			continue;
+
+		if ((ids->hw_type != HWTYPE_ANY_ID) &&
+		    (ids->hw_type != dev->id.hw_type))
+			continue;
+
+		if ((ids->hversion != HVERSION_ANY_ID) &&
+		    (ids->hversion != dev->id.hversion))
+			continue;
+
+		return 1;
+	}
+	return 0;
+}
+
+static int parisc_driver_probe(struct device *dev)
+{
+	int rc;
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+	struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+
+	rc = pa_drv->probe(pa_dev);
+
+	if (!rc)
+		pa_dev->driver = pa_drv;
+
+	return rc;
+}
+
+static int __exit parisc_driver_remove(struct device *dev)
+{
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+	struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+	if (pa_drv->remove)
+		pa_drv->remove(pa_dev);
+
+	return 0;
+}
+	
+
+/**
+ * register_parisc_driver - Register this driver if it can handle a device
+ * @driver: the PA-RISC driver to try
+ */
+int register_parisc_driver(struct parisc_driver *driver)
+{
+	/* FIXME: we need this because apparently the sti
+	 * driver can be registered twice */
+	if (driver->drv.name) {
+		pr_warn("BUG: skipping previously registered driver %s\n",
+			driver->name);
+		return 1;
+	}
+
+	if (!driver->probe) {
+		pr_warn("BUG: driver %s has no probe routine\n", driver->name);
+		return 1;
+	}
+
+	driver->drv.bus = &parisc_bus_type;
+
+	/* We install our own probe and remove routines */
+	WARN_ON(driver->drv.probe != NULL);
+	WARN_ON(driver->drv.remove != NULL);
+
+	driver->drv.name = driver->name;
+
+	return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(register_parisc_driver);
+
+
+struct match_count {
+	struct parisc_driver * driver;
+	int count;
+};
+
+static int match_and_count(struct device * dev, void * data)
+{
+	struct match_count * m = data;
+	struct parisc_device * pdev = to_parisc_device(dev);
+
+	if (check_dev(dev)) {
+		if (match_device(m->driver, pdev))
+			m->count++;
+	}
+	return 0;
+}
+
+/**
+ * count_parisc_driver - count # of devices this driver would match
+ * @driver: the PA-RISC driver to try
+ *
+ * Use by IOMMU support to "guess" the right size IOPdir.
+ * Formula is something like memsize/(num_iommu * entry_size).
+ */
+int __init count_parisc_driver(struct parisc_driver *driver)
+{
+	struct match_count m = {
+		.driver	= driver,
+		.count	= 0,
+	};
+
+	for_each_padev(match_and_count, &m);
+
+	return m.count;
+}
+
+
+
+/**
+ * unregister_parisc_driver - Unregister this driver from the list of drivers
+ * @driver: the PA-RISC driver to unregister
+ */
+int unregister_parisc_driver(struct parisc_driver *driver)
+{
+	driver_unregister(&driver->drv);
+	return 0;
+}
+EXPORT_SYMBOL(unregister_parisc_driver);
+
+struct find_data {
+	unsigned long hpa;
+	struct parisc_device * dev;
+};
+
+static int find_device(struct device * dev, void * data)
+{
+	struct parisc_device * pdev = to_parisc_device(dev);
+	struct find_data * d = (struct find_data*)data;
+
+	if (check_dev(dev)) {
+		if (pdev->hpa.start == d->hpa) {
+			d->dev = pdev;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static struct parisc_device *find_device_by_addr(unsigned long hpa)
+{
+	struct find_data d = {
+		.hpa	= hpa,
+	};
+	int ret;
+
+	ret = for_each_padev(find_device, &d);
+	return ret ? d.dev : NULL;
+}
+
+/**
+ * find_pa_parent_type - Find a parent of a specific type
+ * @dev: The device to start searching from
+ * @type: The device type to search for.
+ *
+ * Walks up the device tree looking for a device of the specified type.
+ * If it finds it, it returns it.  If not, it returns NULL.
+ */
+const struct parisc_device *
+find_pa_parent_type(const struct parisc_device *padev, int type)
+{
+	const struct device *dev = &padev->dev;
+	while (dev != &root) {
+		struct parisc_device *candidate = to_parisc_device(dev);
+		if (candidate->id.hw_type == type)
+			return candidate;
+		dev = dev->parent;
+	}
+
+	return NULL;
+}
+
+/*
+ * get_node_path fills in @path with the firmware path to the device.
+ * Note that if @node is a parisc device, we don't fill in the 'mod' field.
+ * This is because both callers pass the parent and fill in the mod
+ * themselves.  If @node is a PCI device, we do fill it in, even though this
+ * is inconsistent.
+ */
+static void get_node_path(struct device *dev, struct hardware_path *path)
+{
+	int i = 5;
+	memset(&path->bc, -1, 6);
+
+	if (dev_is_pci(dev)) {
+		unsigned int devfn = to_pci_dev(dev)->devfn;
+		path->mod = PCI_FUNC(devfn);
+		path->bc[i--] = PCI_SLOT(devfn);
+		dev = dev->parent;
+	}
+
+	while (dev != &root) {
+		if (dev_is_pci(dev)) {
+			unsigned int devfn = to_pci_dev(dev)->devfn;
+			path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
+		} else if (dev->bus == &parisc_bus_type) {
+			path->bc[i--] = to_parisc_device(dev)->hw_path;
+		}
+		dev = dev->parent;
+	}
+}
+
+static char *print_hwpath(struct hardware_path *path, char *output)
+{
+	int i;
+	for (i = 0; i < 6; i++) {
+		if (path->bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u/", (unsigned char) path->bc[i]);
+	}
+	output += sprintf(output, "%u", (unsigned char) path->mod);
+	return output;
+}
+
+/**
+ * print_pa_hwpath - Returns hardware path for PA devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PA device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pa_hwpath(struct parisc_device *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_node_path(dev->dev.parent, &path);
+	path.mod = dev->hw_path;
+	return print_hwpath(&path, output);
+}
+EXPORT_SYMBOL(print_pa_hwpath);
+
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+/**
+ * get_pci_node_path - Determines the hardware path for a PCI device
+ * @pdev: The device to return the path for
+ * @path: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the hardware_path structure with the route to
+ * the specified PCI device.  This structure is suitable for passing to
+ * PDC calls.
+ */
+void get_pci_node_path(struct pci_dev *pdev, struct hardware_path *path)
+{
+	get_node_path(&pdev->dev, path);
+}
+EXPORT_SYMBOL(get_pci_node_path);
+
+/**
+ * print_pci_hwpath - Returns hardware path for PCI devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PCI device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pci_hwpath(struct pci_dev *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_pci_node_path(dev, &path);
+	return print_hwpath(&path, output);
+}
+EXPORT_SYMBOL(print_pci_hwpath);
+
+#endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
+
+static void setup_bus_id(struct parisc_device *padev)
+{
+	struct hardware_path path;
+	char name[28];
+	char *output = name;
+	int i;
+
+	get_node_path(padev->dev.parent, &path);
+
+	for (i = 0; i < 6; i++) {
+		if (path.bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u:", (unsigned char) path.bc[i]);
+	}
+	sprintf(output, "%u", (unsigned char) padev->hw_path);
+	dev_set_name(&padev->dev, name);
+}
+
+struct parisc_device * __init create_tree_node(char id, struct device *parent)
+{
+	struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	dev->hw_path = id;
+	dev->id.hw_type = HPHW_FAULTY;
+
+	dev->dev.parent = parent;
+	setup_bus_id(dev);
+
+	dev->dev.bus = &parisc_bus_type;
+	dev->dma_mask = 0xffffffffUL;	/* PARISC devices are 32-bit */
+
+	/* make the generic dma mask a pointer to the parisc one */
+	dev->dev.dma_mask = &dev->dma_mask;
+	dev->dev.coherent_dma_mask = dev->dma_mask;
+	if (device_register(&dev->dev)) {
+		kfree(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+
+struct match_id_data {
+	char id;
+	struct parisc_device * dev;
+};
+
+static int match_by_id(struct device * dev, void * data)
+{
+	struct parisc_device * pdev = to_parisc_device(dev);
+	struct match_id_data * d = data;
+
+	if (pdev->hw_path == d->id) {
+		d->dev = pdev;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * alloc_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @id: the element of the module path for this entry
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it allocates a new device and returns it.
+ */
+static struct parisc_device * __init alloc_tree_node(
+			struct device *parent, char id)
+{
+	struct match_id_data d = {
+		.id = id,
+	};
+	if (device_for_each_child(parent, &d, match_by_id))
+		return d.dev;
+	else
+		return create_tree_node(id, parent);
+}
+
+static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
+{
+	int i;
+	struct device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = &alloc_tree_node(parent, modpath->bc[i])->dev;
+	}
+	return alloc_tree_node(parent, modpath->mod);
+}
+
+struct parisc_device * __init
+alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
+{
+	int status;
+	unsigned long bytecnt;
+	u8 iodc_data[32];
+	struct parisc_device *dev;
+	const char *name;
+
+	/* Check to make sure this device has not already been added - Ryan */
+	if (find_device_by_addr(hpa) != NULL)
+		return NULL;
+
+	status = pdc_iodc_read(&bytecnt, hpa, 0, &iodc_data, 32);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = create_parisc_device(mod_path);
+	if (dev->id.hw_type != HPHW_FAULTY) {
+		pr_err("Two devices have hardware path [%s].  IODC data for second device: %7phN\n"
+		       "Rearranging GSC cards sometimes helps\n",
+			parisc_pathname(dev), iodc_data);
+		return NULL;
+	}
+
+	dev->id.hw_type = iodc_data[3] & 0x1f;
+	dev->id.hversion = (iodc_data[0] << 4) | ((iodc_data[1] & 0xf0) >> 4);
+	dev->id.hversion_rev = iodc_data[1] & 0x0f;
+	dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
+			(iodc_data[5] << 8) | iodc_data[6];
+	dev->hpa.name = parisc_pathname(dev);
+	dev->hpa.start = hpa;
+	/* This is awkward.  The STI spec says that gfx devices may occupy
+	 * 32MB or 64MB.  Unfortunately, we don't know how to tell whether
+	 * it's the former or the latter.  Assumptions either way can hurt us.
+	 */
+	if (hpa == 0xf4000000 || hpa == 0xf8000000) {
+		dev->hpa.end = hpa + 0x03ffffff;
+	} else if (hpa == 0xf6000000 || hpa == 0xfa000000) {
+		dev->hpa.end = hpa + 0x01ffffff;
+	} else {
+		dev->hpa.end = hpa + 0xfff;
+	}
+	dev->hpa.flags = IORESOURCE_MEM;
+	name = parisc_hardware_description(&dev->id);
+	if (name) {
+		strlcpy(dev->name, name, sizeof(dev->name));
+	}
+
+	/* Silently fail things like mouse ports which are subsumed within
+	 * the keyboard controller
+	 */
+	if ((hpa & 0xfff) == 0 && insert_resource(&iomem_resource, &dev->hpa))
+		pr_warn("Unable to claim HPA %lx for device %s\n", hpa, name);
+
+	return dev;
+}
+
+static int parisc_generic_match(struct device *dev, struct device_driver *drv)
+{
+	return match_device(to_parisc_driver(drv), to_parisc_device(dev));
+}
+
+static ssize_t make_modalias(struct device *dev, char *buf)
+{
+	const struct parisc_device *padev = to_parisc_device(dev);
+	const struct parisc_device_id *id = &padev->id;
+
+	return sprintf(buf, "parisc:t%02Xhv%04Xrev%02Xsv%08X\n",
+		(u8)id->hw_type, (u16)id->hversion, (u8)id->hversion_rev,
+		(u32)id->sversion);
+}
+
+static int parisc_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	const struct parisc_device *padev;
+	char modalias[40];
+
+	if (!dev)
+		return -ENODEV;
+
+	padev = to_parisc_device(dev);
+	if (!padev)
+		return -ENODEV;
+
+	if (add_uevent_var(env, "PARISC_NAME=%s", padev->name))
+		return -ENOMEM;
+
+	make_modalias(dev, modalias);
+	if (add_uevent_var(env, "MODALIAS=%s", modalias))
+		return -ENOMEM;
+
+	return 0;
+}
+
+#define pa_dev_attr(name, field, format_string)				\
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct parisc_device *padev = to_parisc_device(dev);		\
+	return sprintf(buf, format_string, padev->field);		\
+}									\
+static DEVICE_ATTR_RO(name);
+
+#define pa_dev_attr_id(field, format) pa_dev_attr(field, id.field, format)
+
+pa_dev_attr(irq, irq, "%u\n");
+pa_dev_attr_id(hw_type, "0x%02x\n");
+pa_dev_attr(rev, id.hversion_rev, "0x%x\n");
+pa_dev_attr_id(hversion, "0x%03x\n");
+pa_dev_attr_id(sversion, "0x%05x\n");
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return make_modalias(dev, buf);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *parisc_device_attrs[] = {
+	&dev_attr_irq.attr,
+	&dev_attr_hw_type.attr,
+	&dev_attr_rev.attr,
+	&dev_attr_hversion.attr,
+	&dev_attr_sversion.attr,
+	&dev_attr_modalias.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(parisc_device);
+
+struct bus_type parisc_bus_type = {
+	.name = "parisc",
+	.match = parisc_generic_match,
+	.uevent = parisc_uevent,
+	.dev_groups = parisc_device_groups,
+	.probe = parisc_driver_probe,
+	.remove = __exit_p(parisc_driver_remove),
+};
+
+/**
+ * register_parisc_device - Locate a driver to manage this device.
+ * @dev: The parisc device.
+ *
+ * Search the driver list for a driver that is willing to manage
+ * this device.
+ */
+int __init register_parisc_device(struct parisc_device *dev)
+{
+	if (!dev)
+		return 0;
+
+	if (dev->driver)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * match_pci_device - Matches a pci device against a given hardware path
+ * entry.
+ * @dev: the generic device (known to be contained by a pci_dev).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_pci_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int id;
+
+	if (index == 5) {
+		/* we are at the end of the path, and on the actual device */
+		unsigned int devfn = pdev->devfn;
+		return ((modpath->bc[5] == PCI_SLOT(devfn)) &&
+					(modpath->mod == PCI_FUNC(devfn)));
+	}
+
+	/* index might be out of bounds for bc[] */
+	if (index >= 6)
+		return 0;
+
+	id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
+	return (modpath->bc[index] == id);
+}
+
+/**
+ * match_parisc_device - Matches a parisc device against a given hardware
+ * path entry.
+ * @dev: the generic device (known to be contained by a parisc_device).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_parisc_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct parisc_device *curr = to_parisc_device(dev);
+	char id = (index == 6) ? modpath->mod : modpath->bc[index];
+
+	return (curr->hw_path == id);
+}
+
+struct parse_tree_data {
+	int index;
+	struct hardware_path * modpath;
+	struct device * dev;
+};
+
+static int check_parent(struct device * dev, void * data)
+{
+	struct parse_tree_data * d = data;
+
+	if (check_dev(dev)) {
+		if (dev->bus == &parisc_bus_type) {
+			if (match_parisc_device(dev, d->index, d->modpath))
+				d->dev = dev;
+		} else if (dev_is_pci(dev)) {
+			if (match_pci_device(dev, d->index, d->modpath))
+				d->dev = dev;
+		} else if (dev->bus == NULL) {
+			/* we are on a bus bridge */
+			struct device *new = parse_tree_node(dev, d->index, d->modpath);
+			if (new)
+				d->dev = new;
+		}
+	}
+	return d->dev != NULL;
+}
+
+/**
+ * parse_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @index: the current BC index
+ * @modpath: the hardware_path struct to match a device against
+ * @return: The corresponding device if found, NULL otherwise.
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it returns NULL.
+ */
+static struct device *
+parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
+{
+	struct parse_tree_data d = {
+		.index          = index,
+		.modpath        = modpath,
+	};
+
+	struct recurse_struct recurse_data = {
+		.obj	= &d,
+		.fn	= check_parent,
+	};
+
+	if (device_for_each_child(parent, &recurse_data, descend_children))
+		/* nothing */;
+
+	return d.dev;
+}
+
+/**
+ * hwpath_to_device - Finds the generic device corresponding to a given hardware path.
+ * @modpath: the hardware path.
+ * @return: The target device, NULL if not found.
+ */
+struct device *hwpath_to_device(struct hardware_path *modpath)
+{
+	int i;
+	struct device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = parse_tree_node(parent, i, modpath);
+		if (!parent)
+			return NULL;
+	}
+	if (dev_is_pci(parent)) /* pci devices already parse MOD */
+		return parent;
+	else
+		return parse_tree_node(parent, 6, modpath);
+}
+EXPORT_SYMBOL(hwpath_to_device);
+
+/**
+ * device_to_hwpath - Populates the hwpath corresponding to the given device.
+ * @param dev the target device
+ * @param path pointer to a previously allocated hwpath struct to be filled in
+ */
+void device_to_hwpath(struct device *dev, struct hardware_path *path)
+{
+	struct parisc_device *padev;
+	if (dev->bus == &parisc_bus_type) {
+		padev = to_parisc_device(dev);
+		get_node_path(dev->parent, path);
+		path->mod = padev->hw_path;
+	} else if (dev_is_pci(dev)) {
+		get_node_path(dev, path);
+	}
+}
+EXPORT_SYMBOL(device_to_hwpath);
+
+#define BC_PORT_MASK 0x8
+#define BC_LOWER_PORT 0x8
+
+#define BUS_CONVERTER(dev) \
+        ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
+
+#define IS_LOWER_PORT(dev) \
+        ((gsc_readl(dev->hpa.start + offsetof(struct bc_module, io_status)) \
+                & BC_PORT_MASK) == BC_LOWER_PORT)
+
+#define MAX_NATIVE_DEVICES 64
+#define NATIVE_DEVICE_OFFSET 0x1000
+
+#define FLEX_MASK 	F_EXTEND(0xfffc0000)
+#define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
+#define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
+#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_HIGH)
+
+static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
+                            struct device *parent);
+
+static void walk_lower_bus(struct parisc_device *dev)
+{
+	unsigned long io_io_low, io_io_high;
+
+	if (!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
+		return;
+
+	if (dev->id.hw_type == HPHW_IOA) {
+		io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
+		io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
+	} else {
+		io_io_low = (READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK;
+		io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
+	}
+
+	walk_native_bus(io_io_low, io_io_high, &dev->dev);
+}
+
+/**
+ * walk_native_bus -- Probe a bus for devices
+ * @io_io_low: Base address of this bus.
+ * @io_io_high: Last address of this bus.
+ * @parent: The parent bus device.
+ * 
+ * A native bus (eg Runway or GSC) may have up to 64 devices on it,
+ * spaced at intervals of 0x1000 bytes.  PDC may not inform us of these
+ * devices, so we have to probe for them.  Unfortunately, we may find
+ * devices which are not physically connected (such as extra serial &
+ * keyboard ports).  This problem is not yet solved.
+ */
+static void __init walk_native_bus(unsigned long io_io_low,
+	unsigned long io_io_high, struct device *parent)
+{
+	int i, devices_found = 0;
+	unsigned long hpa = io_io_low;
+	struct hardware_path path;
+
+	get_node_path(parent, &path);
+	do {
+		for(i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) {
+			struct parisc_device *dev;
+
+			/* Was the device already added by Firmware? */
+			dev = find_device_by_addr(hpa);
+			if (!dev) {
+				path.mod = i;
+				dev = alloc_pa_dev(hpa, &path);
+				if (!dev)
+					continue;
+
+				register_parisc_device(dev);
+				devices_found++;
+			}
+			walk_lower_bus(dev);
+		}
+	} while(!devices_found && hpa < io_io_high);
+}
+
+#define CENTRAL_BUS_ADDR F_EXTEND(0xfff80000)
+
+/**
+ * walk_central_bus - Find devices attached to the central bus
+ *
+ * PDC doesn't tell us about all devices in the system.  This routine
+ * finds devices connected to the central bus.
+ */
+void __init walk_central_bus(void)
+{
+	walk_native_bus(CENTRAL_BUS_ADDR,
+			CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
+			&root);
+}
+
+static void print_parisc_device(struct parisc_device *dev)
+{
+	char hw_path[64];
+	static int count;
+
+	print_pa_hwpath(dev, hw_path);
+	pr_info("%d. %s at 0x%px [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+		++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type,
+		dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
+
+	if (dev->num_addrs) {
+		int k;
+		pr_cont(", additional addresses: ");
+		for (k = 0; k < dev->num_addrs; k++)
+			pr_cont("0x%lx ", dev->addr[k]);
+	}
+	pr_cont("\n");
+}
+
+/**
+ * init_parisc_bus - Some preparation to be done before inventory
+ */
+void __init init_parisc_bus(void)
+{
+	if (bus_register(&parisc_bus_type))
+		panic("Could not register PA-RISC bus type\n");
+	if (device_register(&root))
+		panic("Could not register PA-RISC root device\n");
+	get_device(&root);
+}
+
+static __init void qemu_header(void)
+{
+	int num;
+	unsigned long *p;
+
+	pr_info("--- cut here ---\n");
+	pr_info("/* AUTO-GENERATED HEADER FILE FOR SEABIOS FIRMWARE */\n");
+	pr_cont("/* generated with Linux kernel */\n");
+	pr_cont("/* search for PARISC_QEMU_MACHINE_HEADER in Linux */\n\n");
+
+	pr_info("#define PARISC_MODEL \"%s\"\n\n",
+			boot_cpu_data.pdc.sys_model_name);
+
+	pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, "
+		"0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n",
+	#define p ((unsigned long *)&boot_cpu_data.pdc.model)
+		p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
+	#undef p
+
+	pr_info("#define PARISC_PDC_VERSION 0x%04lx\n\n",
+			boot_cpu_data.pdc.versions);
+
+	pr_info("#define PARISC_PDC_CPUID 0x%04lx\n\n",
+			boot_cpu_data.pdc.cpuid);
+
+	pr_info("#define PARISC_PDC_CAPABILITIES 0x%04lx\n\n",
+			boot_cpu_data.pdc.capabilities);
+
+	pr_info("#define PARISC_PDC_ENTRY_ORG 0x%04lx\n\n",
+#ifdef CONFIG_64BIT
+		(unsigned long)(PAGE0->mem_pdc_hi) << 32 |
+#endif
+		(unsigned long)PAGE0->mem_pdc);
+
+	pr_info("#define PARISC_PDC_CACHE_INFO");
+	p = (unsigned long *) &cache_info;
+	for (num = 0; num < sizeof(cache_info); num += sizeof(unsigned long)) {
+		if (((num % 5) == 0)) {
+			pr_cont(" \\\n");
+			pr_info("\t");
+		}
+		pr_cont("%s0x%04lx",
+			num?", ":"", *p++);
+	}
+	pr_cont("\n\n");
+}
+
+static __init int qemu_print_hpa(struct device *lin_dev, void *data)
+{
+	struct parisc_device *dev = to_parisc_device(lin_dev);
+	unsigned long hpa = dev->hpa.start;
+
+	pr_cont("\t{\t.hpa = 0x%08lx,\\\n", hpa);
+	pr_cont("\t\t.iodc = &iodc_data_hpa_%08lx,\\\n", hpa);
+	pr_cont("\t\t.mod_info = &mod_info_hpa_%08lx,\\\n", hpa);
+	pr_cont("\t\t.mod_path = &mod_path_hpa_%08lx,\\\n", hpa);
+	pr_cont("\t\t.num_addr = HPA_%08lx_num_addr,\\\n", hpa);
+	pr_cont("\t\t.add_addr = { HPA_%08lx_add_addr } },\\\n", hpa);
+	return 0;
+}
+
+
+static __init void qemu_footer(void)
+{
+	pr_info("\n\n#define PARISC_DEVICE_LIST \\\n");
+	for_each_padev(qemu_print_hpa, NULL);
+	pr_cont("\t{ 0, }\n");
+	pr_info("--- cut here ---\n");
+}
+
+/* print iodc data of the various hpa modules for qemu inclusion */
+static __init int qemu_print_iodc_data(struct device *lin_dev, void *data)
+{
+	struct parisc_device *dev = to_parisc_device(lin_dev);
+	unsigned long count;
+	unsigned long hpa = dev->hpa.start;
+	int status;
+	struct pdc_iodc iodc_data;
+
+	int mod_index;
+	struct pdc_system_map_mod_info pdc_mod_info;
+	struct pdc_module_path mod_path;
+
+	status = pdc_iodc_read(&count, hpa, 0,
+		&iodc_data, sizeof(iodc_data));
+	if (status != PDC_OK) {
+		pr_info("No IODC data for hpa 0x%08lx\n", hpa);
+		return 0;
+	}
+
+	pr_info("\n");
+
+	pr_info("#define HPA_%08lx_DESCRIPTION \"%s\"\n",
+		hpa, parisc_hardware_description(&dev->id));
+
+	mod_index = 0;
+	do {
+		status = pdc_system_map_find_mods(&pdc_mod_info,
+				&mod_path, mod_index++);
+	} while (status == PDC_OK && pdc_mod_info.mod_addr != hpa);
+
+	pr_info("static struct pdc_system_map_mod_info"
+		" mod_info_hpa_%08lx = {\n", hpa);
+	#define DO(member) \
+		pr_cont("\t." #member " = 0x%x,\n", \
+			(unsigned int)pdc_mod_info.member)
+	DO(mod_addr);
+	DO(mod_pgs);
+	DO(add_addrs);
+	pr_cont("};\n");
+	#undef DO
+	pr_info("static struct pdc_module_path "
+		"mod_path_hpa_%08lx = {\n", hpa);
+	pr_cont("\t.path = { ");
+	pr_cont(".flags = 0x%x, ", mod_path.path.flags);
+	pr_cont(".bc = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }, ",
+		(unsigned char)mod_path.path.bc[0],
+		(unsigned char)mod_path.path.bc[1],
+		(unsigned char)mod_path.path.bc[2],
+		(unsigned char)mod_path.path.bc[3],
+		(unsigned char)mod_path.path.bc[4],
+		(unsigned char)mod_path.path.bc[5]);
+	pr_cont(".mod = 0x%x ", mod_path.path.mod);
+	pr_cont(" },\n");
+	pr_cont("\t.layers = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n",
+		mod_path.layers[0], mod_path.layers[1], mod_path.layers[2],
+		mod_path.layers[3], mod_path.layers[4], mod_path.layers[5]);
+	pr_cont("};\n");
+
+	pr_info("static struct pdc_iodc iodc_data_hpa_%08lx = {\n", hpa);
+	#define DO(member) \
+		pr_cont("\t." #member " = 0x%04lx,\n", \
+			(unsigned long)iodc_data.member)
+	DO(hversion_model);
+	DO(hversion);
+	DO(spa);
+	DO(type);
+	DO(sversion_rev);
+	DO(sversion_model);
+	DO(sversion_opt);
+	DO(rev);
+	DO(dep);
+	DO(features);
+	DO(checksum);
+	DO(length);
+	#undef DO
+	pr_cont("\t/* pad: 0x%04x, 0x%04x */\n",
+		iodc_data.pad[0], iodc_data.pad[1]);
+	pr_cont("};\n");
+
+	pr_info("#define HPA_%08lx_num_addr %d\n", hpa, dev->num_addrs);
+	pr_info("#define HPA_%08lx_add_addr ", hpa);
+	count = 0;
+	if (dev->num_addrs == 0)
+		pr_cont("0");
+	while (count < dev->num_addrs) {
+		pr_cont("0x%08lx, ", dev->addr[count]);
+		count++;
+	}
+	pr_cont("\n\n");
+
+	return 0;
+}
+
+
+
+static int print_one_device(struct device * dev, void * data)
+{
+	struct parisc_device * pdev = to_parisc_device(dev);
+
+	if (check_dev(dev))
+		print_parisc_device(pdev);
+	return 0;
+}
+
+/**
+ * print_parisc_devices - Print out a list of devices found in this system
+ */
+void __init print_parisc_devices(void)
+{
+	for_each_padev(print_one_device, NULL);
+	#define PARISC_QEMU_MACHINE_HEADER 0
+	if (PARISC_QEMU_MACHINE_HEADER) {
+		qemu_header();
+		for_each_padev(qemu_print_iodc_data, NULL);
+		qemu_footer();
+	}
+}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
new file mode 100644
index 0000000..d2f9227
--- /dev/null
+++ b/arch/parisc/kernel/entry.S
@@ -0,0 +1,2270 @@
+/*
+ * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+ *
+ * kernel entry points (interruptions, system call wrappers)
+ *  Copyright (C) 1999,2000 Philipp Rumpf 
+ *  Copyright (C) 1999 SuSE GmbH Nuernberg 
+ *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
+ *  Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/asm-offsets.h>
+
+/* we have the following possibilities to act on an interruption:
+ *  - handle in assembly and use shadowed registers only
+ *  - save registers to kernel stack and handle in assembly or C */
+
+
+#include <asm/psw.h>
+#include <asm/cache.h>		/* for L1_CACHE_SHIFT */
+#include <asm/assembly.h>	/* for LDREG/STREG defines */
+#include <asm/pgtable.h>
+#include <asm/signal.h>
+#include <asm/unistd.h>
+#include <asm/ldcw.h>
+#include <asm/traps.h>
+#include <asm/thread_info.h>
+
+#include <linux/linkage.h>
+
+#ifdef CONFIG_64BIT
+	.level 2.0w
+#else
+	.level 2.0
+#endif
+
+	.import		pa_tlb_lock,data
+	.macro  load_pa_tlb_lock reg
+#if __PA_LDCW_ALIGNMENT > 4
+	load32	PA(pa_tlb_lock) + __PA_LDCW_ALIGNMENT-1, \reg
+	depi	0,31,__PA_LDCW_ALIGN_ORDER, \reg
+#else
+	load32	PA(pa_tlb_lock), \reg
+#endif
+	.endm
+
+	/* space_to_prot macro creates a prot id from a space id */
+
+#if (SPACEID_SHIFT) == 0
+	.macro  space_to_prot spc prot
+	depd,z  \spc,62,31,\prot
+	.endm
+#else
+	.macro  space_to_prot spc prot
+	extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
+	.endm
+#endif
+
+	/* Switch to virtual mapping, trashing only %r1 */
+	.macro  virt_map
+	/* pcxt_ssm_bug */
+	rsm	PSW_SM_I, %r0	/* barrier for "Relied upon Translation */
+	mtsp	%r0, %sr4
+	mtsp	%r0, %sr5
+	mtsp	%r0, %sr6
+	tovirt_r1 %r29
+	load32	KERNEL_PSW, %r1
+
+	rsm     PSW_SM_QUIET,%r0	/* second "heavy weight" ctl op */
+	mtctl	%r0, %cr17	/* Clear IIASQ tail */
+	mtctl	%r0, %cr17	/* Clear IIASQ head */
+	mtctl	%r1, %ipsw
+	load32	4f, %r1
+	mtctl	%r1, %cr18	/* Set IIAOQ tail */
+	ldo	4(%r1), %r1
+	mtctl	%r1, %cr18	/* Set IIAOQ head */
+	rfir
+	nop
+4:
+	.endm
+
+	/*
+	 * The "get_stack" macros are responsible for determining the
+	 * kernel stack value.
+	 *
+	 *      If sr7 == 0
+	 *          Already using a kernel stack, so call the
+	 *          get_stack_use_r30 macro to push a pt_regs structure
+	 *          on the stack, and store registers there.
+	 *      else
+	 *          Need to set up a kernel stack, so call the
+	 *          get_stack_use_cr30 macro to set up a pointer
+	 *          to the pt_regs structure contained within the
+	 *          task pointer pointed to by cr30. Set the stack
+	 *          pointer to point to the end of the task structure.
+	 *
+	 * Note that we use shadowed registers for temps until
+	 * we can save %r26 and %r29. %r26 is used to preserve
+	 * %r8 (a shadowed register) which temporarily contained
+	 * either the fault type ("code") or the eirr. We need
+	 * to use a non-shadowed register to carry the value over
+	 * the rfir in virt_map. We use %r26 since this value winds
+	 * up being passed as the argument to either do_cpu_irq_mask
+	 * or handle_interruption. %r29 is used to hold a pointer
+	 * the register save area, and once again, it needs to
+	 * be a non-shadowed register so that it survives the rfir.
+	 *
+	 * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
+	 */
+
+	.macro  get_stack_use_cr30
+
+	/* we save the registers in the task struct */
+
+	copy	%r30, %r17
+	mfctl   %cr30, %r1
+	ldo	THREAD_SZ_ALGN(%r1), %r30
+	mtsp	%r0,%sr7
+	mtsp	%r16,%sr3
+	tophys  %r1,%r9
+	LDREG	TI_TASK(%r9), %r1	/* thread_info -> task_struct */
+	tophys  %r1,%r9
+	ldo     TASK_REGS(%r9),%r9
+	STREG   %r17,PT_GR30(%r9)
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
+	copy    %r9,%r29
+	.endm
+
+	.macro  get_stack_use_r30
+
+	/* we put a struct pt_regs on the stack and save the registers there */
+
+	tophys  %r30,%r9
+	copy	%r30,%r1
+	ldo	PT_SZ_ALGN(%r30),%r30
+	STREG   %r1,PT_GR30(%r9)
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
+	copy    %r9,%r29
+	.endm
+
+	.macro  rest_stack
+	LDREG   PT_GR1(%r29), %r1
+	LDREG   PT_GR30(%r29),%r30
+	LDREG   PT_GR29(%r29),%r29
+	.endm
+
+	/* default interruption handler
+	 * (calls traps.c:handle_interruption) */
+	.macro	def code
+	b	intr_save
+	ldi     \code, %r8
+	.align	32
+	.endm
+
+	/* Interrupt interruption handler
+	 * (calls irq.c:do_cpu_irq_mask) */
+	.macro	extint code
+	b	intr_extint
+	mfsp    %sr7,%r16
+	.align	32
+	.endm	
+
+	.import	os_hpmc, code
+
+	/* HPMC handler */
+	.macro	hpmc code
+	nop			/* must be a NOP, will be patched later */
+	load32	PA(os_hpmc), %r3
+	bv,n	0(%r3)
+	nop
+	.word	0		/* checksum (will be patched) */
+	.word	0		/* address of handler */
+	.word	0		/* length of handler */
+	.endm
+
+	/*
+	 * Performance Note: Instructions will be moved up into
+	 * this part of the code later on, once we are sure
+	 * that the tlb miss handlers are close to final form.
+	 */
+
+	/* Register definitions for tlb miss handler macros */
+
+	va  = r8	/* virtual address for which the trap occurred */
+	spc = r24	/* space for which the trap occurred */
+
+#ifndef CONFIG_64BIT
+
+	/*
+	 * itlb miss interruption handler (parisc 1.1 - 32 bit)
+	 */
+
+	.macro	itlb_11 code
+
+	mfctl	%pcsq, spc
+	b	itlb_miss_11
+	mfctl	%pcoq, va
+
+	.align		32
+	.endm
+#endif
+	
+	/*
+	 * itlb miss interruption handler (parisc 2.0)
+	 */
+
+	.macro	itlb_20 code
+	mfctl	%pcsq, spc
+#ifdef CONFIG_64BIT
+	b       itlb_miss_20w
+#else
+	b	itlb_miss_20
+#endif
+	mfctl	%pcoq, va
+
+	.align		32
+	.endm
+	
+#ifndef CONFIG_64BIT
+	/*
+	 * naitlb miss interruption handler (parisc 1.1 - 32 bit)
+	 */
+
+	.macro	naitlb_11 code
+
+	mfctl	%isr,spc
+	b	naitlb_miss_11
+	mfctl 	%ior,va
+
+	.align		32
+	.endm
+#endif
+	
+	/*
+	 * naitlb miss interruption handler (parisc 2.0)
+	 */
+
+	.macro	naitlb_20 code
+
+	mfctl	%isr,spc
+#ifdef CONFIG_64BIT
+	b       naitlb_miss_20w
+#else
+	b	naitlb_miss_20
+#endif
+	mfctl 	%ior,va
+
+	.align		32
+	.endm
+	
+#ifndef CONFIG_64BIT
+	/*
+	 * dtlb miss interruption handler (parisc 1.1 - 32 bit)
+	 */
+
+	.macro	dtlb_11 code
+
+	mfctl	%isr, spc
+	b	dtlb_miss_11
+	mfctl	%ior, va
+
+	.align		32
+	.endm
+#endif
+
+	/*
+	 * dtlb miss interruption handler (parisc 2.0)
+	 */
+
+	.macro	dtlb_20 code
+
+	mfctl	%isr, spc
+#ifdef CONFIG_64BIT
+	b       dtlb_miss_20w
+#else
+	b	dtlb_miss_20
+#endif
+	mfctl	%ior, va
+
+	.align		32
+	.endm
+	
+#ifndef CONFIG_64BIT
+	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
+
+	.macro	nadtlb_11 code
+
+	mfctl	%isr,spc
+	b       nadtlb_miss_11
+	mfctl	%ior,va
+
+	.align		32
+	.endm
+#endif
+	
+	/* nadtlb miss interruption handler (parisc 2.0) */
+
+	.macro	nadtlb_20 code
+
+	mfctl	%isr,spc
+#ifdef CONFIG_64BIT
+	b       nadtlb_miss_20w
+#else
+	b       nadtlb_miss_20
+#endif
+	mfctl	%ior,va
+
+	.align		32
+	.endm
+	
+#ifndef CONFIG_64BIT
+	/*
+	 * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
+	 */
+
+	.macro	dbit_11 code
+
+	mfctl	%isr,spc
+	b	dbit_trap_11
+	mfctl	%ior,va
+
+	.align		32
+	.endm
+#endif
+
+	/*
+	 * dirty bit trap interruption handler (parisc 2.0)
+	 */
+
+	.macro	dbit_20 code
+
+	mfctl	%isr,spc
+#ifdef CONFIG_64BIT
+	b       dbit_trap_20w
+#else
+	b	dbit_trap_20
+#endif
+	mfctl	%ior,va
+
+	.align		32
+	.endm
+
+	/* In LP64, the space contains part of the upper 32 bits of the
+	 * fault.  We have to extract this and place it in the va,
+	 * zeroing the corresponding bits in the space register */
+	.macro		space_adjust	spc,va,tmp
+#ifdef CONFIG_64BIT
+	extrd,u		\spc,63,SPACEID_SHIFT,\tmp
+	depd		%r0,63,SPACEID_SHIFT,\spc
+	depd		\tmp,31,SPACEID_SHIFT,\va
+#endif
+	.endm
+
+	.import		swapper_pg_dir,code
+
+	/* Get the pgd.  For faults on space zero (kernel space), this
+	 * is simply swapper_pg_dir.  For user space faults, the
+	 * pgd is stored in %cr25 */
+	.macro		get_pgd		spc,reg
+	ldil		L%PA(swapper_pg_dir),\reg
+	ldo		R%PA(swapper_pg_dir)(\reg),\reg
+	or,COND(=)	%r0,\spc,%r0
+	mfctl		%cr25,\reg
+	.endm
+
+	/* 
+		space_check(spc,tmp,fault)
+
+		spc - The space we saw the fault with.
+		tmp - The place to store the current space.
+		fault - Function to call on failure.
+
+		Only allow faults on different spaces from the
+		currently active one if we're the kernel 
+
+	*/
+	.macro		space_check	spc,tmp,fault
+	mfsp		%sr7,\tmp
+	or,COND(<>)	%r0,\spc,%r0	/* user may execute gateway page
+					 * as kernel, so defeat the space
+					 * check if it is */
+	copy		\spc,\tmp
+	or,COND(=)	%r0,\tmp,%r0	/* nullify if executing as kernel */
+	cmpb,COND(<>),n	\tmp,\spc,\fault
+	.endm
+
+	/* Look up a PTE in a 2-Level scheme (faulting at each
+	 * level if the entry isn't present 
+	 *
+	 * NOTE: we use ldw even for LP64, since the short pointers
+	 * can address up to 1TB
+	 */
+	.macro		L2_ptep	pmd,pte,index,va,fault
+#if CONFIG_PGTABLE_LEVELS == 3
+	extru		\va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
+#else
+# if defined(CONFIG_64BIT)
+	extrd,u		\va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
+  #else
+  # if PAGE_SIZE > 4096
+	extru		\va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index
+  # else
+	extru		\va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
+  # endif
+# endif
+#endif
+	dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
+	copy		%r0,\pte
+	ldw,s		\index(\pmd),\pmd
+	bb,>=,n		\pmd,_PxD_PRESENT_BIT,\fault
+	dep		%r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
+	copy		\pmd,%r9
+	SHLREG		%r9,PxD_VALUE_SHIFT,\pmd
+	extru		\va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
+	dep		%r0,31,PAGE_SHIFT,\pmd  /* clear offset */
+	shladd		\index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
+	LDREG		%r0(\pmd),\pte
+	bb,>=,n		\pte,_PAGE_PRESENT_BIT,\fault
+	.endm
+
+	/* Look up PTE in a 3-Level scheme.
+	 *
+	 * Here we implement a Hybrid L2/L3 scheme: we allocate the
+	 * first pmd adjacent to the pgd.  This means that we can
+	 * subtract a constant offset to get to it.  The pmd and pgd
+	 * sizes are arranged so that a single pmd covers 4GB (giving
+	 * a full LP64 process access to 8TB) so our lookups are
+	 * effectively L2 for the first 4GB of the kernel (i.e. for
+	 * all ILP32 processes and all the kernel for machines with
+	 * under 4GB of memory) */
+	.macro		L3_ptep pgd,pte,index,va,fault
+#if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
+	extrd,u		\va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
+	copy		%r0,\pte
+	extrd,u,*=	\va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
+	ldw,s		\index(\pgd),\pgd
+	extrd,u,*=	\va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
+	bb,>=,n		\pgd,_PxD_PRESENT_BIT,\fault
+	extrd,u,*=	\va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
+	shld		\pgd,PxD_VALUE_SHIFT,\index
+	extrd,u,*=	\va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
+	copy		\index,\pgd
+	extrd,u,*<>	\va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
+	ldo		ASM_PGD_PMD_OFFSET(\pgd),\pgd
+#endif
+	L2_ptep		\pgd,\pte,\index,\va,\fault
+	.endm
+
+	/* Acquire pa_tlb_lock lock and recheck page is still present. */
+	.macro		tlb_lock	spc,ptp,pte,tmp,tmp1,fault
+#ifdef CONFIG_SMP
+	cmpib,COND(=),n	0,\spc,2f
+	load_pa_tlb_lock \tmp
+1:	LDCW		0(\tmp),\tmp1
+	cmpib,COND(=)	0,\tmp1,1b
+	nop
+	LDREG		0(\ptp),\pte
+	bb,<,n		\pte,_PAGE_PRESENT_BIT,2f
+	b		\fault
+	stw		 \spc,0(\tmp)
+2:
+#endif
+	.endm
+
+	/* Release pa_tlb_lock lock without reloading lock address. */
+	.macro		tlb_unlock0	spc,tmp
+#ifdef CONFIG_SMP
+	or,COND(=)	%r0,\spc,%r0
+	sync
+	or,COND(=)	%r0,\spc,%r0
+	stw             \spc,0(\tmp)
+#endif
+	.endm
+
+	/* Release pa_tlb_lock lock. */
+	.macro		tlb_unlock1	spc,tmp
+#ifdef CONFIG_SMP
+	load_pa_tlb_lock \tmp
+	tlb_unlock0	\spc,\tmp
+#endif
+	.endm
+
+	/* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
+	 * don't needlessly dirty the cache line if it was already set */
+	.macro		update_accessed	ptp,pte,tmp,tmp1
+	ldi		_PAGE_ACCESSED,\tmp1
+	or		\tmp1,\pte,\tmp
+	and,COND(<>)	\tmp1,\pte,%r0
+	STREG		\tmp,0(\ptp)
+	.endm
+
+	/* Set the dirty bit (and accessed bit).  No need to be
+	 * clever, this is only used from the dirty fault */
+	.macro		update_dirty	ptp,pte,tmp
+	ldi		_PAGE_ACCESSED|_PAGE_DIRTY,\tmp
+	or		\tmp,\pte,\pte
+	STREG		\pte,0(\ptp)
+	.endm
+
+	/* We have (depending on the page size):
+	 * - 38 to 52-bit Physical Page Number
+	 * - 12 to 26-bit page offset
+	 */
+	/* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+	 * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+	#define PAGE_ADD_SHIFT		(PAGE_SHIFT-12)
+	#define PAGE_ADD_HUGE_SHIFT	(REAL_HPAGE_SHIFT-12)
+
+	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+	.macro		convert_for_tlb_insert20 pte,tmp
+#ifdef CONFIG_HUGETLB_PAGE
+	copy		\pte,\tmp
+	extrd,u		\tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+				64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+
+	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
+				(63-58)+PAGE_ADD_SHIFT,\pte
+	extrd,u,*=	\tmp,_PAGE_HPAGE_BIT+32,1,%r0
+	depdi		_HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
+				(63-58)+PAGE_ADD_HUGE_SHIFT,\pte
+#else /* Huge pages disabled */
+	extrd,u		\pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+				64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
+				(63-58)+PAGE_ADD_SHIFT,\pte
+#endif
+	.endm
+
+	/* Convert the pte and prot to tlb insertion values.  How
+	 * this happens is quite subtle, read below */
+	.macro		make_insert_tlb	spc,pte,prot,tmp
+	space_to_prot   \spc \prot        /* create prot id from space */
+	/* The following is the real subtlety.  This is depositing
+	 * T <-> _PAGE_REFTRAP
+	 * D <-> _PAGE_DIRTY
+	 * B <-> _PAGE_DMB (memory break)
+	 *
+	 * Then incredible subtlety: The access rights are
+	 * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE
+	 * See 3-14 of the parisc 2.0 manual
+	 *
+	 * Finally, _PAGE_READ goes in the top bit of PL1 (so we
+	 * trigger an access rights trap in user space if the user
+	 * tries to read an unreadable page */
+	depd            \pte,8,7,\prot
+
+	/* PAGE_USER indicates the page can be read with user privileges,
+	 * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
+	 * contains _PAGE_READ) */
+	extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
+	depdi		7,11,3,\prot
+	/* If we're a gateway page, drop PL2 back to zero for promotion
+	 * to kernel privilege (so we can execute the page as kernel).
+	 * Any privilege promotion page always denys read and write */
+	extrd,u,*= 	\pte,_PAGE_GATEWAY_BIT+32,1,%r0
+	depd		%r0,11,2,\prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Enforce uncacheable pages.
+	 * This should ONLY be use for MMIO on PA 2.0 machines.
+	 * Memory/DMA is cache coherent on all PA2.0 machines we support
+	 * (that means T-class is NOT supported) and the memory controllers
+	 * on most of those machines only handles cache transactions.
+	 */
+	extrd,u,*=	\pte,_PAGE_NO_CACHE_BIT+32,1,%r0
+	depdi		1,12,1,\prot
+
+	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+	convert_for_tlb_insert20 \pte \tmp
+	.endm
+
+	/* Identical macro to make_insert_tlb above, except it
+	 * makes the tlb entry for the differently formatted pa11
+	 * insertion instructions */
+	.macro		make_insert_tlb_11	spc,pte,prot
+	zdep		\spc,30,15,\prot
+	dep		\pte,8,7,\prot
+	extru,=		\pte,_PAGE_NO_CACHE_BIT,1,%r0
+	depi		1,12,1,\prot
+	extru,=         \pte,_PAGE_USER_BIT,1,%r0
+	depi		7,11,3,\prot   /* Set for user space (1 rsvd for read) */
+	extru,= 	\pte,_PAGE_GATEWAY_BIT,1,%r0
+	depi		0,11,2,\prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for iitlba */
+
+	depi		0,31,ASM_PFN_PTE_SHIFT,\pte
+	SHRREG		\pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
+	.endm
+
+	/* This is for ILP32 PA2.0 only.  The TLB insertion needs
+	 * to extend into I/O space if the address is 0xfXXXXXXX
+	 * so we extend the f's into the top word of the pte in
+	 * this case */
+	.macro		f_extend	pte,tmp
+	extrd,s		\pte,42,4,\tmp
+	addi,<>		1,\tmp,%r0
+	extrd,s		\pte,63,25,\pte
+	.endm
+
+	/* The alias region is an 8MB aligned 16MB to do clear and
+	 * copy user pages at addresses congruent with the user
+	 * virtual address.
+	 *
+	 * To use the alias page, you set %r26 up with the to TLB
+	 * entry (identifying the physical page) and %r23 up with
+	 * the from tlb entry (or nothing if only a to entry---for
+	 * clear_user_page_asm) */
+	.macro		do_alias	spc,tmp,tmp1,va,pte,prot,fault,patype
+	cmpib,COND(<>),n 0,\spc,\fault
+	ldil		L%(TMPALIAS_MAP_START),\tmp
+#if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
+	/* on LP64, ldi will sign extend into the upper 32 bits,
+	 * which is behaviour we don't want */
+	depdi		0,31,32,\tmp
+#endif
+	copy		\va,\tmp1
+	depi		0,31,23,\tmp1
+	cmpb,COND(<>),n	\tmp,\tmp1,\fault
+	mfctl		%cr19,\tmp	/* iir */
+	/* get the opcode (first six bits) into \tmp */
+	extrw,u		\tmp,5,6,\tmp
+	/*
+	 * Only setting the T bit prevents data cache movein
+	 * Setting access rights to zero prevents instruction cache movein
+	 *
+	 * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
+	 * to type field and _PAGE_READ goes to top bit of PL1
+	 */
+	ldi		(_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
+	/*
+	 * so if the opcode is one (i.e. this is a memory management
+	 * instruction) nullify the next load so \prot is only T.
+	 * Otherwise this is a normal data operation
+	 */
+	cmpiclr,=	0x01,\tmp,%r0
+	ldi		(_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
+.ifc \patype,20
+	depd,z		\prot,8,7,\prot
+.else
+.ifc \patype,11
+	depw,z		\prot,8,7,\prot
+.else
+	.error "undefined PA type to do_alias"
+.endif
+.endif
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+#ifdef CONFIG_64BIT
+	extrd,u,*=	\va,41,1,%r0
+#else
+	extrw,u,=	\va,9,1,%r0
+#endif
+	or,COND(tr)	%r23,%r0,\pte
+	or		%r26,%r0,\pte
+	.endm 
+
+
+	/*
+	 * Fault_vectors are architecturally required to be aligned on a 2K
+	 * boundary
+	 */
+
+	.section .text.hot
+	.align 2048
+
+ENTRY(fault_vector_20)
+	/* First vector is invalid (0) */
+	.ascii	"cows can fly"
+	.byte 0
+	.align 32
+
+	hpmc		 1
+	def		 2
+	def		 3
+	extint		 4
+	def		 5
+	itlb_20		 PARISC_ITLB_TRAP
+	def		 7
+	def		 8
+	def              9
+	def		10
+	def		11
+	def		12
+	def		13
+	def		14
+	dtlb_20		15
+	naitlb_20	16
+	nadtlb_20	17
+	def		18
+	def		19
+	dbit_20		20
+	def		21
+	def		22
+	def		23
+	def		24
+	def		25
+	def		26
+	def		27
+	def		28
+	def		29
+	def		30
+	def		31
+END(fault_vector_20)
+
+#ifndef CONFIG_64BIT
+
+	.align 2048
+
+ENTRY(fault_vector_11)
+	/* First vector is invalid (0) */
+	.ascii	"cows can fly"
+	.byte 0
+	.align 32
+
+	hpmc		 1
+	def		 2
+	def		 3
+	extint		 4
+	def		 5
+	itlb_11		 PARISC_ITLB_TRAP
+	def		 7
+	def		 8
+	def              9
+	def		10
+	def		11
+	def		12
+	def		13
+	def		14
+	dtlb_11		15
+	naitlb_11	16
+	nadtlb_11	17
+	def		18
+	def		19
+	dbit_11		20
+	def		21
+	def		22
+	def		23
+	def		24
+	def		25
+	def		26
+	def		27
+	def		28
+	def		29
+	def		30
+	def		31
+END(fault_vector_11)
+
+#endif
+	/* Fault vector is separately protected and *must* be on its own page */
+	.align		PAGE_SIZE
+
+	.import		handle_interruption,code
+	.import		do_cpu_irq_mask,code
+
+	/*
+	 * Child Returns here
+	 *
+	 * copy_thread moved args into task save area.
+	 */
+
+ENTRY(ret_from_kernel_thread)
+	/* Call schedule_tail first though */
+	BL	schedule_tail, %r2
+	nop
+
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
+	LDREG	TASK_PT_GR25(%r1), %r26
+#ifdef CONFIG_64BIT
+	LDREG	TASK_PT_GR27(%r1), %r27
+#endif
+	LDREG	TASK_PT_GR26(%r1), %r1
+	ble	0(%sr7, %r1)
+	copy	%r31, %r2
+	b	finish_child_return
+	nop
+END(ret_from_kernel_thread)
+
+
+	/*
+	 * struct task_struct *_switch_to(struct task_struct *prev,
+	 *	struct task_struct *next)
+	 *
+	 * switch kernel stacks and return prev */
+ENTRY_CFI(_switch_to)
+	STREG	 %r2, -RP_OFFSET(%r30)
+
+	callee_save_float
+	callee_save
+
+	load32	_switch_to_ret, %r2
+
+	STREG	%r2, TASK_PT_KPC(%r26)
+	LDREG	TASK_PT_KPC(%r25), %r2
+
+	STREG	%r30, TASK_PT_KSP(%r26)
+	LDREG	TASK_PT_KSP(%r25), %r30
+	LDREG	TASK_THREAD_INFO(%r25), %r25
+	bv	%r0(%r2)
+	mtctl   %r25,%cr30
+
+ENTRY(_switch_to_ret)
+	mtctl	%r0, %cr0		/* Needed for single stepping */
+	callee_rest
+	callee_rest_float
+
+	LDREG	-RP_OFFSET(%r30), %r2
+	bv	%r0(%r2)
+	copy	%r26, %r28
+ENDPROC_CFI(_switch_to)
+
+	/*
+	 * Common rfi return path for interruptions, kernel execve, and
+	 * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
+	 * return via this path if the signal was received when the process
+	 * was running; if the process was blocked on a syscall then the
+	 * normal syscall_exit path is used.  All syscalls for traced
+	 * proceses exit via intr_restore.
+	 *
+	 * XXX If any syscalls that change a processes space id ever exit
+	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
+	 * adjust IASQ[0..1].
+	 *
+	 */
+
+	.align	PAGE_SIZE
+
+ENTRY_CFI(syscall_exit_rfi)
+	mfctl   %cr30,%r16
+	LDREG	TI_TASK(%r16), %r16	/* thread_info -> task_struct */
+	ldo	TASK_REGS(%r16),%r16
+	/* Force iaoq to userspace, as the user has had access to our current
+	 * context via sigcontext. Also Filter the PSW for the same reason.
+	 */
+	LDREG	PT_IAOQ0(%r16),%r19
+	depi	3,31,2,%r19
+	STREG	%r19,PT_IAOQ0(%r16)
+	LDREG	PT_IAOQ1(%r16),%r19
+	depi	3,31,2,%r19
+	STREG	%r19,PT_IAOQ1(%r16)
+	LDREG   PT_PSW(%r16),%r19
+	load32	USER_PSW_MASK,%r1
+#ifdef CONFIG_64BIT
+	load32	USER_PSW_HI_MASK,%r20
+	depd    %r20,31,32,%r1
+#endif
+	and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
+	load32	USER_PSW,%r1
+	or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
+	STREG   %r19,PT_PSW(%r16)
+
+	/*
+	 * If we aren't being traced, we never saved space registers
+	 * (we don't store them in the sigcontext), so set them
+	 * to "proper" values now (otherwise we'll wind up restoring
+	 * whatever was last stored in the task structure, which might
+	 * be inconsistent if an interrupt occurred while on the gateway
+	 * page). Note that we may be "trashing" values the user put in
+	 * them, but we don't support the user changing them.
+	 */
+
+	STREG   %r0,PT_SR2(%r16)
+	mfsp    %sr3,%r19
+	STREG   %r19,PT_SR0(%r16)
+	STREG   %r19,PT_SR1(%r16)
+	STREG   %r19,PT_SR3(%r16)
+	STREG   %r19,PT_SR4(%r16)
+	STREG   %r19,PT_SR5(%r16)
+	STREG   %r19,PT_SR6(%r16)
+	STREG   %r19,PT_SR7(%r16)
+
+ENTRY(intr_return)
+	/* check for reschedule */
+	mfctl   %cr30,%r1
+	LDREG   TI_FLAGS(%r1),%r19	/* sched.h: TIF_NEED_RESCHED */
+	bb,<,n	%r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
+
+	.import do_notify_resume,code
+intr_check_sig:
+	/* As above */
+	mfctl   %cr30,%r1
+	LDREG	TI_FLAGS(%r1),%r19
+	ldi	(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20
+	and,COND(<>)	%r19, %r20, %r0
+	b,n	intr_restore	/* skip past if we've nothing to do */
+
+	/* This check is critical to having LWS
+	 * working. The IASQ is zero on the gateway
+	 * page and we cannot deliver any signals until
+	 * we get off the gateway page.
+	 *
+	 * Only do signals if we are returning to user space
+	 */
+	LDREG	PT_IASQ0(%r16), %r20
+	cmpib,COND(=),n 0,%r20,intr_restore /* backward */
+	LDREG	PT_IASQ1(%r16), %r20
+	cmpib,COND(=),n 0,%r20,intr_restore /* backward */
+
+	/* NOTE: We need to enable interrupts if we have to deliver
+	 * signals. We used to do this earlier but it caused kernel
+	 * stack overflows. */
+	ssm     PSW_SM_I, %r0
+
+	copy	%r0, %r25			/* long in_syscall = 0 */
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+
+	BL	do_notify_resume,%r2
+	copy	%r16, %r26			/* struct pt_regs *regs */
+
+	b,n	intr_check_sig
+
+intr_restore:
+	copy            %r16,%r29
+	ldo             PT_FR31(%r29),%r1
+	rest_fp         %r1
+	rest_general    %r29
+
+	/* inverse of virt_map */
+	pcxt_ssm_bug
+	rsm             PSW_SM_QUIET,%r0	/* prepare for rfi */
+	tophys_r1       %r29
+
+	/* Restore space id's and special cr's from PT_REGS
+	 * structure pointed to by r29
+	 */
+	rest_specials	%r29
+
+	/* IMPORTANT: rest_stack restores r29 last (we are using it)!
+	 * It also restores r1 and r30.
+	 */
+	rest_stack
+
+	rfi
+	nop
+
+#ifndef CONFIG_PREEMPT
+# define intr_do_preempt	intr_restore
+#endif /* !CONFIG_PREEMPT */
+
+	.import schedule,code
+intr_do_resched:
+	/* Only call schedule on return to userspace. If we're returning
+	 * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
+	 * we jump back to intr_restore.
+	 */
+	LDREG	PT_IASQ0(%r16), %r20
+	cmpib,COND(=)	0, %r20, intr_do_preempt
+	nop
+	LDREG	PT_IASQ1(%r16), %r20
+	cmpib,COND(=)	0, %r20, intr_do_preempt
+	nop
+
+	/* NOTE: We need to enable interrupts if we schedule.  We used
+	 * to do this earlier but it caused kernel stack overflows. */
+	ssm     PSW_SM_I, %r0
+
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
+
+	ldil	L%intr_check_sig, %r2
+#ifndef CONFIG_64BIT
+	b	schedule
+#else
+	load32	schedule, %r20
+	bv	%r0(%r20)
+#endif
+	ldo	R%intr_check_sig(%r2), %r2
+
+	/* preempt the current task on returning to kernel
+	 * mode from an interrupt, iff need_resched is set,
+	 * and preempt_count is 0. otherwise, we continue on
+	 * our merry way back to the current running task.
+	 */
+#ifdef CONFIG_PREEMPT
+	.import preempt_schedule_irq,code
+intr_do_preempt:
+	rsm	PSW_SM_I, %r0		/* disable interrupts */
+
+	/* current_thread_info()->preempt_count */
+	mfctl	%cr30, %r1
+	LDREG	TI_PRE_COUNT(%r1), %r19
+	cmpib,COND(<>)	0, %r19, intr_restore	/* if preempt_count > 0 */
+	nop				/* prev insn branched backwards */
+
+	/* check if we interrupted a critical path */
+	LDREG	PT_PSW(%r16), %r20
+	bb,<,n	%r20, 31 - PSW_SM_I, intr_restore
+	nop
+
+	BL	preempt_schedule_irq, %r2
+	nop
+
+	b,n	intr_restore		/* ssm PSW_SM_I done by intr_restore */
+#endif /* CONFIG_PREEMPT */
+
+	/*
+	 * External interrupts.
+	 */
+
+intr_extint:
+	cmpib,COND(=),n 0,%r16,1f
+
+	get_stack_use_cr30
+	b,n 2f
+
+1:
+	get_stack_use_r30
+2:
+	save_specials	%r29
+	virt_map
+	save_general	%r29
+
+	ldo	PT_FR0(%r29), %r24
+	save_fp	%r24
+	
+	loadgp
+
+	copy	%r29, %r26	/* arg0 is pt_regs */
+	copy	%r29, %r16	/* save pt_regs */
+
+	ldil	L%intr_return, %r2
+
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29	/* Reference param save area */
+#endif
+
+	b	do_cpu_irq_mask
+	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
+ENDPROC_CFI(syscall_exit_rfi)
+
+
+	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
+
+ENTRY_CFI(intr_save)		/* for os_hpmc */
+	mfsp    %sr7,%r16
+	cmpib,COND(=),n 0,%r16,1f
+	get_stack_use_cr30
+	b	2f
+	copy    %r8,%r26
+
+1:
+	get_stack_use_r30
+	copy    %r8,%r26
+
+2:
+	save_specials	%r29
+
+	/* If this trap is a itlb miss, skip saving/adjusting isr/ior */
+	cmpib,COND(=),n        PARISC_ITLB_TRAP,%r26,skip_save_ior
+
+
+	mfctl           %isr, %r16
+	nop		/* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
+	mfctl           %ior, %r17
+
+
+#ifdef CONFIG_64BIT
+	/*
+	 * If the interrupted code was running with W bit off (32 bit),
+	 * clear the b bits (bits 0 & 1) in the ior.
+	 * save_specials left ipsw value in r8 for us to test.
+	 */
+	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
+	depdi           0,1,2,%r17
+
+	/* adjust isr/ior: get high bits from isr and deposit in ior */
+	space_adjust	%r16,%r17,%r1
+#endif
+	STREG           %r16, PT_ISR(%r29)
+	STREG           %r17, PT_IOR(%r29)
+
+#if 0 && defined(CONFIG_64BIT)
+	/* Revisit when we have 64-bit code above 4Gb */
+	b,n		intr_save2
+
+skip_save_ior:
+	/* We have a itlb miss, and when executing code above 4 Gb on ILP64, we
+	 * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
+	 * above.
+	 */
+	extrd,u,*	%r8,PSW_W_BIT,1,%r1
+	cmpib,COND(=),n	1,%r1,intr_save2
+	LDREG		PT_IASQ0(%r29), %r16
+	LDREG		PT_IAOQ0(%r29), %r17
+	/* adjust iasq/iaoq */
+	space_adjust	%r16,%r17,%r1
+	STREG           %r16, PT_IASQ0(%r29)
+	STREG           %r17, PT_IAOQ0(%r29)
+#else
+skip_save_ior:
+#endif
+
+intr_save2:
+	virt_map
+	save_general	%r29
+
+	ldo		PT_FR0(%r29), %r25
+	save_fp		%r25
+	
+	loadgp
+
+	copy		%r29, %r25	/* arg1 is pt_regs */
+#ifdef CONFIG_64BIT
+	ldo		-16(%r30),%r29	/* Reference param save area */
+#endif
+
+	ldil		L%intr_check_sig, %r2
+	copy		%r25, %r16	/* save pt_regs */
+
+	b		handle_interruption
+	ldo		R%intr_check_sig(%r2), %r2
+ENDPROC_CFI(intr_save)
+
+
+	/*
+	 * Note for all tlb miss handlers:
+	 *
+	 * cr24 contains a pointer to the kernel address space
+	 * page directory.
+	 *
+	 * cr25 contains a pointer to the current user address
+	 * space page directory.
+	 *
+	 * sr3 will contain the space id of the user address space
+	 * of the current running thread while that thread is
+	 * running in the kernel.
+	 */
+
+	/*
+	 * register number allocations.  Note that these are all
+	 * in the shadowed registers
+	 */
+
+	t0 = r1		/* temporary register 0 */
+	va = r8		/* virtual address for which the trap occurred */
+	t1 = r9		/* temporary register 1 */
+	pte  = r16	/* pte/phys page # */
+	prot = r17	/* prot bits */
+	spc  = r24	/* space for which the trap occurred */
+	ptp = r25	/* page directory/page table pointer */
+
+#ifdef CONFIG_64BIT
+
+dtlb_miss_20w:
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,dtlb_fault
+
+	L3_ptep		ptp,pte,t0,va,dtlb_check_alias_20w
+
+	tlb_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_20w
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+	
+	idtlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+dtlb_check_alias_20w:
+	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,20
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20w:
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,nadtlb_fault
+
+	L3_ptep		ptp,pte,t0,va,nadtlb_check_alias_20w
+
+	tlb_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	idtlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+nadtlb_check_alias_20w:
+	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,20
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+#else
+
+dtlb_miss_11:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,dtlb_fault
+
+	L2_ptep		ptp,pte,t0,va,dtlb_check_alias_11
+
+	tlb_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_11
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb_11	spc,pte,prot
+
+	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t1, %sr1	/* Restore sr1 */
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+dtlb_check_alias_11:
+	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,11
+
+	idtlba          pte,(va)
+	idtlbp          prot,(va)
+
+	rfir
+	nop
+
+nadtlb_miss_11:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,nadtlb_fault
+
+	L2_ptep		ptp,pte,t0,va,nadtlb_check_alias_11
+
+	tlb_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_11
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb_11	spc,pte,prot
+
+	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t1, %sr1	/* Restore sr1 */
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+nadtlb_check_alias_11:
+	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,11
+
+	idtlba          pte,(va)
+	idtlbp          prot,(va)
+
+	rfir
+	nop
+
+dtlb_miss_20:
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,dtlb_fault
+
+	L2_ptep		ptp,pte,t0,va,dtlb_check_alias_20
+
+	tlb_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_20
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	f_extend	pte,t1
+
+	idtlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+dtlb_check_alias_20:
+	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,20
+	
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,nadtlb_fault
+
+	L2_ptep		ptp,pte,t0,va,nadtlb_check_alias_20
+
+	tlb_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_20
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	f_extend	pte,t1
+	
+	idtlbt		pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+nadtlb_check_alias_20:
+	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,20
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+#endif
+
+nadtlb_emulate:
+
+	/*
+	 * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
+	 * probei instructions. We don't want to fault for these
+	 * instructions (not only does it not make sense, it can cause
+	 * deadlocks, since some flushes are done with the mmap
+	 * semaphore held). If the translation doesn't exist, we can't
+	 * insert a translation, so have to emulate the side effects
+	 * of the instruction. Since we don't insert a translation
+	 * we can get a lot of faults during a flush loop, so it makes
+	 * sense to try to do it here with minimum overhead. We only
+	 * emulate fdc,fic,pdc,probew,prober instructions whose base 
+	 * and index registers are not shadowed. We defer everything 
+	 * else to the "slow" path.
+	 */
+
+	mfctl           %cr19,%r9 /* Get iir */
+
+	/* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
+	   Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
+
+	/* Checks for fdc,fdce,pdc,"fic,4f" only */
+	ldi             0x280,%r16
+	and             %r9,%r16,%r17
+	cmpb,<>,n       %r16,%r17,nadtlb_probe_check
+	bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
+	BL		get_register,%r25
+	extrw,u         %r9,15,5,%r8           /* Get index register # */
+	cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	copy            %r1,%r24
+	BL		get_register,%r25
+	extrw,u         %r9,10,5,%r8           /* Get base register # */
+	cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	BL		set_register,%r25
+	add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
+
+nadtlb_nullify:
+	mfctl           %ipsw,%r8
+	ldil            L%PSW_N,%r9
+	or              %r8,%r9,%r8            /* Set PSW_N */
+	mtctl           %r8,%ipsw
+
+	rfir
+	nop
+
+	/* 
+		When there is no translation for the probe address then we
+		must nullify the insn and return zero in the target register.
+		This will indicate to the calling code that it does not have 
+		write/read privileges to this address.
+
+		This should technically work for prober and probew in PA 1.1,
+		and also probe,r and probe,w in PA 2.0
+
+		WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
+		THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
+
+	*/
+nadtlb_probe_check:
+	ldi             0x80,%r16
+	and             %r9,%r16,%r17
+	cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
+	BL              get_register,%r25      /* Find the target register */
+	extrw,u         %r9,31,5,%r8           /* Get target register */
+	cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	BL		set_register,%r25
+	copy            %r0,%r1                /* Write zero to target register */
+	b nadtlb_nullify                       /* Nullify return insn */
+	nop
+
+
+#ifdef CONFIG_64BIT
+itlb_miss_20w:
+
+	/*
+	 * I miss is a little different, since we allow users to fault
+	 * on the gateway page which is in the kernel address space.
+	 */
+
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,itlb_fault
+
+	L3_ptep		ptp,pte,t0,va,itlb_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,itlb_fault
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+	
+	iitlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_miss_20w:
+
+	/*
+	 * I miss is a little different, since we allow users to fault
+	 * on the gateway page which is in the kernel address space.
+	 */
+
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,naitlb_fault
+
+	L3_ptep		ptp,pte,t0,va,naitlb_check_alias_20w
+
+	tlb_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_20w
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	iitlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_check_alias_20w:
+	do_alias	spc,t0,t1,va,pte,prot,naitlb_fault,20
+
+	iitlbt		pte,prot
+
+	rfir
+	nop
+
+#else
+
+itlb_miss_11:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,itlb_fault
+
+	L2_ptep		ptp,pte,t0,va,itlb_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,itlb_fault
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb_11	spc,pte,prot
+
+	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	iitlba		pte,(%sr1,va)
+	iitlbp		prot,(%sr1,va)
+
+	mtsp		t1, %sr1	/* Restore sr1 */
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_miss_11:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,naitlb_fault
+
+	L2_ptep		ptp,pte,t0,va,naitlb_check_alias_11
+
+	tlb_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_11
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb_11	spc,pte,prot
+
+	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	iitlba		pte,(%sr1,va)
+	iitlbp		prot,(%sr1,va)
+
+	mtsp		t1, %sr1	/* Restore sr1 */
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_check_alias_11:
+	do_alias	spc,t0,t1,va,pte,prot,itlb_fault,11
+
+	iitlba          pte,(%sr0, va)
+	iitlbp          prot,(%sr0, va)
+
+	rfir
+	nop
+
+
+itlb_miss_20:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,itlb_fault
+
+	L2_ptep		ptp,pte,t0,va,itlb_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,itlb_fault
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	f_extend	pte,t1
+
+	iitlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_miss_20:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,naitlb_fault
+
+	L2_ptep		ptp,pte,t0,va,naitlb_check_alias_20
+
+	tlb_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_20
+	update_accessed	ptp,pte,t0,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	f_extend	pte,t1
+
+	iitlbt          pte,prot
+
+	tlb_unlock1	spc,t0
+	rfir
+	nop
+
+naitlb_check_alias_20:
+	do_alias	spc,t0,t1,va,pte,prot,naitlb_fault,20
+
+	iitlbt          pte,prot
+
+	rfir
+	nop
+
+#endif
+
+#ifdef CONFIG_64BIT
+
+dbit_trap_20w:
+	space_adjust	spc,va,t0
+	get_pgd		spc,ptp
+	space_check	spc,t0,dbit_fault
+
+	L3_ptep		ptp,pte,t0,va,dbit_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,dbit_fault
+	update_dirty	ptp,pte,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+		
+	idtlbt          pte,prot
+
+	tlb_unlock0	spc,t0
+	rfir
+	nop
+#else
+
+dbit_trap_11:
+
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,dbit_fault
+
+	L2_ptep		ptp,pte,t0,va,dbit_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,dbit_fault
+	update_dirty	ptp,pte,t1
+
+	make_insert_tlb_11	spc,pte,prot
+
+	mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp            t1, %sr1     /* Restore sr1 */
+
+	tlb_unlock0	spc,t0
+	rfir
+	nop
+
+dbit_trap_20:
+	get_pgd		spc,ptp
+
+	space_check	spc,t0,dbit_fault
+
+	L2_ptep		ptp,pte,t0,va,dbit_fault
+
+	tlb_lock	spc,ptp,pte,t0,t1,dbit_fault
+	update_dirty	ptp,pte,t1
+
+	make_insert_tlb	spc,pte,prot,t1
+
+	f_extend	pte,t1
+	
+	idtlbt		pte,prot
+
+	tlb_unlock0	spc,t0
+	rfir
+	nop
+#endif
+
+	.import handle_interruption,code
+
+kernel_bad_space:
+	b               intr_save
+	ldi             31,%r8  /* Use an unused code */
+
+dbit_fault:
+	b               intr_save
+	ldi             20,%r8
+
+itlb_fault:
+	b               intr_save
+	ldi             6,%r8
+
+nadtlb_fault:
+	b               intr_save
+	ldi             17,%r8
+
+naitlb_fault:
+	b               intr_save
+	ldi             16,%r8
+
+dtlb_fault:
+	b               intr_save
+	ldi             15,%r8
+
+	/* Register saving semantics for system calls:
+
+	   %r1		   clobbered by system call macro in userspace
+	   %r2		   saved in PT_REGS by gateway page
+	   %r3  - %r18	   preserved by C code (saved by signal code)
+	   %r19 - %r20	   saved in PT_REGS by gateway page
+	   %r21 - %r22	   non-standard syscall args
+			   stored in kernel stack by gateway page
+	   %r23 - %r26	   arg3-arg0, saved in PT_REGS by gateway page
+	   %r27 - %r30	   saved in PT_REGS by gateway page
+	   %r31		   syscall return pointer
+	 */
+
+	/* Floating point registers (FIXME: what do we do with these?)
+
+	   %fr0  - %fr3	   status/exception, not preserved
+	   %fr4  - %fr7	   arguments
+	   %fr8	 - %fr11   not preserved by C code
+	   %fr12 - %fr21   preserved by C code
+	   %fr22 - %fr31   not preserved by C code
+	 */
+
+	.macro	reg_save regs
+	STREG	%r3, PT_GR3(\regs)
+	STREG	%r4, PT_GR4(\regs)
+	STREG	%r5, PT_GR5(\regs)
+	STREG	%r6, PT_GR6(\regs)
+	STREG	%r7, PT_GR7(\regs)
+	STREG	%r8, PT_GR8(\regs)
+	STREG	%r9, PT_GR9(\regs)
+	STREG   %r10,PT_GR10(\regs)
+	STREG   %r11,PT_GR11(\regs)
+	STREG   %r12,PT_GR12(\regs)
+	STREG   %r13,PT_GR13(\regs)
+	STREG   %r14,PT_GR14(\regs)
+	STREG   %r15,PT_GR15(\regs)
+	STREG   %r16,PT_GR16(\regs)
+	STREG   %r17,PT_GR17(\regs)
+	STREG   %r18,PT_GR18(\regs)
+	.endm
+
+	.macro	reg_restore regs
+	LDREG	PT_GR3(\regs), %r3
+	LDREG	PT_GR4(\regs), %r4
+	LDREG	PT_GR5(\regs), %r5
+	LDREG	PT_GR6(\regs), %r6
+	LDREG	PT_GR7(\regs), %r7
+	LDREG	PT_GR8(\regs), %r8
+	LDREG	PT_GR9(\regs), %r9
+	LDREG   PT_GR10(\regs),%r10
+	LDREG   PT_GR11(\regs),%r11
+	LDREG   PT_GR12(\regs),%r12
+	LDREG   PT_GR13(\regs),%r13
+	LDREG   PT_GR14(\regs),%r14
+	LDREG   PT_GR15(\regs),%r15
+	LDREG   PT_GR16(\regs),%r16
+	LDREG   PT_GR17(\regs),%r17
+	LDREG   PT_GR18(\regs),%r18
+	.endm
+
+	.macro	fork_like name
+ENTRY_CFI(sys_\name\()_wrapper)
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
+	ldo	TASK_REGS(%r1),%r1
+	reg_save %r1
+	mfctl	%cr27, %r28
+	ldil	L%sys_\name, %r31
+	be	R%sys_\name(%sr4,%r31)
+	STREG	%r28, PT_CR27(%r1)
+ENDPROC_CFI(sys_\name\()_wrapper)
+	.endm
+
+fork_like clone
+fork_like fork
+fork_like vfork
+
+	/* Set the return value for the child */
+ENTRY(child_return)
+	BL	schedule_tail, %r2
+	nop
+finish_child_return:
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
+	ldo	TASK_REGS(%r1),%r1	 /* get pt regs */
+
+	LDREG	PT_CR27(%r1), %r3
+	mtctl	%r3, %cr27
+	reg_restore %r1
+	b	syscall_exit
+	copy	%r0,%r28
+END(child_return)
+
+ENTRY_CFI(sys_rt_sigreturn_wrapper)
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
+	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
+	/* Don't save regs, we are going to restore them from sigcontext. */
+	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef CONFIG_64BIT
+	ldo	FRAME_SIZE(%r30), %r30
+	BL	sys_rt_sigreturn,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
+	BL	sys_rt_sigreturn,%r2
+	ldo	FRAME_SIZE(%r30), %r30
+#endif
+
+	ldo	-FRAME_SIZE(%r30), %r30
+	LDREG	-RP_OFFSET(%r30), %r2
+
+	/* FIXME: I think we need to restore a few more things here. */
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
+	reg_restore %r1
+
+	/* If the signal was received while the process was blocked on a
+	 * syscall, then r2 will take us to syscall_exit; otherwise r2 will
+	 * take us to syscall_exit_rfi and on to intr_return.
+	 */
+	bv	%r0(%r2)
+	LDREG	PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
+ENDPROC_CFI(sys_rt_sigreturn_wrapper)
+
+ENTRY(syscall_exit)
+	/* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
+	 * via syscall_exit_rfi if the signal was received while the process
+	 * was running.
+	 */
+
+	/* save return value now */
+
+	mfctl     %cr30, %r1
+	LDREG     TI_TASK(%r1),%r1
+	STREG     %r28,TASK_PT_GR28(%r1)
+
+	/* Seems to me that dp could be wrong here, if the syscall involved
+	 * calling a module, and nothing got round to restoring dp on return.
+	 */
+	loadgp
+
+syscall_check_resched:
+
+	/* check for reschedule */
+
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
+	bb,<,n	%r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
+
+	.import do_signal,code
+syscall_check_sig:
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
+	ldi	(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26
+	and,COND(<>)	%r19, %r26, %r0
+	b,n	syscall_restore	/* skip past if we've nothing to do */
+
+syscall_do_signal:
+	/* Save callee-save registers (for sigcontext).
+	 * FIXME: After this point the process structure should be
+	 * consistent with all the relevant state of the process
+	 * before the syscall.  We need to verify this.
+	 */
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1), %r26		/* struct pt_regs *regs */
+	reg_save %r26
+
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+
+	BL	do_notify_resume,%r2
+	ldi	1, %r25				/* long in_syscall = 1 */
+
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */
+	reg_restore %r20
+
+	b,n     syscall_check_sig
+
+syscall_restore:
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+
+	/* Are we being ptraced? */
+	ldw	TASK_FLAGS(%r1),%r19
+	ldi	_TIF_SYSCALL_TRACE_MASK,%r2
+	and,COND(=)	%r19,%r2,%r0
+	b,n	syscall_restore_rfi
+
+	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
+	rest_fp	%r19
+
+	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
+	mtsar	%r19
+
+	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */
+	LDREG	TASK_PT_GR19(%r1),%r19
+	LDREG   TASK_PT_GR20(%r1),%r20
+	LDREG	TASK_PT_GR21(%r1),%r21
+	LDREG	TASK_PT_GR22(%r1),%r22
+	LDREG	TASK_PT_GR23(%r1),%r23
+	LDREG	TASK_PT_GR24(%r1),%r24
+	LDREG	TASK_PT_GR25(%r1),%r25
+	LDREG	TASK_PT_GR26(%r1),%r26
+	LDREG	TASK_PT_GR27(%r1),%r27	   /* restore user dp */
+	LDREG	TASK_PT_GR28(%r1),%r28	   /* syscall return value */
+	LDREG	TASK_PT_GR29(%r1),%r29
+	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */
+
+	/* NOTE: We use rsm/ssm pair to make this operation atomic */
+	LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
+	rsm     PSW_SM_I, %r0
+	copy    %r1,%r30                           /* Restore user sp */
+	mfsp    %sr3,%r1                           /* Get user space id */
+	mtsp    %r1,%sr7                           /* Restore sr7 */
+	ssm     PSW_SM_I, %r0
+
+	/* Set sr2 to zero for userspace syscalls to work. */
+	mtsp	%r0,%sr2 
+	mtsp	%r1,%sr4			   /* Restore sr4 */
+	mtsp	%r1,%sr5			   /* Restore sr5 */
+	mtsp	%r1,%sr6			   /* Restore sr6 */
+
+	depi	3,31,2,%r31			   /* ensure return to user mode. */
+
+#ifdef CONFIG_64BIT
+	/* decide whether to reset the wide mode bit
+	 *
+	 * For a syscall, the W bit is stored in the lowest bit
+	 * of sp.  Extract it and reset W if it is zero */
+	extrd,u,*<>	%r30,63,1,%r1
+	rsm	PSW_SM_W, %r0
+	/* now reset the lowest bit of sp if it was set */
+	xor	%r30,%r1,%r30
+#endif
+	be,n    0(%sr3,%r31)                       /* return to user space */
+
+	/* We have to return via an RFI, so that PSW T and R bits can be set
+	 * appropriately.
+	 * This sets up pt_regs so we can return via intr_restore, which is not
+	 * the most efficient way of doing things, but it works.
+	 */
+syscall_restore_rfi:
+	ldo	-1(%r0),%r2			   /* Set recovery cntr to -1 */
+	mtctl	%r2,%cr0			   /*   for immediate trap */
+	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */
+	ldi	0x0b,%r20			   /* Create new PSW */
+	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */
+
+	/* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
+	 * set in thread_info.h and converted to PA bitmap
+	 * numbers in asm-offsets.c */
+
+	/* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
+	extru,=	%r19,TIF_SINGLESTEP_PA_BIT,1,%r0
+	depi	-1,27,1,%r20			   /* R bit */
+
+	/* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
+	extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
+	depi	-1,7,1,%r20			   /* T bit */
+
+	STREG	%r20,TASK_PT_PSW(%r1)
+
+	/* Always store space registers, since sr3 can be changed (e.g. fork) */
+
+	mfsp    %sr3,%r25
+	STREG   %r25,TASK_PT_SR3(%r1)
+	STREG   %r25,TASK_PT_SR4(%r1)
+	STREG   %r25,TASK_PT_SR5(%r1)
+	STREG   %r25,TASK_PT_SR6(%r1)
+	STREG   %r25,TASK_PT_SR7(%r1)
+	STREG   %r25,TASK_PT_IASQ0(%r1)
+	STREG   %r25,TASK_PT_IASQ1(%r1)
+
+	/* XXX W bit??? */
+	/* Now if old D bit is clear, it means we didn't save all registers
+	 * on syscall entry, so do that now.  This only happens on TRACEME
+	 * calls, or if someone attached to us while we were on a syscall.
+	 * We could make this more efficient by not saving r3-r18, but
+	 * then we wouldn't be able to use the common intr_restore path.
+	 * It is only for traced processes anyway, so performance is not
+	 * an issue.
+	 */
+	bb,<	%r2,30,pt_regs_ok		   /* Branch if D set */
+	ldo	TASK_REGS(%r1),%r25
+	reg_save %r25				   /* Save r3 to r18 */
+
+	/* Save the current sr */
+	mfsp	%sr0,%r2
+	STREG	%r2,TASK_PT_SR0(%r1)
+
+	/* Save the scratch sr */
+	mfsp	%sr1,%r2
+	STREG	%r2,TASK_PT_SR1(%r1)
+
+	/* sr2 should be set to zero for userspace syscalls */
+	STREG	%r0,TASK_PT_SR2(%r1)
+
+	LDREG	TASK_PT_GR31(%r1),%r2
+	depi	3,31,2,%r2		   /* ensure return to user mode. */
+	STREG   %r2,TASK_PT_IAOQ0(%r1)
+	ldo	4(%r2),%r2
+	STREG	%r2,TASK_PT_IAOQ1(%r1)
+	b	intr_restore
+	copy	%r25,%r16
+
+pt_regs_ok:
+	LDREG	TASK_PT_IAOQ0(%r1),%r2
+	depi	3,31,2,%r2		   /* ensure return to user mode. */
+	STREG	%r2,TASK_PT_IAOQ0(%r1)
+	LDREG	TASK_PT_IAOQ1(%r1),%r2
+	depi	3,31,2,%r2
+	STREG	%r2,TASK_PT_IAOQ1(%r1)
+	b	intr_restore
+	copy	%r25,%r16
+
+syscall_do_resched:
+	load32	syscall_check_resched,%r2 /* if resched, we start over again */
+	load32	schedule,%r19
+	bv	%r0(%r19)		/* jumps to schedule() */
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
+	nop
+#endif
+END(syscall_exit)
+
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+	.import ftrace_function_trampoline,code
+	.align L1_CACHE_BYTES
+ENTRY_CFI(mcount, caller)
+_mcount:
+	.export _mcount,data
+	/*
+	 * The 64bit mcount() function pointer needs 4 dwords, of which the
+	 * first two are free.  We optimize it here and put 2 instructions for
+	 * calling mcount(), and 2 instructions for ftrace_stub().  That way we
+	 * have all on one L1 cacheline.
+	 */
+	b	ftrace_function_trampoline
+	copy	%r3, %arg2	/* caller original %sp */
+ftrace_stub:
+	.globl ftrace_stub
+        .type  ftrace_stub, @function
+#ifdef CONFIG_64BIT
+	bve	(%rp)
+#else
+	bv	%r0(%rp)
+#endif
+	nop
+#ifdef CONFIG_64BIT
+	.dword mcount
+	.dword 0 /* code in head.S puts value of global gp here */
+#endif
+ENDPROC_CFI(mcount)
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.align 8
+ENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE)
+	.export parisc_return_to_handler,data
+parisc_return_to_handler:
+	copy %r3,%r1
+	STREG %r0,-RP_OFFSET(%sp)	/* store 0 as %rp */
+	copy %sp,%r3
+	STREGM %r1,FRAME_SIZE(%sp)
+	STREG %ret0,8(%r3)
+	STREG %ret1,16(%r3)
+
+#ifdef CONFIG_64BIT
+	loadgp
+#endif
+
+	/* call ftrace_return_to_handler(0) */
+	.import ftrace_return_to_handler,code
+	load32 ftrace_return_to_handler,%ret0
+	load32 .Lftrace_ret,%r2
+#ifdef CONFIG_64BIT
+	ldo -16(%sp),%ret1		/* Reference param save area */
+	bve	(%ret0)
+#else
+	bv	%r0(%ret0)
+#endif
+	ldi 0,%r26
+.Lftrace_ret:
+	copy %ret0,%rp
+
+	/* restore original return values */
+	LDREG 8(%r3),%ret0
+	LDREG 16(%r3),%ret1
+
+	/* return from function */
+#ifdef CONFIG_64BIT
+	bve	(%rp)
+#else
+	bv	%r0(%rp)
+#endif
+	LDREGM -FRAME_SIZE(%sp),%r3
+ENDPROC_CFI(return_to_handler)
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#endif	/* CONFIG_FUNCTION_TRACER */
+
+#ifdef CONFIG_IRQSTACKS
+/* void call_on_stack(unsigned long param1, void *func,
+		      unsigned long new_stack) */
+ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
+ENTRY(_call_on_stack)
+	copy	%sp, %r1
+
+	/* Regarding the HPPA calling conventions for function pointers,
+	   we assume the PIC register is not changed across call.  For
+	   CONFIG_64BIT, the argument pointer is left to point at the
+	   argument region allocated for the call to call_on_stack. */
+
+	/* Switch to new stack.  We allocate two frames.  */
+	ldo	2*FRAME_SIZE(%arg2), %sp
+# ifdef CONFIG_64BIT
+	/* Save previous stack pointer and return pointer in frame marker */
+	STREG	%rp, -FRAME_SIZE-RP_OFFSET(%sp)
+	/* Calls always use function descriptor */
+	LDREG	16(%arg1), %arg1
+	bve,l	(%arg1), %rp
+	STREG	%r1, -FRAME_SIZE-REG_SZ(%sp)
+	LDREG	-FRAME_SIZE-RP_OFFSET(%sp), %rp
+	bve	(%rp)
+	LDREG	-FRAME_SIZE-REG_SZ(%sp), %sp
+# else
+	/* Save previous stack pointer and return pointer in frame marker */
+	STREG	%r1, -FRAME_SIZE-REG_SZ(%sp)
+	STREG	%rp, -FRAME_SIZE-RP_OFFSET(%sp)
+	/* Calls use function descriptor if PLABEL bit is set */
+	bb,>=,n	%arg1, 30, 1f
+	depwi	0,31,2, %arg1
+	LDREG	0(%arg1), %arg1
+1:
+	be,l	0(%sr4,%arg1), %sr0, %r31
+	copy	%r31, %rp
+	LDREG	-FRAME_SIZE-RP_OFFSET(%sp), %rp
+	bv	(%rp)
+	LDREG	-FRAME_SIZE-REG_SZ(%sp), %sp
+# endif /* CONFIG_64BIT */
+ENDPROC_CFI(call_on_stack)
+#endif /* CONFIG_IRQSTACKS */
+
+ENTRY_CFI(get_register)
+	/*
+	 * get_register is used by the non access tlb miss handlers to
+	 * copy the value of the general register specified in r8 into
+	 * r1. This routine can't be used for shadowed registers, since
+	 * the rfir will restore the original value. So, for the shadowed
+	 * registers we put a -1 into r1 to indicate that the register
+	 * should not be used (the register being copied could also have
+	 * a -1 in it, but that is OK, it just means that we will have
+	 * to use the slow path instead).
+	 */
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 */
+	copy    %r0,%r1
+	bv      %r0(%r25)    /* r1 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r2,%r1
+	bv      %r0(%r25)    /* r3 */
+	copy    %r3,%r1
+	bv      %r0(%r25)    /* r4 */
+	copy    %r4,%r1
+	bv      %r0(%r25)    /* r5 */
+	copy    %r5,%r1
+	bv      %r0(%r25)    /* r6 */
+	copy    %r6,%r1
+	bv      %r0(%r25)    /* r7 */
+	copy    %r7,%r1
+	bv      %r0(%r25)    /* r8 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r9 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r10 */
+	copy    %r10,%r1
+	bv      %r0(%r25)    /* r11 */
+	copy    %r11,%r1
+	bv      %r0(%r25)    /* r12 */
+	copy    %r12,%r1
+	bv      %r0(%r25)    /* r13 */
+	copy    %r13,%r1
+	bv      %r0(%r25)    /* r14 */
+	copy    %r14,%r1
+	bv      %r0(%r25)    /* r15 */
+	copy    %r15,%r1
+	bv      %r0(%r25)    /* r16 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r17 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r18 */
+	copy    %r18,%r1
+	bv      %r0(%r25)    /* r19 */
+	copy    %r19,%r1
+	bv      %r0(%r25)    /* r20 */
+	copy    %r20,%r1
+	bv      %r0(%r25)    /* r21 */
+	copy    %r21,%r1
+	bv      %r0(%r25)    /* r22 */
+	copy    %r22,%r1
+	bv      %r0(%r25)    /* r23 */
+	copy    %r23,%r1
+	bv      %r0(%r25)    /* r24 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r25 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r26 */
+	copy    %r26,%r1
+	bv      %r0(%r25)    /* r27 */
+	copy    %r27,%r1
+	bv      %r0(%r25)    /* r28 */
+	copy    %r28,%r1
+	bv      %r0(%r25)    /* r29 */
+	copy    %r29,%r1
+	bv      %r0(%r25)    /* r30 */
+	copy    %r30,%r1
+	bv      %r0(%r25)    /* r31 */
+	copy    %r31,%r1
+ENDPROC_CFI(get_register)
+
+
+ENTRY_CFI(set_register)
+	/*
+	 * set_register is used by the non access tlb miss handlers to
+	 * copy the value of r1 into the general register specified in
+	 * r8.
+	 */
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
+	copy    %r1,%r0
+	bv      %r0(%r25)    /* r1 */
+	copy    %r1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r1,%r2
+	bv      %r0(%r25)    /* r3 */
+	copy    %r1,%r3
+	bv      %r0(%r25)    /* r4 */
+	copy    %r1,%r4
+	bv      %r0(%r25)    /* r5 */
+	copy    %r1,%r5
+	bv      %r0(%r25)    /* r6 */
+	copy    %r1,%r6
+	bv      %r0(%r25)    /* r7 */
+	copy    %r1,%r7
+	bv      %r0(%r25)    /* r8 */
+	copy    %r1,%r8
+	bv      %r0(%r25)    /* r9 */
+	copy    %r1,%r9
+	bv      %r0(%r25)    /* r10 */
+	copy    %r1,%r10
+	bv      %r0(%r25)    /* r11 */
+	copy    %r1,%r11
+	bv      %r0(%r25)    /* r12 */
+	copy    %r1,%r12
+	bv      %r0(%r25)    /* r13 */
+	copy    %r1,%r13
+	bv      %r0(%r25)    /* r14 */
+	copy    %r1,%r14
+	bv      %r0(%r25)    /* r15 */
+	copy    %r1,%r15
+	bv      %r0(%r25)    /* r16 */
+	copy    %r1,%r16
+	bv      %r0(%r25)    /* r17 */
+	copy    %r1,%r17
+	bv      %r0(%r25)    /* r18 */
+	copy    %r1,%r18
+	bv      %r0(%r25)    /* r19 */
+	copy    %r1,%r19
+	bv      %r0(%r25)    /* r20 */
+	copy    %r1,%r20
+	bv      %r0(%r25)    /* r21 */
+	copy    %r1,%r21
+	bv      %r0(%r25)    /* r22 */
+	copy    %r1,%r22
+	bv      %r0(%r25)    /* r23 */
+	copy    %r1,%r23
+	bv      %r0(%r25)    /* r24 */
+	copy    %r1,%r24
+	bv      %r0(%r25)    /* r25 */
+	copy    %r1,%r25
+	bv      %r0(%r25)    /* r26 */
+	copy    %r1,%r26
+	bv      %r0(%r25)    /* r27 */
+	copy    %r1,%r27
+	bv      %r0(%r25)    /* r28 */
+	copy    %r1,%r28
+	bv      %r0(%r25)    /* r29 */
+	copy    %r1,%r29
+	bv      %r0(%r25)    /* r30 */
+	copy    %r1,%r30
+	bv      %r0(%r25)    /* r31 */
+	copy    %r1,%r31
+ENDPROC_CFI(set_register)
+
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
new file mode 100644
index 0000000..6d471c0
--- /dev/null
+++ b/arch/parisc/kernel/firmware.c
@@ -0,0 +1,1700 @@
+/*
+ * arch/parisc/kernel/firmware.c  - safe PDC access routines
+ *
+ *	PDC == Processor Dependent Code
+ *
+ * See http://www.parisc-linux.org/documentation/index.html
+ * for documentation describing the entry points and calling
+ * conventions defined below.
+ *
+ * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
+ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 2003 Grant Grundler <grundler parisc-linux org>
+ * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
+ * Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ *    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.
+ *
+ */
+
+/*	I think it would be in everyone's best interest to follow this
+ *	guidelines when writing PDC wrappers:
+ *
+ *	 - the name of the pdc wrapper should match one of the macros
+ *	   used for the first two arguments
+ *	 - don't use caps for random parts of the name
+ *	 - use the static PDC result buffers and "copyout" to structs
+ *	   supplied by the caller to encapsulate alignment restrictions
+ *	 - hold pdc_lock while in PDC or using static result buffers
+ *	 - use __pa() to convert virtual (kernel) pointers to physical
+ *	   ones.
+ *	 - the name of the struct used for pdc return values should equal
+ *	   one of the macros used for the first two arguments to the
+ *	   corresponding PDC call
+ *	 - keep the order of arguments
+ *	 - don't be smart (setting trailing NUL bytes for strings, return
+ *	   something useful even if the call failed) unless you are sure
+ *	   it's not going to affect functionality or performance
+ *
+ *	Example:
+ *	int pdc_cache_info(struct pdc_cache_info *cache_info )
+ *	{
+ *		int retval;
+ *
+ *		spin_lock_irq(&pdc_lock);
+ *		retval = mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
+ *		convert_to_wide(pdc_result);
+ *		memcpy(cache_info, pdc_result, sizeof(*cache_info));
+ *		spin_unlock_irq(&pdc_lock);
+ *
+ *		return retval;
+ *	}
+ *					prumpf	991016	
+ */
+
+#include <stdarg.h>
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+
+#include <asm/page.h>
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
+#include <asm/processor.h>	/* for boot_cpu_data */
+
+#if defined(BOOTLOADER)
+# undef  spin_lock_irqsave
+# define spin_lock_irqsave(a, b) { b = 1; }
+# undef  spin_unlock_irqrestore
+# define spin_unlock_irqrestore(a, b)
+#else
+static DEFINE_SPINLOCK(pdc_lock);
+#endif
+
+extern unsigned long pdc_result[NUM_PDC_RESULT];
+extern unsigned long pdc_result2[NUM_PDC_RESULT];
+
+#ifdef CONFIG_64BIT
+#define WIDE_FIRMWARE 0x1
+#define NARROW_FIRMWARE 0x2
+
+/* Firmware needs to be initially set to narrow to determine the 
+ * actual firmware width. */
+int parisc_narrow_firmware __read_mostly = 1;
+#endif
+
+/* On most currently-supported platforms, IODC I/O calls are 32-bit calls
+ * and MEM_PDC calls are always the same width as the OS.
+ * Some PAT boxes may have 64-bit IODC I/O.
+ *
+ * Ryan Bradetich added the now obsolete CONFIG_PDC_NARROW to allow
+ * 64-bit kernels to run on systems with 32-bit MEM_PDC calls.
+ * This allowed wide kernels to run on Cxxx boxes.
+ * We now detect 32-bit-only PDC and dynamically switch to 32-bit mode
+ * when running a 64-bit kernel on such boxes (e.g. C200 or C360).
+ */
+
+#ifdef CONFIG_64BIT
+long real64_call(unsigned long function, ...);
+#endif
+long real32_call(unsigned long function, ...);
+
+#ifdef CONFIG_64BIT
+#   define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
+#   define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args)
+#else
+#   define MEM_PDC (unsigned long)PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real32_call(MEM_PDC, args)
+#endif
+
+
+/**
+ * f_extend - Convert PDC addresses to kernel addresses.
+ * @address: Address returned from PDC.
+ *
+ * This function is used to convert PDC addresses into kernel addresses
+ * when the PDC address size and kernel address size are different.
+ */
+static unsigned long f_extend(unsigned long address)
+{
+#ifdef CONFIG_64BIT
+	if(unlikely(parisc_narrow_firmware)) {
+		if((address & 0xff000000) == 0xf0000000)
+			return 0xf0f0f0f000000000UL | (u32)address;
+
+		if((address & 0xf0000000) == 0xf0000000)
+			return 0xffffffff00000000UL | (u32)address;
+	}
+#endif
+	return address;
+}
+
+/**
+ * convert_to_wide - Convert the return buffer addresses into kernel addresses.
+ * @address: The return buffer from PDC.
+ *
+ * This function is used to convert the return buffer addresses retrieved from PDC
+ * into kernel addresses when the PDC address size and kernel address size are
+ * different.
+ */
+static void convert_to_wide(unsigned long *addr)
+{
+#ifdef CONFIG_64BIT
+	int i;
+	unsigned int *p = (unsigned int *)addr;
+
+	if (unlikely(parisc_narrow_firmware)) {
+		for (i = (NUM_PDC_RESULT-1); i >= 0; --i)
+			addr[i] = p[i];
+	}
+#endif
+}
+
+#ifdef CONFIG_64BIT
+void set_firmware_width_unlocked(void)
+{
+	int ret;
+
+	ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES,
+		__pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	if (pdc_result[0] != NARROW_FIRMWARE)
+		parisc_narrow_firmware = 0;
+}
+	
+/**
+ * set_firmware_width - Determine if the firmware is wide or narrow.
+ * 
+ * This function must be called before any pdc_* function that uses the
+ * convert_to_wide function.
+ */
+void set_firmware_width(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&pdc_lock, flags);
+	set_firmware_width_unlocked();
+	spin_unlock_irqrestore(&pdc_lock, flags);
+}
+#else
+void set_firmware_width_unlocked(void)
+{
+	return;
+}
+
+void set_firmware_width(void)
+{
+	return;
+}
+#endif /*CONFIG_64BIT*/
+
+
+#if !defined(BOOTLOADER)
+/**
+ * pdc_emergency_unlock - Unlock the linux pdc lock
+ *
+ * This call unlocks the linux pdc lock in case we need some PDC functions
+ * (like pdc_add_valid) during kernel stack dump.
+ */
+void pdc_emergency_unlock(void)
+{
+ 	/* Spinlock DEBUG code freaks out if we unconditionally unlock */
+        if (spin_is_locked(&pdc_lock))
+		spin_unlock(&pdc_lock);
+}
+
+
+/**
+ * pdc_add_valid - Verify address can be accessed without causing a HPMC.
+ * @address: Address to be verified.
+ *
+ * This PDC call attempts to read from the specified address and verifies
+ * if the address is valid.
+ * 
+ * The return value is PDC_OK (0) in case accessing this address is valid.
+ */
+int pdc_add_valid(unsigned long address)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+EXPORT_SYMBOL(pdc_add_valid);
+
+/**
+ * pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler.
+ * @instr: Pointer to variable which will get instruction opcode.
+ *
+ * The return value is PDC_OK (0) in case call succeeded.
+ */
+int __init pdc_instr(unsigned int *instr)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result));
+	convert_to_wide(pdc_result);
+	*instr = pdc_result[0];
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_chassis_info - Return chassis information.
+ * @result: The return buffer.
+ * @chassis_info: The memory buffer address.
+ * @len: The size of the memory buffer address.
+ *
+ * An HVERSION dependent call for returning the chassis information.
+ */
+int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
+        memcpy(&pdc_result2, led_info, len);
+        retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+                              __pa(pdc_result), __pa(pdc_result2), len);
+        memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
+        memcpy(led_info, pdc_result2, len);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_pat_chassis_send_log - Sends a PDC PAT CHASSIS log message.
+ * @retval: -1 on error, 0 on success. Other value are PDC errors
+ * 
+ * Must be correctly formatted or expect system crash
+ */
+#ifdef CONFIG_64BIT
+int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
+{
+	int retval = 0;
+	unsigned long flags;
+        
+	if (!is_pdc_pat())
+		return -1;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+#endif
+
+/**
+ * pdc_chassis_disp - Updates chassis code
+ * @retval: -1 on error, 0 on success
+ */
+int pdc_chassis_disp(unsigned long disp)
+{
+	int retval = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_chassis_warn - Fetches chassis warnings
+ * @retval: -1 on error, 0 on success
+ */
+int pdc_chassis_warn(unsigned long *warn)
+{
+	int retval = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
+	*warn = pdc_result[0];
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+	int ret;
+
+	ret = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+	convert_to_wide(pdc_result);
+	pdc_coproc_info->ccr_functional = pdc_result[0];
+	pdc_coproc_info->ccr_present = pdc_result[1];
+	pdc_coproc_info->revision = pdc_result[17];
+	pdc_coproc_info->model = pdc_result[18];
+
+	return ret;
+}
+
+/**
+ * pdc_coproc_cfg - To identify coprocessors attached to the processor.
+ * @pdc_coproc_info: Return buffer address.
+ *
+ * This PDC call returns the presence and status of all the coprocessors
+ * attached to the processor.
+ */
+int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	ret = pdc_coproc_cfg_unlocked(pdc_coproc_info);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return ret;
+}
+
+/**
+ * pdc_iodc_read - Read data from the modules IODC.
+ * @actcnt: The actual number of bytes.
+ * @hpa: The HPA of the module for the iodc read.
+ * @index: The iodc entry point.
+ * @iodc_data: A buffer memory for the iodc options.
+ * @iodc_data_size: Size of the memory buffer.
+ *
+ * This PDC call reads from the IODC of the module specified by the hpa
+ * argument.
+ */
+int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
+		  void *iodc_data, unsigned int iodc_data_size)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, 
+			      index, __pa(pdc_result2), iodc_data_size);
+	convert_to_wide(pdc_result);
+	*actcnt = pdc_result[0];
+	memcpy(iodc_data, pdc_result2, iodc_data_size);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL(pdc_iodc_read);
+
+/**
+ * pdc_system_map_find_mods - Locate unarchitected modules.
+ * @pdc_mod_info: Return buffer address.
+ * @mod_path: pointer to dev path structure.
+ * @mod_index: fixed address module index.
+ *
+ * To locate and identify modules which reside at fixed I/O addresses, which
+ * do not self-identify via architected bus walks.
+ */
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+			     struct pdc_module_path *mod_path, long mod_index)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), 
+			      __pa(pdc_result2), mod_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
+	memcpy(mod_path, pdc_result2, sizeof(*mod_path));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_system_map_find_addrs - Retrieve additional address ranges.
+ * @pdc_addr_info: Return buffer address.
+ * @mod_index: Fixed address module index.
+ * @addr_index: Address range index.
+ * 
+ * Retrieve additional information about subsequent address ranges for modules
+ * with multiple address ranges.  
+ */
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+			      long mod_index, long addr_index)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
+			      mod_index, addr_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_model_info - Return model information about the processor.
+ * @model: The return buffer.
+ *
+ * Returns the version numbers, identifiers, and capabilities from the processor module.
+ */
+int pdc_model_info(struct pdc_model *model) 
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	memcpy(model, pdc_result, sizeof(*model));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_model_sysmodel - Get the system model name.
+ * @name: A char array of at least 81 characters.
+ *
+ * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L).
+ * Using OS_ID_HPUX will return the equivalent of the 'modelname' command
+ * on HP/UX.
+ */
+int pdc_model_sysmodel(char *name)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
+                              OS_ID_HPUX, __pa(name));
+        convert_to_wide(pdc_result);
+
+        if (retval == PDC_OK) {
+                name[pdc_result[0]] = '\0'; /* add trailing '\0' */
+        } else {
+                name[0] = 0;
+        }
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_model_versions - Identify the version number of each processor.
+ * @cpu_id: The return buffer.
+ * @id: The id of the processor to check.
+ *
+ * Returns the version number for each processor component.
+ *
+ * This comment was here before, but I do not know what it means :( -RB
+ * id: 0 = cpu revision, 1 = boot-rom-version
+ */
+int pdc_model_versions(unsigned long *versions, int id)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
+        convert_to_wide(pdc_result);
+        *versions = pdc_result[0];
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_model_cpuid - Returns the CPU_ID.
+ * @cpu_id: The return buffer.
+ *
+ * Returns the CPU_ID value which uniquely identifies the cpu portion of
+ * the processor module.
+ */
+int pdc_model_cpuid(unsigned long *cpu_id)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        *cpu_id = pdc_result[0];
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_model_capabilities - Returns the platform capabilities.
+ * @capabilities: The return buffer.
+ *
+ * Returns information about platform support for 32- and/or 64-bit
+ * OSes, IO-PDIR coherency, and virtual aliasing.
+ */
+int pdc_model_capabilities(unsigned long *capabilities)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        if (retval == PDC_OK) {
+                *capabilities = pdc_result[0];
+        } else {
+                *capabilities = PDC_MODEL_OS32;
+        }
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_cache_info - Return cache and TLB information.
+ * @cache_info: The return buffer.
+ *
+ * Returns information about the processor's cache and TLB.
+ */
+int pdc_cache_info(struct pdc_cache_info *cache_info)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(cache_info, pdc_result, sizeof(*cache_info));
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/**
+ * pdc_spaceid_bits - Return whether Space ID hashing is turned on.
+ * @space_bits: Should be 0, if not, bad mojo!
+ *
+ * Returns information about Space ID hashing.
+ */
+int pdc_spaceid_bits(unsigned long *space_bits)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	pdc_result[0] = 0;
+	retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	*space_bits = pdc_result[0];
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+#ifndef CONFIG_PA20
+/**
+ * pdc_btlb_info - Return block TLB information.
+ * @btlb: The return buffer.
+ *
+ * Returns information about the hardware Block TLB.
+ */
+int pdc_btlb_info(struct pdc_btlb_info *btlb) 
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
+        memcpy(btlb, pdc_result, sizeof(*btlb));
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        if(retval < 0) {
+                btlb->max_size = 0;
+        }
+        return retval;
+}
+
+/**
+ * pdc_mem_map_hpa - Find fixed module information.  
+ * @address: The return buffer
+ * @mod_path: pointer to dev path structure.
+ *
+ * This call was developed for S700 workstations to allow the kernel to find
+ * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this
+ * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP
+ * call.
+ *
+ * This call is supported by all existing S700 workstations (up to  Gecko).
+ */
+int pdc_mem_map_hpa(struct pdc_memory_map *address,
+		struct pdc_module_path *mod_path)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        memcpy(pdc_result2, mod_path, sizeof(*mod_path));
+        retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
+				__pa(pdc_result2));
+        memcpy(address, pdc_result, sizeof(*address));
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+#endif	/* !CONFIG_PA20 */
+
+/**
+ * pdc_lan_station_id - Get the LAN address.
+ * @lan_addr: The return buffer.
+ * @hpa: The network device HPA.
+ *
+ * Get the LAN station address when it is not directly available from the LAN hardware.
+ */
+int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
+			__pa(pdc_result), hpa);
+	if (retval < 0) {
+		/* FIXME: else read MAC from NVRAM */
+		memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
+	} else {
+		memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
+	}
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL(pdc_lan_station_id);
+
+/**
+ * pdc_stable_read - Read data from Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be copied.
+ * @count: number of bytes to transfer. count is multiple of 4.
+ *
+ * This PDC call reads from the Stable Storage address supplied in staddr
+ * and copies count bytes to the memory address memaddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+	unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
+               __pa(pdc_result), count);
+       convert_to_wide(pdc_result);
+       memcpy(memaddr, pdc_result, count);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_read);
+
+/**
+ * pdc_stable_write - Write data to Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be read from.
+ * @count: number of bytes to transfer. count is multiple of 4.
+ *
+ * This PDC call reads count bytes from the supplied memaddr address,
+ * and copies count bytes to the Stable Storage address staddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+	unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       memcpy(pdc_result, memaddr, count);
+       convert_to_wide(pdc_result);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
+               __pa(pdc_result), count);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_write);
+
+/**
+ * pdc_stable_get_size - Get Stable Storage size in bytes.
+ * @size: pointer where the size will be stored.
+ *
+ * This PDC call returns the number of bytes in the processor's Stable
+ * Storage, which is the number of contiguous bytes implemented in Stable
+ * Storage starting from staddr=0. size in an unsigned 64-bit integer
+ * which is a multiple of four.
+ */
+int pdc_stable_get_size(unsigned long *size)
+{
+       int retval;
+	unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
+       *size = pdc_result[0];
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_get_size);
+
+/**
+ * pdc_stable_verify_contents - Checks that Stable Storage contents are valid.
+ *
+ * This PDC call is meant to be used to check the integrity of the current
+ * contents of Stable Storage.
+ */
+int pdc_stable_verify_contents(void)
+{
+       int retval;
+	unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_verify_contents);
+
+/**
+ * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize
+ * the validity indicator.
+ *
+ * This PDC call will erase all contents of Stable Storage. Use with care!
+ */
+int pdc_stable_initialize(void)
+{
+       int retval;
+	unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_initialize);
+
+/**
+ * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
+ * @hwpath: fully bc.mod style path to the device.
+ * @initiator: the array to return the result into
+ *
+ * Get the SCSI operational parameters from PDC.
+ * Needed since HPUX never used BIOS or symbios card NVRAM.
+ * Most ncr/sym cards won't have an entry and just use whatever
+ * capabilities of the card are (eg Ultra, LVD). But there are
+ * several cases where it's useful:
+ *    o set SCSI id for Multi-initiator clusters,
+ *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
+ *    o bus width exported is less than what the interface chip supports.
+ */
+int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+
+/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
+#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
+	strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0)
+
+	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
+			      __pa(pdc_result), __pa(hwpath));
+	if (retval < PDC_OK)
+		goto out;
+
+	if (pdc_result[0] < 16) {
+		initiator->host_id = pdc_result[0];
+	} else {
+		initiator->host_id = -1;
+	}
+
+	/*
+	 * Sprockets and Piranha return 20 or 40 (MT/s).  Prelude returns
+	 * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively
+	 */
+	switch (pdc_result[1]) {
+		case  1: initiator->factor = 50; break;
+		case  2: initiator->factor = 25; break;
+		case  5: initiator->factor = 12; break;
+		case 25: initiator->factor = 10; break;
+		case 20: initiator->factor = 12; break;
+		case 40: initiator->factor = 10; break;
+		default: initiator->factor = -1; break;
+	}
+
+	if (IS_SPROCKETS()) {
+		initiator->width = pdc_result[4];
+		initiator->mode = pdc_result[5];
+	} else {
+		initiator->width = -1;
+		initiator->mode = -1;
+	}
+
+ out:
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return (retval >= PDC_OK);
+}
+EXPORT_SYMBOL(pdc_get_initiator);
+
+
+/**
+ * pdc_pci_irt_size - Get the number of entries in the interrupt routing table.
+ * @num_entries: The return value.
+ * @hpa: The HPA for the device.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */ 
+int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, 
+			      __pa(pdc_result), hpa);
+	convert_to_wide(pdc_result);
+	*num_entries = pdc_result[0];
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/** 
+ * pdc_pci_irt - Get the PCI interrupt routing table.
+ * @num_entries: The number of entries in the table.
+ * @hpa: The Hard Physical Address of the device.
+ * @tbl: 
+ *
+ * Get the PCI interrupt routing table for the device at the given HPA.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */
+int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
+{
+	int retval;
+	unsigned long flags;
+
+	BUG_ON((unsigned long)tbl & 0x7);
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	pdc_result[0] = num_entries;
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 
+			      __pa(pdc_result), hpa, __pa(tbl));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+
+#if 0	/* UNTEST CODE - left here in case someone needs it */
+
+/** 
+ * pdc_pci_config_read - read PCI config space.
+ * @hpa		token from PDC to indicate which PCI device
+ * @pci_addr	configuration space address to read from
+ *
+ * Read PCI Configuration space *before* linux PCI subsystem is running.
+ */
+unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	pdc_result[0] = 0;
+	pdc_result[1] = 0;
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, 
+			      __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval ? ~0 : (unsigned int) pdc_result[0];
+}
+
+
+/** 
+ * pdc_pci_config_write - read PCI config space.
+ * @hpa		token from PDC to indicate which PCI device
+ * @pci_addr	configuration space address to write
+ * @val		value we want in the 32-bit register
+ *
+ * Write PCI Configuration space *before* linux PCI subsystem is running.
+ */
+void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	pdc_result[0] = 0;
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, 
+			      __pa(pdc_result), hpa,
+			      cfg_addr&~3UL, 4UL, (unsigned long) val);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+#endif /* UNTESTED CODE */
+
+/**
+ * pdc_tod_read - Read the Time-Of-Day clock.
+ * @tod: The return buffer:
+ *
+ * Read the Time-Of-Day clock
+ */
+int pdc_tod_read(struct pdc_tod *tod)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(tod, pdc_result, sizeof(*tod));
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+EXPORT_SYMBOL(pdc_tod_read);
+
+int pdc_mem_pdt_info(struct pdc_mem_retinfo *rinfo)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_MEMINFO, __pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	memcpy(rinfo, pdc_result, sizeof(*rinfo));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
+		unsigned long *pdt_entries_ptr)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result),
+			__pa(pdt_entries_ptr));
+	if (retval == PDC_OK) {
+		convert_to_wide(pdc_result);
+		memcpy(pret, pdc_result, sizeof(*pret));
+	}
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+#ifdef CONFIG_64BIT
+	/*
+	 * 64-bit kernels should not call this PDT function in narrow mode.
+	 * The pdt_entries_ptr array above will now contain 32-bit values
+	 */
+	if (WARN_ON_ONCE((retval == PDC_OK) && parisc_narrow_firmware))
+		return PDC_ERROR;
+#endif
+
+	return retval;
+}
+
+/**
+ * pdc_tod_set - Set the Time-Of-Day clock.
+ * @sec: The number of seconds since epoch.
+ * @usec: The number of micro seconds.
+ *
+ * Set the Time-Of-Day clock.
+ */ 
+int pdc_tod_set(unsigned long sec, unsigned long usec)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+EXPORT_SYMBOL(pdc_tod_set);
+
+#ifdef CONFIG_64BIT
+int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+		struct pdc_memory_table *tbl, unsigned long entries)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
+	convert_to_wide(pdc_result);
+	memcpy(r_addr, pdc_result, sizeof(*r_addr));
+	memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+#endif /* CONFIG_64BIT */
+
+/* FIXME: Is this pdc used?  I could not find type reference to ftc_bitmap
+ * so I guessed at unsigned long.  Someone who knows what this does, can fix
+ * it later. :)
+ */
+int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
+                              PDC_FIRM_TEST_MAGIC, ftc_bitmap);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/*
+ * pdc_do_reset - Reset the system.
+ *
+ * Reset the system.
+ */
+int pdc_do_reset(void)
+{
+        int retval;
+	unsigned long flags;
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+        return retval;
+}
+
+/*
+ * pdc_soft_power_info - Enable soft power switch.
+ * @power_reg: address of soft power register
+ *
+ * Return the absolute address of the soft power switch register
+ */
+int __init pdc_soft_power_info(unsigned long *power_reg)
+{
+	int retval;
+	unsigned long flags;
+
+	*power_reg = (unsigned long) (-1);
+	
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
+	if (retval == PDC_OK) {
+                convert_to_wide(pdc_result);
+                *power_reg = f_extend(pdc_result[0]);
+	}
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/*
+ * pdc_soft_power_button - Control the soft power button behaviour
+ * @sw_control: 0 for hardware control, 1 for software control 
+ *
+ *
+ * This PDC function places the soft power button under software or
+ * hardware control.
+ * Under software control the OS may control to when to allow to shut 
+ * down the system. Under hardware control pressing the power button 
+ * powers off the system immediately.
+ */
+int pdc_soft_power_button(int sw_control)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/*
+ * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
+ * Primarily a problem on T600 (which parisc-linux doesn't support) but
+ * who knows what other platform firmware might do with this OS "hook".
+ */
+void pdc_io_reset(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+/*
+ * pdc_io_reset_devices - Hack to Stop USB controller
+ *
+ * If PDC used the usb controller, the usb controller
+ * is still running and will crash the machines during iommu 
+ * setup, because of still running DMA. This PDC call
+ * stops the USB controller.
+ * Normally called after calling pdc_io_reset().
+ */
+void pdc_io_reset_devices(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+#endif /* defined(BOOTLOADER) */
+
+/* locked by pdc_console_lock */
+static int __attribute__((aligned(8)))   iodc_retbuf[32];
+static char __attribute__((aligned(64))) iodc_dbuf[4096];
+
+/**
+ * pdc_iodc_print - Console print using IODC.
+ * @str: the string to output.
+ * @count: length of str
+ *
+ * Note that only these special chars are architected for console IODC io:
+ * BEL, BS, CR, and LF. Others are passed through.
+ * Since the HP console requires CR+LF to perform a 'newline', we translate
+ * "\n" to "\r\n".
+ */
+int pdc_iodc_print(const unsigned char *str, unsigned count)
+{
+	unsigned int i;
+	unsigned long flags;
+
+	for (i = 0; i < count;) {
+		switch(str[i]) {
+		case '\n':
+			iodc_dbuf[i+0] = '\r';
+			iodc_dbuf[i+1] = '\n';
+			i += 2;
+			goto print;
+		default:
+			iodc_dbuf[i] = str[i];
+			i++;
+			break;
+		}
+	}
+
+print:
+        spin_lock_irqsave(&pdc_lock, flags);
+        real32_call(PAGE0->mem_cons.iodc_io,
+                    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+                    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+                    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return i;
+}
+
+#if !defined(BOOTLOADER)
+/**
+ * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
+ *
+ * Read a character (non-blocking) from the PDC console, returns -1 if
+ * key is not present.
+ */
+int pdc_iodc_getc(void)
+{
+	int ch;
+	int status;
+	unsigned long flags;
+
+	/* Bail if no console input device. */
+	if (!PAGE0->mem_kbd.iodc_io)
+		return 0;
+	
+	/* wait for a keyboard (rs232)-input */
+	spin_lock_irqsave(&pdc_lock, flags);
+	real32_call(PAGE0->mem_kbd.iodc_io,
+		    (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+		    PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
+		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+
+	ch = *iodc_dbuf;
+	status = *iodc_retbuf;
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	if (status == 0)
+	    return -1;
+	
+	return ch;
+}
+
+int pdc_sti_call(unsigned long func, unsigned long flags,
+                 unsigned long inptr, unsigned long outputr,
+                 unsigned long glob_cfg)
+{
+        int retval;
+	unsigned long irqflags;
+
+        spin_lock_irqsave(&pdc_lock, irqflags);  
+        retval = real32_call(func, flags, inptr, outputr, glob_cfg);
+        spin_unlock_irqrestore(&pdc_lock, irqflags);
+
+        return retval;
+}
+EXPORT_SYMBOL(pdc_sti_call);
+
+#ifdef CONFIG_64BIT
+/**
+ * pdc_pat_cell_get_number - Returns the cell number.
+ * @cell_info: The return buffer.
+ *
+ * This PDC call returns the cell number of the cell from which the call
+ * is made.
+ */
+int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
+	memcpy(cell_info, pdc_result, sizeof(*cell_info));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cell_module - Retrieve the cell's module information.
+ * @actcnt: The number of bytes written to mem_addr.
+ * @ploc: The physical location.
+ * @mod: The module index.
+ * @view_type: The view of the address type.
+ * @mem_addr: The return buffer.
+ *
+ * This PDC call returns information about each module attached to the cell
+ * at the specified location.
+ */
+int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
+			unsigned long view_type, void *mem_addr)
+{
+	int retval;
+	unsigned long flags;
+	static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), 
+			      ploc, mod, view_type, __pa(&result));
+	if(!retval) {
+		*actcnt = pdc_result[0];
+		memcpy(mem_addr, &result, *actcnt);
+	}
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cpu_get_number - Retrieve the cpu number.
+ * @cpu_info: The return buffer.
+ * @hpa: The Hard Physical Address of the CPU.
+ *
+ * Retrieve the cpu number for the cpu at the specified HPA.
+ */
+int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
+			      __pa(&pdc_result), hpa);
+	memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table.
+ * @num_entries: The return value.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ */
+int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
+			      __pa(pdc_result), cell_num);
+	*num_entries = pdc_result[0];
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt - Retrieve the cell's interrupt table.
+ * @r_addr: The return buffer.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the actual interrupt table for the specified cell.
+ */
+int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
+			      __pa(r_addr), cell_num);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges.
+ * @actlen: The return buffer.
+ * @mem_addr: Pointer to the memory buffer.
+ * @count: The number of bytes to read from the buffer.
+ * @offset: The offset with respect to the beginning of the buffer.
+ *
+ */
+int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, 
+			    unsigned long count, unsigned long offset)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), 
+			      __pa(pdc_result2), count, offset);
+	*actual_len = pdc_result[0];
+	memcpy(mem_addr, pdc_result2, *actual_len);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_io_pci_cfg_read - Read PCI configuration space.
+ * @pci_addr: PCI configuration space address for which the read request is being made.
+ * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. 
+ * @mem_addr: Pointer to return memory buffer.
+ *
+ */
+int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
+					__pa(pdc_result), pci_addr, pci_size);
+	switch(pci_size) {
+		case 1: *(u8 *) mem_addr =  (u8)  pdc_result[0]; break;
+		case 2: *(u16 *)mem_addr =  (u16) pdc_result[0]; break;
+		case 4: *(u32 *)mem_addr =  (u32) pdc_result[0]; break;
+	}
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges.
+ * @pci_addr: PCI configuration space address for which the write  request is being made.
+ * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4. 
+ * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be 
+ *         written to PCI Config space.
+ *
+ */
+int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
+				pci_addr, pci_size, val);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_mem_pdc_info - Retrieve information about page deallocation table
+ * @rinfo: memory pdt information
+ *
+ */
+int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_INFO,
+			__pa(&pdc_result));
+	if (retval == PDC_OK)
+		memcpy(rinfo, &pdc_result, sizeof(*rinfo));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_mem_pdt_cell_info - Retrieve information about page deallocation
+ *				table of a cell
+ * @rinfo: memory pdt information
+ * @cell: cell number
+ *
+ */
+int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo,
+		unsigned long cell)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_INFO,
+			__pa(&pdc_result), cell);
+	if (retval == PDC_OK)
+		memcpy(rinfo, &pdc_result, sizeof(*rinfo));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware
+ * @pret: array of PDT entries
+ * @pdt_entries_ptr: ptr to hold number of PDT entries
+ * @max_entries: maximum number of entries to be read
+ *
+ */
+int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
+		unsigned long *pdt_entries_ptr, unsigned long max_entries)
+{
+	int retval;
+	unsigned long flags, entries;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	/* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */
+	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ,
+			__pa(&pdc_result), parisc_cell_num,
+			__pa(pdt_entries_ptr));
+
+	if (retval == PDC_OK) {
+		/* build up return value as for PDC_PAT_MEM_PD_READ */
+		entries = min(pdc_result[0], max_entries);
+		pret->pdt_entries = entries;
+		pret->actual_count_bytes = entries * sizeof(unsigned long);
+	}
+
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	WARN_ON(retval == PDC_OK && pdc_result[0] > max_entries);
+
+	return retval;
+}
+/**
+ * pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware
+ * @pret: array of PDT entries
+ * @pdt_entries_ptr: ptr to hold number of PDT entries
+ * @count: number of bytes to read
+ * @offset: offset to start (in bytes)
+ *
+ */
+int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
+		unsigned long *pdt_entries_ptr, unsigned long count,
+		unsigned long offset)
+{
+	int retval;
+	unsigned long flags, entries;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_READ,
+		__pa(&pdc_result), __pa(pdt_entries_ptr),
+		count, offset);
+
+	if (retval == PDC_OK) {
+		entries = min(pdc_result[0], count);
+		pret->actual_count_bytes = entries;
+		pret->pdt_entries = entries / sizeof(unsigned long);
+	}
+
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_mem_get_dimm_phys_location - Get physical DIMM slot via PAT firmware
+ * @pret: ptr to hold returned information
+ * @phys_addr: physical address to examine
+ *
+ */
+int pdc_pat_mem_get_dimm_phys_location(
+		struct pdc_pat_mem_phys_mem_location *pret,
+		unsigned long phys_addr)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_ADDRESS,
+		__pa(&pdc_result), phys_addr);
+
+	if (retval == PDC_OK)
+		memcpy(pret, &pdc_result, sizeof(*pret));
+
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	return retval;
+}
+#endif /* CONFIG_64BIT */
+#endif /* defined(BOOTLOADER) */
+
+
+/***************** 32-bit real-mode calls ***********/
+/* The struct below is used
+ * to overlay real_stack (real2.S), preparing a 32-bit call frame.
+ * real32_call_asm() then uses this stack in narrow real mode
+ */
+
+struct narrow_stack {
+	/* use int, not long which is 64 bits */
+	unsigned int arg13;
+	unsigned int arg12;
+	unsigned int arg11;
+	unsigned int arg10;
+	unsigned int arg9;
+	unsigned int arg8;
+	unsigned int arg7;
+	unsigned int arg6;
+	unsigned int arg5;
+	unsigned int arg4;
+	unsigned int arg3;
+	unsigned int arg2;
+	unsigned int arg1;
+	unsigned int arg0;
+	unsigned int frame_marker[8];
+	unsigned int sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+long real32_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct narrow_stack real_stack;
+	extern unsigned long real32_call_asm(unsigned int *,
+					     unsigned int *, 
+					     unsigned int);
+	
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned int);
+	real_stack.arg1 = va_arg(args, unsigned int);
+	real_stack.arg2 = va_arg(args, unsigned int);
+	real_stack.arg3 = va_arg(args, unsigned int);
+	real_stack.arg4 = va_arg(args, unsigned int);
+	real_stack.arg5 = va_arg(args, unsigned int);
+	real_stack.arg6 = va_arg(args, unsigned int);
+	real_stack.arg7 = va_arg(args, unsigned int);
+	real_stack.arg8 = va_arg(args, unsigned int);
+	real_stack.arg9 = va_arg(args, unsigned int);
+	real_stack.arg10 = va_arg(args, unsigned int);
+	real_stack.arg11 = va_arg(args, unsigned int);
+	real_stack.arg12 = va_arg(args, unsigned int);
+	real_stack.arg13 = va_arg(args, unsigned int);
+	va_end(args);
+	
+	return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+}
+
+#ifdef CONFIG_64BIT
+/***************** 64-bit real-mode calls ***********/
+
+struct wide_stack {
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long arg6;
+	unsigned long arg7;
+	unsigned long arg8;
+	unsigned long arg9;
+	unsigned long arg10;
+	unsigned long arg11;
+	unsigned long arg12;
+	unsigned long arg13;
+	unsigned long frame_marker[2];	/* rp, previous sp */
+	unsigned long sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+long real64_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct wide_stack real64_stack;
+	extern unsigned long real64_call_asm(unsigned long *,
+					     unsigned long *, 
+					     unsigned long);
+    
+	va_start(args, fn);
+	real64_stack.arg0 = va_arg(args, unsigned long);
+	real64_stack.arg1 = va_arg(args, unsigned long);
+	real64_stack.arg2 = va_arg(args, unsigned long);
+	real64_stack.arg3 = va_arg(args, unsigned long);
+	real64_stack.arg4 = va_arg(args, unsigned long);
+	real64_stack.arg5 = va_arg(args, unsigned long);
+	real64_stack.arg6 = va_arg(args, unsigned long);
+	real64_stack.arg7 = va_arg(args, unsigned long);
+	real64_stack.arg8 = va_arg(args, unsigned long);
+	real64_stack.arg9 = va_arg(args, unsigned long);
+	real64_stack.arg10 = va_arg(args, unsigned long);
+	real64_stack.arg11 = va_arg(args, unsigned long);
+	real64_stack.arg12 = va_arg(args, unsigned long);
+	real64_stack.arg13 = va_arg(args, unsigned long);
+	va_end(args);
+	
+	return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
+}
+
+#endif /* CONFIG_64BIT */
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
new file mode 100644
index 0000000..e46a415
--- /dev/null
+++ b/arch/parisc/kernel/ftrace.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009-2016 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * 	- add CONFIG_DYNAMIC_FTRACE
+ *	- add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/assembly.h>
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+#define __hot __attribute__ ((__section__ (".text.hot")))
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+static void __hot prepare_ftrace_return(unsigned long *parent,
+					unsigned long self_addr)
+{
+	unsigned long old;
+	extern int parisc_return_to_handler;
+
+	if (unlikely(ftrace_graph_is_dead()))
+		return;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	old = *parent;
+
+	if (!function_graph_enter(old, self_addr, 0, NULL))
+		/* activate parisc_return_to_handler() as return point */
+		*parent = (unsigned long) &parisc_return_to_handler;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+void notrace __hot ftrace_function_trampoline(unsigned long parent,
+				unsigned long self_addr,
+				unsigned long org_sp_gr3)
+{
+	extern ftrace_func_t ftrace_trace_function;  /* depends on CONFIG_DYNAMIC_FTRACE */
+	extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
+
+	if (ftrace_trace_function != ftrace_stub) {
+		/* struct ftrace_ops *op, struct pt_regs *regs); */
+		ftrace_trace_function(parent, self_addr, NULL, NULL);
+		return;
+	}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
+		ftrace_graph_entry != ftrace_graph_entry_stub) {
+		unsigned long *parent_rp;
+
+		/* calculate pointer to %rp in stack */
+		parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET);
+		/* sanity check: parent_rp should hold parent */
+		if (*parent_rp != parent)
+			return;
+
+		prepare_ftrace_return(parent_rp, self_addr);
+		return;
+	}
+#endif
+}
+
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
new file mode 100644
index 0000000..a205895
--- /dev/null
+++ b/arch/parisc/kernel/hardware.c
@@ -0,0 +1,1390 @@
+/*
+ *    Hardware descriptions for HP 9000 based hardware, including
+ *    system types, SCSI controllers, DMA controllers, HPPB controllers
+ *    and lots more.
+ * 
+ *    Based on the document "PA-RISC 1.1 I/O Firmware Architecture 
+ *    Reference Specification", March 7, 1999, version 0.96.  This
+ *    is available at http://parisc-linux.org/documentation/
+ *
+ *    Copyright 1999 by Alex deVries <alex@onefishtwo.ca>
+ *    and copyright 1999 The Puffin Group Inc.
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <asm/hardware.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+/*
+ *	HP PARISC Hardware Database
+ *	Access to this database is only possible during bootup
+ *	so don't reference this table after starting the init process
+ *
+ *	NOTE: Product names which are listed here and ends with a '?'
+ *	are guessed. If you know the correct name, please let us know.
+ */
+ 
+static struct hp_hardware hp_hardware_list[] __initdata = {
+	{HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"},
+	{HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"},
+	{HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"},
+	{HPHW_NPROC,0xB,0x4,0x01,"Technical Shogun (845, 645)"},
+	{HPHW_NPROC,0xF,0x4,0x01,"Commercial Shogun (949)"},
+	{HPHW_NPROC,0xC,0x4,0x01,"Cheetah (850, 950)"},
+	{HPHW_NPROC,0x80,0x4,0x01,"Cheetah (950S)"},
+	{HPHW_NPROC,0x81,0x4,0x01,"Jaguar (855, 955)"},
+	{HPHW_NPROC,0x82,0x4,0x01,"Cougar (860, 960)"},
+	{HPHW_NPROC,0x83,0x4,0x13,"Panther (865, 870, 980)"},
+	{HPHW_NPROC,0x100,0x4,0x01,"Burgundy (810)"},
+	{HPHW_NPROC,0x101,0x4,0x01,"SilverFox Low (822, 922)"},
+	{HPHW_NPROC,0x102,0x4,0x01,"SilverFox High (832, 932)"},
+	{HPHW_NPROC,0x103,0x4,0x01,"Lego, SilverLite (815, 808, 920)"},
+	{HPHW_NPROC,0x104,0x4,0x03,"SilverBullet Low (842, 948)"},
+	{HPHW_NPROC,0x105,0x4,0x03,"SilverBullet High (852, 958)"},
+	{HPHW_NPROC,0x106,0x4,0x81,"Oboe"},
+	{HPHW_NPROC,0x180,0x4,0x12,"Dragon"},
+	{HPHW_NPROC,0x181,0x4,0x13,"Chimera (890, 990, 992)"},
+	{HPHW_NPROC,0x182,0x4,0x91,"TNT 100 (891,T500)"},
+	{HPHW_NPROC,0x183,0x4,0x91,"TNT 120 (892,T520)"},
+	{HPHW_NPROC,0x184,0x4,0x91,"Jade 180 U (893,T540)"},
+	{HPHW_NPROC,0x1FF,0x4,0x91,"Hitachi X Processor"},
+	{HPHW_NPROC,0x200,0x4,0x81,"Cobra (720)"},
+	{HPHW_NPROC,0x201,0x4,0x81,"Coral (750)"},
+	{HPHW_NPROC,0x202,0x4,0x81,"King Cobra (730)"},
+	{HPHW_NPROC,0x203,0x4,0x81,"Hardball (735/99)"},
+	{HPHW_NPROC,0x204,0x4,0x81,"Coral II (755/99)"},
+	{HPHW_NPROC,0x205,0x4,0x81,"Coral II (755/125)"},
+	{HPHW_NPROC,0x205,0x4,0x91,"Snake Eagle "},
+	{HPHW_NPROC,0x206,0x4,0x81,"Snake Cheetah (735/130)"},
+	{HPHW_NPROC,0x280,0x4,0x81,"Nova Low (817, 827, 957, 957LX)"},
+	{HPHW_NPROC,0x281,0x4,0x81,"Nova High (837, 847, 857, 967, 967LX)"},
+	{HPHW_NPROC,0x282,0x4,0x81,"Nova8 (807, 917, 917LX, 927,927LX, 937, 937LX, 947,947LX)"},
+	{HPHW_NPROC,0x283,0x4,0x81,"Nova64 (867, 877, 977)"},
+	{HPHW_NPROC,0x284,0x4,0x81,"TNova (887, 897, 987)"},
+	{HPHW_NPROC,0x285,0x4,0x81,"TNova64"},
+	{HPHW_NPROC,0x286,0x4,0x91,"Hydra64 (Nova)"},
+	{HPHW_NPROC,0x287,0x4,0x91,"Hydra96 (Nova)"},
+	{HPHW_NPROC,0x288,0x4,0x81,"TNova96"},
+	{HPHW_NPROC,0x300,0x4,0x81,"Bushmaster (710)"},
+	{HPHW_NPROC,0x302,0x4,0x81,"Flounder (705)"},
+	{HPHW_NPROC,0x310,0x4,0x81,"Scorpio (715/50)"},
+	{HPHW_NPROC,0x311,0x4,0x81,"Scorpio Jr.(715/33)"},
+	{HPHW_NPROC,0x312,0x4,0x81,"Strider-50 (715S/50)"},
+	{HPHW_NPROC,0x313,0x4,0x81,"Strider-33 (715S/33)"},
+	{HPHW_NPROC,0x314,0x4,0x81,"Trailways-50 (715T/50)"},
+	{HPHW_NPROC,0x315,0x4,0x81,"Trailways-33 (715T/33)"},
+	{HPHW_NPROC,0x316,0x4,0x81,"Scorpio Sr.(715/75)"},
+	{HPHW_NPROC,0x317,0x4,0x81,"Scorpio 100 (715/100)"},
+	{HPHW_NPROC,0x318,0x4,0x81,"Spectra (725/50)"},
+	{HPHW_NPROC,0x319,0x4,0x81,"Spectra (725/75)"},
+	{HPHW_NPROC,0x320,0x4,0x81,"Spectra (725/100)"},
+	{HPHW_NPROC,0x401,0x4,0x81,"Pace (745i, 747i)"},
+	{HPHW_NPROC,0x402,0x4,0x81,"Sidewinder (742i)"},
+	{HPHW_NPROC,0x403,0x4,0x81,"Fast Pace"},
+	{HPHW_NPROC,0x480,0x4,0x81,"Orville (E23)"},
+	{HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"},
+	{HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"},
+	{HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"},
+	{HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
+	{HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"},
+	{HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"},
+	{HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"},
+	{HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"},
+	{HPHW_NPROC,0x504,0x4,0x81,"Merlin L2+ 180 (9000/778/B180L)"},
+	{HPHW_NPROC,0x505,0x4,0x81,"Raven L2 132 (9000/778/C132L)"},
+	{HPHW_NPROC,0x506,0x4,0x81,"Raven L2 160 (9000/779/C160L)"},
+	{HPHW_NPROC,0x507,0x4,0x81,"Raven L2 180 (9000/779/C180L)"},
+	{HPHW_NPROC,0x508,0x4,0x81,"Raven L2 160 (9000/779/C160L)"},
+	{HPHW_NPROC,0x509,0x4,0x81,"712/132 L2 Upgrade"},
+	{HPHW_NPROC,0x50A,0x4,0x81,"712/160 L2 Upgrade"},
+	{HPHW_NPROC,0x50B,0x4,0x81,"715/132 L2 Upgrade"},
+	{HPHW_NPROC,0x50C,0x4,0x81,"715/160 L2 Upgrade"},
+	{HPHW_NPROC,0x50D,0x4,0x81,"Rocky2 L2 120"},
+	{HPHW_NPROC,0x50E,0x4,0x81,"Rocky2 L2 150"},
+	{HPHW_NPROC,0x50F,0x4,0x81,"Anole L2 132 (744)"},
+	{HPHW_NPROC,0x510,0x4,0x81,"Anole L2 165 (744)"},
+	{HPHW_NPROC,0x511,0x4,0x81,"Kiji L2 132"},
+	{HPHW_NPROC,0x512,0x4,0x81,"UL L2 132 (803/D220,D320)"},
+	{HPHW_NPROC,0x513,0x4,0x81,"UL L2 160 (813/D220,D320)"},
+	{HPHW_NPROC,0x514,0x4,0x81,"Merlin Jr L2 132"},
+	{HPHW_NPROC,0x515,0x4,0x81,"Staccato L2 132"},
+	{HPHW_NPROC,0x516,0x4,0x81,"Staccato L2 180 (A Class 180)"},
+	{HPHW_NPROC,0x580,0x4,0x81,"KittyHawk DC2-100 (K100)"},
+	{HPHW_NPROC,0x581,0x4,0x91,"KittyHawk DC3-120 (K210)"},
+	{HPHW_NPROC,0x582,0x4,0x91,"KittyHawk DC3 100 (K400)"},
+	{HPHW_NPROC,0x583,0x4,0x91,"KittyHawk DC3 120 (K410)"},
+	{HPHW_NPROC,0x584,0x4,0x91,"LighteningHawk T120"},
+	{HPHW_NPROC,0x585,0x4,0x91,"SkyHawk 100"},
+	{HPHW_NPROC,0x586,0x4,0x91,"SkyHawk 120"},
+	{HPHW_NPROC,0x587,0x4,0x81,"UL Proc 1-way T'120"},
+	{HPHW_NPROC,0x588,0x4,0x91,"UL Proc 2-way T'120"},
+	{HPHW_NPROC,0x589,0x4,0x81,"UL Proc 1-way T'100 (821/D250,D350)"},
+	{HPHW_NPROC,0x58A,0x4,0x91,"UL Proc 2-way T'100 (831/D250,D350)"},
+	{HPHW_NPROC,0x58B,0x4,0x91,"KittyHawk DC2 100 (K200)"},
+	{HPHW_NPROC,0x58C,0x4,0x91,"ThunderHawk DC3- 120 1M (K220)"},
+	{HPHW_NPROC,0x58D,0x4,0x91,"ThunderHawk DC3 120 1M (K420)"},
+	{HPHW_NPROC,0x58E,0x4,0x81,"Raven 120 T'"},
+	{HPHW_NPROC,0x58F,0x4,0x91,"Mohawk 160 U 1M DC3 (K450)"},
+	{HPHW_NPROC,0x590,0x4,0x91,"Mohawk 180 U 1M DC3 (K460)"},
+	{HPHW_NPROC,0x591,0x4,0x91,"Mohawk 200 U 1M DC3"},
+	{HPHW_NPROC,0x592,0x4,0x81,"Raven 100 T'"},
+	{HPHW_NPROC,0x593,0x4,0x91,"FireHawk 160 U"},
+	{HPHW_NPROC,0x594,0x4,0x91,"FireHawk 180 U"},
+	{HPHW_NPROC,0x595,0x4,0x91,"FireHawk 220 U"},
+	{HPHW_NPROC,0x596,0x4,0x91,"FireHawk 240 U"},
+	{HPHW_NPROC,0x597,0x4,0x91,"SPP2000 processor"},
+	{HPHW_NPROC,0x598,0x4,0x81,"Raven U 230 (9000/780/C230)"},
+	{HPHW_NPROC,0x599,0x4,0x81,"Raven U 240 (9000/780/C240)"},
+	{HPHW_NPROC,0x59A,0x4,0x91,"Unlisted but reserved"},
+	{HPHW_NPROC,0x59A,0x4,0x81,"Unlisted but reserved"},
+	{HPHW_NPROC,0x59B,0x4,0x81,"Raven U 160 (9000/780/C160)"},
+	{HPHW_NPROC,0x59C,0x4,0x81,"Raven U 180 (9000/780/C180)"},
+	{HPHW_NPROC,0x59D,0x4,0x81,"Raven U 200 (9000/780/C200)"},
+	{HPHW_NPROC,0x59E,0x4,0x91,"ThunderHawk T' 120"},
+	{HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780)"},
+	{HPHW_NPROC,0x5A0,0x4,0x81,"UL 1w T120 1MB/1MB (841/D260,D360)"},
+	{HPHW_NPROC,0x5A1,0x4,0x91,"UL 2w T120 1MB/1MB (851/D260,D360)"},
+	{HPHW_NPROC,0x5A2,0x4,0x81,"UL 1w U160 512K/512K (861/D270,D370)"},
+	{HPHW_NPROC,0x5A3,0x4,0x91,"UL 2w U160 512K/512K (871/D270,D370)"},
+	{HPHW_NPROC,0x5A4,0x4,0x91,"Mohawk 160 U 1M DC3- (K250)"},
+	{HPHW_NPROC,0x5A5,0x4,0x91,"Mohawk 180 U 1M DC3- (K260)"},
+	{HPHW_NPROC,0x5A6,0x4,0x91,"Mohawk 200 U 1M DC3-"},
+	{HPHW_NPROC,0x5A7,0x4,0x81,"UL proc 1-way U160 1M/1M"},
+	{HPHW_NPROC,0x5A8,0x4,0x91,"UL proc 2-way U160 1M/1M"},
+	{HPHW_NPROC,0x5A9,0x4,0x81,"UL proc 1-way U180 1M/1M"},
+	{HPHW_NPROC,0x5AA,0x4,0x91,"UL proc 2-way U180 1M/1M"},
+	{HPHW_NPROC,0x5AB,0x4,0x91,"Obsolete"},
+	{HPHW_NPROC,0x5AB,0x4,0x81,"Obsolete"},
+	{HPHW_NPROC,0x5AC,0x4,0x91,"Obsolete"},
+	{HPHW_NPROC,0x5AC,0x4,0x81,"Obsolete"},
+	{HPHW_NPROC,0x5AD,0x4,0x91,"BraveHawk 180MHz DC3-"},
+	{HPHW_NPROC,0x5AE,0x4,0x91,"BraveHawk 200MHz DC3- (898/K370)"},
+	{HPHW_NPROC,0x5AF,0x4,0x91,"BraveHawk 220MHz DC3-"},
+	{HPHW_NPROC,0x5B0,0x4,0x91,"BraveHawk 180MHz DC3"},
+	{HPHW_NPROC,0x5B1,0x4,0x91,"BraveHawk 200MHz DC3 (899/K570)"},
+	{HPHW_NPROC,0x5B2,0x4,0x91,"BraveHawk 220MHz DC3"},
+	{HPHW_NPROC,0x5B3,0x4,0x91,"FireHawk 200"},
+	{HPHW_NPROC,0x5B4,0x4,0x91,"SPP2500"},
+	{HPHW_NPROC,0x5B5,0x4,0x91,"SummitHawk U+"},
+	{HPHW_NPROC,0x5B6,0x4,0x91,"DragonHawk U+ 240 DC3"},
+	{HPHW_NPROC,0x5B7,0x4,0x91,"DragonHawk U+ 240 DC3-"},
+	{HPHW_NPROC,0x5B8,0x4,0x91,"SPP2250 240 MHz"},
+	{HPHW_NPROC,0x5B9,0x4,0x81,"UL 1w U+/240 (350/550)"},
+	{HPHW_NPROC,0x5BA,0x4,0x91,"UL 2w U+/240 (350/550)"},
+	{HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W"},
+	{HPHW_NPROC,0x5BC,0x4,0x91,"AllegroLow W"},
+	{HPHW_NPROC,0x5BD,0x4,0x91,"Forte W 2-way"},
+	{HPHW_NPROC,0x5BE,0x4,0x91,"Prelude W"},
+	{HPHW_NPROC,0x5BF,0x4,0x91,"Forte W 4-way"},
+	{HPHW_NPROC,0x5C0,0x4,0x91,"M2250"},
+	{HPHW_NPROC,0x5C1,0x4,0x91,"M2500"},
+	{HPHW_NPROC,0x5C2,0x4,0x91,"Sonata 440"},
+	{HPHW_NPROC,0x5C3,0x4,0x91,"Sonata 360"},
+	{HPHW_NPROC,0x5C4,0x4,0x91,"Rhapsody 440"},
+	{HPHW_NPROC,0x5C5,0x4,0x91,"Rhapsody 360"},
+	{HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780)"},
+	{HPHW_NPROC,0x5C7,0x4,0x91,"Halfdome W 440"},
+	{HPHW_NPROC,0x5C8,0x4,0x81,"Lego 360 processor"},
+	{HPHW_NPROC,0x5C9,0x4,0x91,"Rhapsody DC- 440"},
+	{HPHW_NPROC,0x5CA,0x4,0x91,"Rhapsody DC- 360"},
+	{HPHW_NPROC,0x5CB,0x4,0x91,"Crescendo 440"},
+	{HPHW_NPROC,0x5CC,0x4,0x91,"Prelude W 440"},
+	{HPHW_NPROC,0x5CD,0x4,0x91,"SPP2600"},
+	{HPHW_NPROC,0x5CE,0x4,0x91,"M2600"},
+	{HPHW_NPROC,0x5CF,0x4,0x81,"Allegro W+"},
+	{HPHW_NPROC,0x5D0,0x4,0x81,"Kazoo W+"},
+	{HPHW_NPROC,0x5D1,0x4,0x91,"Forte W+ 2w"},
+	{HPHW_NPROC,0x5D2,0x4,0x91,"Forte W+ 4w"},
+	{HPHW_NPROC,0x5D3,0x4,0x91,"Prelude W+ 540"},
+	{HPHW_NPROC,0x5D4,0x4,0x91,"Duet W+"},
+	{HPHW_NPROC,0x5D5,0x4,0x91,"Crescendo 550"},
+	{HPHW_NPROC,0x5D6,0x4,0x81,"Crescendo DC- 440"},
+	{HPHW_NPROC,0x5D7,0x4,0x91,"Keystone W+"},
+	{HPHW_NPROC,0x5D8,0x4,0x91,"Rhapsody wave 2 W+ DC-"},
+	{HPHW_NPROC,0x5D9,0x4,0x91,"Rhapsody wave 2 W+"},
+	{HPHW_NPROC,0x5DA,0x4,0x91,"Marcato W+ DC-"},
+	{HPHW_NPROC,0x5DB,0x4,0x91,"Marcato W+"},
+	{HPHW_NPROC,0x5DC,0x4,0x91,"Allegro W2"},
+	{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
+	{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
+	{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
+	{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+ (rp5470)?"},
+	{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
+	{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
+	{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
+	{HPHW_NPROC,0x5E3,0x4,0x91,"Crescendo 750 W2"},
+	{HPHW_NPROC,0x5E4,0x4,0x91,"Keystone/Matterhorn W2 750"},
+	{HPHW_NPROC,0x5E5,0x4,0x91,"PowerBar W+"},
+	{HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
+	{HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
+	{HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
+	{HPHW_NPROC,0x5EB,0x4,0x91,"Perf/Leone 875 W2+"},
+	{HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
+	{HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
+	{HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
+	{HPHW_NPROC,0x602,0x4,0x81,"Gecko 100 (712/100)"},
+	{HPHW_NPROC,0x603,0x4,0x81,"Anole 64 (743/64)"},
+	{HPHW_NPROC,0x604,0x4,0x81,"Anole 100 (743/100)"},
+	{HPHW_NPROC,0x605,0x4,0x81,"Gecko 120 (712/120)"},
+	{HPHW_NPROC,0x606,0x4,0x81,"Gila 80"},
+	{HPHW_NPROC,0x607,0x4,0x81,"Gila 100"},
+	{HPHW_NPROC,0x608,0x4,0x81,"Gila 120"},
+	{HPHW_NPROC,0x609,0x4,0x81,"Scorpio-L 80"},
+	{HPHW_NPROC,0x60A,0x4,0x81,"Mirage Jr (715/64)"},
+	{HPHW_NPROC,0x60B,0x4,0x81,"Mirage 100"},
+	{HPHW_NPROC,0x60C,0x4,0x81,"Mirage 100+"},
+	{HPHW_NPROC,0x60D,0x4,0x81,"Electra 100"},
+	{HPHW_NPROC,0x60E,0x4,0x81,"Electra 120"},
+	{HPHW_NPROC,0x610,0x4,0x81,"Scorpio-L 100"},
+	{HPHW_NPROC,0x611,0x4,0x81,"Scorpio-L 120"},
+	{HPHW_NPROC,0x612,0x4,0x81,"Spectra-L 80"},
+	{HPHW_NPROC,0x613,0x4,0x81,"Spectra-L 100"},
+	{HPHW_NPROC,0x614,0x4,0x81,"Spectra-L 120"},
+	{HPHW_NPROC,0x615,0x4,0x81,"Piranha 100"},
+	{HPHW_NPROC,0x616,0x4,0x81,"Piranha 120"},
+	{HPHW_NPROC,0x617,0x4,0x81,"Jason 50"},
+	{HPHW_NPROC,0x618,0x4,0x81,"Jason 100"},
+	{HPHW_NPROC,0x619,0x4,0x81,"Mirage 80"},
+	{HPHW_NPROC,0x61A,0x4,0x81,"SAIC L-80"},
+	{HPHW_NPROC,0x61B,0x4,0x81,"Rocky1 L-60"},
+	{HPHW_NPROC,0x61C,0x4,0x81,"Anole T (743/T)"},
+	{HPHW_NPROC,0x67E,0x4,0x81,"Hitachi Tiny 80"},
+	{HPHW_NPROC,0x67F,0x4,0x81,"Hitachi Tiny 64"},
+	{HPHW_NPROC,0x700,0x4,0x91,"NEC Aska Processor"},
+	{HPHW_NPROC,0x880,0x4,0x91,"Orca Mako"},
+	{HPHW_NPROC,0x881,0x4,0x91,"Everest Mako"},
+	{HPHW_NPROC,0x882,0x4,0x91,"Rainier/Medel Mako Slow"},
+	{HPHW_NPROC,0x883,0x4,0x91,"Rainier/Medel Mako Fast"},
+	{HPHW_NPROC,0x884,0x4,0x91,"Mt. Hamilton"},
+	{HPHW_NPROC,0x885,0x4,0x91,"Mt. Hamilton DC-"},
+	{HPHW_NPROC,0x886,0x4,0x91,"Storm Peak Slow DC-"},
+	{HPHW_NPROC,0x887,0x4,0x91,"Storm Peak Slow"},
+	{HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
+	{HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
+	{HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"},
+	{HPHW_NPROC,0x88B,0x4,0x91,"Crestone Peak Fast?"},
+	{HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"},
+	{HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"},
+	{HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"},
+	{HPHW_NPROC,0x892,0x4,0x91,"Mt. Hamilton Slow Mako+?"},
+	{HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"},
+	{HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"},
+	{HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"},
+	{HPHW_NPROC,0x897,0x4,0x91,"Storm Peak DC- Slow Mako+"},
+	{HPHW_NPROC,0x898,0x4,0x91,"Storm Peak DC- Fast Mako+"},
+	{HPHW_NPROC,0x899,0x4,0x91,"Mt. Hamilton Slow Mako+"},
+	{HPHW_NPROC,0x89B,0x4,0x91,"Crestone Peak Mako+ Slow"},
+	{HPHW_NPROC,0x89C,0x4,0x91,"Crestone Peak Mako+ Fast"},
+	{HPHW_A_DIRECT, 0x004, 0x0000D, 0x00, "Arrakis MUX"}, 
+	{HPHW_A_DIRECT, 0x005, 0x0000D, 0x00, "Dyun Kiuh MUX"}, 
+	{HPHW_A_DIRECT, 0x006, 0x0000D, 0x00, "Baat Kiuh AP/MUX (40299B)"}, 
+	{HPHW_A_DIRECT, 0x007, 0x0000D, 0x00, "Dino AP"}, 
+	{HPHW_A_DIRECT, 0x009, 0x0000D, 0x00, "Solaris Direct Connect MUX (J2092A)"}, 
+	{HPHW_A_DIRECT, 0x00A, 0x0000D, 0x00, "Solaris RS-422/423 MUX (J2093A)"}, 
+	{HPHW_A_DIRECT, 0x00B, 0x0000D, 0x00, "Solaris RS-422/423 Quadriloops MUX"}, 
+	{HPHW_A_DIRECT, 0x00C, 0x0000D, 0x00, "Solaris Modem MUX (J2094A)"}, 
+	{HPHW_A_DIRECT, 0x00D, 0x0000D, 0x00, "Twins Direct Connect MUX"}, 
+	{HPHW_A_DIRECT, 0x00E, 0x0000D, 0x00, "Twins Modem MUX"}, 
+	{HPHW_A_DIRECT, 0x00F, 0x0000D, 0x00, "Nautilus RS-485"}, 
+	{HPHW_A_DIRECT, 0x010, 0x0000D, 0x00, "UltraLight CAP/MUX"}, 
+	{HPHW_A_DIRECT, 0x015, 0x0000D, 0x00, "Eole CAP/MUX"}, 
+	{HPHW_A_DIRECT, 0x024, 0x0000D, 0x00, "Sahp Kiuh AP/MUX"}, 
+	{HPHW_A_DIRECT, 0x034, 0x0000D, 0x00, "Sahp Kiuh Low AP/MUX"}, 
+	{HPHW_A_DIRECT, 0x044, 0x0000D, 0x00, "Sahp Baat Kiuh AP/MUX"}, 
+	{HPHW_A_DIRECT, 0x004, 0x0000E, 0x80, "Burgundy RS-232"}, 
+	{HPHW_A_DIRECT, 0x005, 0x0000E, 0x80, "Silverfox RS-232"}, 
+	{HPHW_A_DIRECT, 0x006, 0x0000E, 0x80, "Lego RS-232"}, 
+	{HPHW_A_DIRECT, 0x004, 0x0000F, 0x00, "Peacock Graphics"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00014, 0x80, "Burgundy HIL"}, 
+	{HPHW_A_DIRECT, 0x005, 0x00014, 0x80, "Peacock HIL"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00015, 0x80, "Leonardo"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00016, 0x80, "HP-PB HRM"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00017, 0x80, "HP-PB HRC"}, 
+	{HPHW_A_DIRECT, 0x004, 0x0003A, 0x80, "Skunk Centronics (28655A)"}, 
+	{HPHW_A_DIRECT, 0x024, 0x0003A, 0x80, "Sahp Kiuh Centronics"}, 
+	{HPHW_A_DIRECT, 0x044, 0x0003A, 0x80, "Sahp Baat Kiuh Centronics"}, 
+	{HPHW_A_DIRECT, 0x004, 0x0004E, 0x80, "AT&T DataKit (AMSO)"}, 
+	{HPHW_A_DIRECT, 0x004, 0x0009B, 0x80, "Test&Meas GSC HPIB"}, 
+	{HPHW_A_DIRECT, 0x004, 0x000A8, 0x00, "Rocky2-120 Front Keyboard"}, 
+	{HPHW_A_DIRECT, 0x005, 0x000A8, 0x00, "Rocky2-150 Front Keyboard"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00101, 0x80, "Hitachi Console Module"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00102, 0x80, "Hitachi Boot Module"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00203, 0x80, "MELCO HBMLA MLAIT"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00208, 0x80, "MELCO HBDPC"}, 
+	{HPHW_A_DIRECT, 0x004, 0x00300, 0x00, "DCI TWINAX TERM IO MUX"}, 
+	{HPHW_A_DMA, 0x004, 0x00039, 0x80, "Skunk SCSI (28655A)"}, 
+	{HPHW_A_DMA, 0x005, 0x00039, 0x80, "KittyHawk CSY Core SCSI"}, 
+	{HPHW_A_DMA, 0x014, 0x00039, 0x80, "Diablo SCSI"}, 
+	{HPHW_A_DMA, 0x024, 0x00039, 0x80, "Sahp Kiuh SCSI"}, 
+	{HPHW_A_DMA, 0x034, 0x00039, 0x80, "Sahp Kiuh Low SCSI"}, 
+	{HPHW_A_DMA, 0x044, 0x00039, 0x80, "Sahp Baat Kiuh SCSI"}, 
+	{HPHW_A_DMA, 0x004, 0x0003B, 0x80, "Wizard SCSI"}, 
+	{HPHW_A_DMA, 0x005, 0x0003B, 0x80, "KittyHawk CSY Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x006, 0x0003B, 0x80, "Symbios EPIC FW-SCSI"}, 
+	{HPHW_A_DMA, 0x004, 0x00040, 0x80, "HP-PB Shazam HPIB (28650A)"}, 
+	{HPHW_A_DMA, 0x005, 0x00040, 0x80, "Burgundy HPIB"}, 
+	{HPHW_A_DMA, 0x004, 0x00041, 0x80, "HP-PB HP-FL"}, 
+	{HPHW_A_DMA, 0x004, 0x00042, 0x80, "HP-PB LoQuix HPIB (28650B)"}, 
+	{HPHW_A_DMA, 0x004, 0x00043, 0x80, "HP-PB Crypt LoQuix"}, 
+	{HPHW_A_DMA, 0x004, 0x00044, 0x80, "HP-PB Shazam GPIO (28651A)"}, 
+	{HPHW_A_DMA, 0x004, 0x00045, 0x80, "HP-PB LoQuix GPIO"}, 
+	{HPHW_A_DMA, 0x004, 0x00046, 0x80, "2-Port X.25 NIO_ACC (AMSO)"}, 
+	{HPHW_A_DMA, 0x004, 0x00047, 0x80, "4-Port X.25 NIO_ACC (AMSO)"}, 
+	{HPHW_A_DMA, 0x004, 0x0004B, 0x80, "LGB Control"}, 
+	{HPHW_A_DMA, 0x004, 0x0004C, 0x80, "Martian RTI (AMSO)"}, 
+	{HPHW_A_DMA, 0x004, 0x0004D, 0x80, "ACC Mux (AMSO)"}, 
+	{HPHW_A_DMA, 0x004, 0x00050, 0x80, "Lanbrusca 802.3 (36967A)"}, 
+	{HPHW_A_DMA, 0x004, 0x00056, 0x80, "HP-PB LoQuix FDDI"}, 
+	{HPHW_A_DMA, 0x004, 0x00057, 0x80, "HP-PB LoQuix FDDI (28670A)"}, 
+	{HPHW_A_DMA, 0x004, 0x0005E, 0x00, "Gecko Add-on Token Ring"}, 
+	{HPHW_A_DMA, 0x012, 0x00089, 0x80, "Barracuda Add-on FW-SCSI"}, 
+	{HPHW_A_DMA, 0x013, 0x00089, 0x80, "Bluefish Add-on FW-SCSI"}, 
+	{HPHW_A_DMA, 0x014, 0x00089, 0x80, "Shrike Add-on FW-SCSI"}, 
+	{HPHW_A_DMA, 0x015, 0x00089, 0x80, "KittyHawk GSY Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x017, 0x00089, 0x80, "Shrike Jade Add-on FW-SCSI (A3644A)"}, 
+	{HPHW_A_DMA, 0x01F, 0x00089, 0x80, "SkyHawk 100/120 FW-SCSI"}, 
+	{HPHW_A_DMA, 0x027, 0x00089, 0x80, "Piranha 100 FW-SCSI"}, 
+	{HPHW_A_DMA, 0x032, 0x00089, 0x80, "Raven T' Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x03B, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x03C, 0x00089, 0x80, "Merlin 132 Core FW-SCSI"},
+	{HPHW_A_DMA, 0x03D, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"},
+	{HPHW_A_DMA, 0x044, 0x00089, 0x80, "Mohawk Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x051, 0x00089, 0x80, "Firehawk FW-SCSI"}, 
+	{HPHW_A_DMA, 0x058, 0x00089, 0x80, "FireHawk 200 FW-SCSI"}, 
+	{HPHW_A_DMA, 0x05C, 0x00089, 0x80, "SummitHawk 230 Ultra-SCSI"}, 
+	{HPHW_A_DMA, 0x014, 0x00091, 0x80, "Baby Hugo Add-on Net FC (A3406A)"}, 
+	{HPHW_A_DMA, 0x020, 0x00091, 0x80, "Baby Jade Add-on Net FC (A3638A)"}, 
+	{HPHW_A_DMA, 0x004, 0x00092, 0x80, "GSC+ YLIASTER ATM"}, 
+	{HPHW_A_DMA, 0x004, 0x00095, 0x80, "Hamlyn GSC+ Network Card"}, 
+	{HPHW_A_DMA, 0x004, 0x00098, 0x80, "Lo-fat Emulator"}, 
+	{HPHW_A_DMA, 0x004, 0x0009A, 0x80, "GSC+ Venus ATM"}, 
+	{HPHW_A_DMA, 0x005, 0x0009A, 0x80, "GSC+ Samorobrive ATM"}, 
+	{HPHW_A_DMA, 0x004, 0x0009D, 0x80, "HP HSC-PCI Cards"}, 
+	{HPHW_A_DMA, 0x004, 0x0009E, 0x80, "Alaxis GSC+ 155Mb ATM"}, 
+	{HPHW_A_DMA, 0x005, 0x0009E, 0x80, "Alaxis GSC+ 622Mb ATM"}, 
+	{HPHW_A_DMA, 0x05C, 0x0009F, 0x80, "SummitHawk 230 USB"}, 
+	{HPHW_A_DMA, 0x05C, 0x000A0, 0x80, "SummitHawk 230 100BaseT"}, 
+	{HPHW_A_DMA, 0x015, 0x000A7, 0x80, "Baby Hugo Add-on mass FC (A3404A)"}, 
+	{HPHW_A_DMA, 0x018, 0x000A7, 0x80, "Mombasa GS Add-on mass FC (A3591)"}, 
+	{HPHW_A_DMA, 0x021, 0x000A7, 0x80, "Baby Jade Add-on mass FC (A3636A)"}, 
+	{HPHW_A_DMA, 0x004, 0x00201, 0x80, "MELCO HCMAP"}, 
+	{HPHW_A_DMA, 0x004, 0x00202, 0x80, "MELCO HBMLA MLAMA"}, 
+	{HPHW_A_DMA, 0x004, 0x00205, 0x80, "MELCO HBRFU"}, 
+	{HPHW_A_DMA, 0x004, 0x00380, 0x80, "Interphase NIO-FC"}, 
+	{HPHW_A_DMA, 0x004, 0x00381, 0x80, "Interphase NIO-ATM"}, 
+	{HPHW_A_DMA, 0x004, 0x00382, 0x80, "Interphase NIO-100BaseTX"}, 
+	{HPHW_BA, 0x004, 0x00070, 0x0, "Cobra Core BA"}, 
+	{HPHW_BA, 0x005, 0x00070, 0x0, "Coral Core BA"}, 
+	{HPHW_BA, 0x006, 0x00070, 0x0, "Bushmaster Core BA"}, 
+	{HPHW_BA, 0x007, 0x00070, 0x0, "Scorpio Core BA"}, 
+	{HPHW_BA, 0x008, 0x00070, 0x0, "Flounder Core BA"}, 
+	{HPHW_BA, 0x009, 0x00070, 0x0, "Outfield Core BA"}, 
+	{HPHW_BA, 0x00A, 0x00070, 0x0, "CoralII Core BA"}, 
+	{HPHW_BA, 0x00B, 0x00070, 0x0, "Scorpio Jr. Core BA"}, 
+	{HPHW_BA, 0x00C, 0x00070, 0x0, "Strider-50 Core BA"}, 
+	{HPHW_BA, 0x00D, 0x00070, 0x0, "Strider-33 Core BA"}, 
+	{HPHW_BA, 0x00E, 0x00070, 0x0, "Trailways-50 Core BA"}, 
+	{HPHW_BA, 0x00F, 0x00070, 0x0, "Trailways-33 Core BA"}, 
+	{HPHW_BA, 0x010, 0x00070, 0x0, "Pace Core BA"}, 
+	{HPHW_BA, 0x011, 0x00070, 0x0, "Sidewinder Core BA"}, 
+	{HPHW_BA, 0x019, 0x00070, 0x0, "Scorpio Sr. Core BA"}, 
+	{HPHW_BA, 0x020, 0x00070, 0x0, "Scorpio 100 Core BA"}, 
+	{HPHW_BA, 0x021, 0x00070, 0x0, "Spectra 50 Core BA"}, 
+	{HPHW_BA, 0x022, 0x00070, 0x0, "Spectra 75 Core BA"}, 
+	{HPHW_BA, 0x023, 0x00070, 0x0, "Spectra 100 Core BA"}, 
+	{HPHW_BA, 0x024, 0x00070, 0x0, "Fast Pace Core BA"}, 
+	{HPHW_BA, 0x026, 0x00070, 0x0, "CoralII Jaguar Core BA"}, 
+	{HPHW_BA, 0x004, 0x00076, 0x0, "Cobra EISA BA"}, 
+	{HPHW_BA, 0x005, 0x00076, 0x0, "Coral EISA BA"}, 
+	{HPHW_BA, 0x007, 0x00076, 0x0, "Scorpio EISA BA"}, 
+	{HPHW_BA, 0x00A, 0x00076, 0x0, "CoralII EISA BA"}, 
+	{HPHW_BA, 0x00B, 0x00076, 0x0, "Scorpio Jr. EISA BA"}, 
+	{HPHW_BA, 0x00C, 0x00076, 0x0, "Strider-50 Core EISA"}, 
+	{HPHW_BA, 0x00D, 0x00076, 0x0, "Strider-33 Core EISA"}, 
+	{HPHW_BA, 0x00E, 0x00076, 0x0, "Trailways-50 Core EISA"}, 
+	{HPHW_BA, 0x00F, 0x00076, 0x0, "Trailways-33 Core EISA"}, 
+	{HPHW_BA, 0x010, 0x00076, 0x0, "Pace Core EISA"}, 
+	{HPHW_BA, 0x019, 0x00076, 0x0, "Scorpio Sr. EISA BA"}, 
+	{HPHW_BA, 0x020, 0x00076, 0x0, "Scorpio 100 EISA BA"}, 
+	{HPHW_BA, 0x021, 0x00076, 0x0, "Spectra 50 EISA BA"}, 
+	{HPHW_BA, 0x022, 0x00076, 0x0, "Spectra 75 EISA BA"}, 
+	{HPHW_BA, 0x023, 0x00076, 0x0, "Spectra 100 EISA BA"}, 
+	{HPHW_BA, 0x026, 0x00076, 0x0, "CoralII Jaguar EISA BA"}, 
+	{HPHW_BA, 0x010, 0x00078, 0x0, "Pace VME BA"}, 
+	{HPHW_BA, 0x011, 0x00078, 0x0, "Sidewinder VME BA"}, 
+	{HPHW_BA, 0x01A, 0x00078, 0x0, "Anole 64 VME BA"}, 
+	{HPHW_BA, 0x01B, 0x00078, 0x0, "Anole 100 VME BA"}, 
+	{HPHW_BA, 0x024, 0x00078, 0x0, "Fast Pace VME BA"}, 
+	{HPHW_BA, 0x034, 0x00078, 0x0, "Anole T VME BA"}, 
+	{HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 VME BA"}, 
+	{HPHW_BA, 0x04C, 0x00078, 0x0, "Anole L2 165 VME BA"}, 
+	{HPHW_BA, 0x011, 0x00081, 0x0, "WB-96 Core BA"}, 
+	{HPHW_BA, 0x012, 0x00081, 0x0, "Orville UX Core BA"}, 
+	{HPHW_BA, 0x013, 0x00081, 0x0, "Wilbur UX Core BA"}, 
+	{HPHW_BA, 0x014, 0x00081, 0x0, "WB-80 Core BA"}, 
+	{HPHW_BA, 0x015, 0x00081, 0x0, "KittyHawk GSY Core BA"}, 
+	{HPHW_BA, 0x016, 0x00081, 0x0, "Gecko Core BA"}, 
+	{HPHW_BA, 0x018, 0x00081, 0x0, "Gecko Optional BA"}, 
+	{HPHW_BA, 0x01A, 0x00081, 0x0, "Anole 64 Core BA"}, 
+	{HPHW_BA, 0x01B, 0x00081, 0x0, "Anole 100 Core BA"}, 
+	{HPHW_BA, 0x01C, 0x00081, 0x0, "Gecko 80 Core BA"}, 
+	{HPHW_BA, 0x01D, 0x00081, 0x0, "Gecko 100 Core BA"}, 
+	{HPHW_BA, 0x01F, 0x00081, 0x0, "SkyHawk 100/120 Core BA"}, 
+	{HPHW_BA, 0x027, 0x00081, 0x0, "Piranha 100 Core BA"}, 
+	{HPHW_BA, 0x028, 0x00081, 0x0, "Mirage Jr Core BA"}, 
+	{HPHW_BA, 0x029, 0x00081, 0x0, "Mirage Core BA"}, 
+	{HPHW_BA, 0x02A, 0x00081, 0x0, "Electra Core BA"}, 
+	{HPHW_BA, 0x02B, 0x00081, 0x0, "Mirage 80 Core BA"}, 
+	{HPHW_BA, 0x02C, 0x00081, 0x0, "Mirage 100+ Core BA"}, 
+	{HPHW_BA, 0x02E, 0x00081, 0x0, "UL 350 Lasi Core BA"}, 
+	{HPHW_BA, 0x02F, 0x00081, 0x0, "UL 550 Lasi Core BA"}, 
+	{HPHW_BA, 0x032, 0x00081, 0x0, "Raven T' Core BA"}, 
+	{HPHW_BA, 0x033, 0x00081, 0x0, "Anole T Core BA"}, 
+	{HPHW_BA, 0x034, 0x00081, 0x0, "SAIC L-80 Core BA"}, 
+	{HPHW_BA, 0x035, 0x00081, 0x0, "PCX-L2 712/132 Core BA"}, 
+	{HPHW_BA, 0x036, 0x00081, 0x0, "PCX-L2 712/160 Core BA"}, 
+	{HPHW_BA, 0x03B, 0x00081, 0x0, "Raven U/L2 Core BA"}, 
+	{HPHW_BA, 0x03C, 0x00081, 0x0, "Merlin 132 Core BA"}, 
+	{HPHW_BA, 0x03D, 0x00081, 0x0, "Merlin 160 Core BA"}, 
+	{HPHW_BA, 0x03E, 0x00081, 0x0, "Merlin+ 132 Core BA"}, 
+	{HPHW_BA, 0x03F, 0x00081, 0x0, "Merlin+ 180 Core BA"}, 
+	{HPHW_BA, 0x044, 0x00081, 0x0, "Mohawk Core BA"}, 
+	{HPHW_BA, 0x045, 0x00081, 0x0, "Rocky1 Core BA"}, 
+	{HPHW_BA, 0x046, 0x00081, 0x0, "Rocky2 120 Core BA"}, 
+	{HPHW_BA, 0x047, 0x00081, 0x0, "Rocky2 150 Core BA"}, 
+	{HPHW_BA, 0x04B, 0x00081, 0x0, "Anole L2 132 Core BA"}, 
+	{HPHW_BA, 0x04D, 0x00081, 0x0, "Anole L2 165 Core BA"}, 
+	{HPHW_BA, 0x04E, 0x00081, 0x0, "Kiji L2 132 Core BA"}, 
+	{HPHW_BA, 0x050, 0x00081, 0x0, "Merlin Jr 132 Core BA"}, 
+	{HPHW_BA, 0x051, 0x00081, 0x0, "Firehawk Core BA"}, 
+	{HPHW_BA, 0x056, 0x00081, 0x0, "Raven+ w SE FWSCSI Core BA"}, 
+	{HPHW_BA, 0x057, 0x00081, 0x0, "Raven+ w Diff FWSCSI Core BA"}, 
+	{HPHW_BA, 0x058, 0x00081, 0x0, "FireHawk 200 Core BA"}, 
+	{HPHW_BA, 0x05C, 0x00081, 0x0, "SummitHawk 230 Core BA"}, 
+	{HPHW_BA, 0x05E, 0x00081, 0x0, "Staccato 132 Core BA"}, 
+	{HPHW_BA, 0x05E, 0x00081, 0x0, "Staccato 180 Core BA"}, 
+	{HPHW_BA, 0x05F, 0x00081, 0x0, "Staccato 180 Lasi"}, 
+	{HPHW_BA, 0x800, 0x00081, 0x0, "Hitachi Tiny 64 Core BA"}, 
+	{HPHW_BA, 0x801, 0x00081, 0x0, "Hitachi Tiny 80 Core BA"}, 
+	{HPHW_BA, 0x004, 0x0008B, 0x0, "Anole Optional PCMCIA BA"}, 
+	{HPHW_BA, 0x004, 0x0008E, 0x0, "GSC ITR Wax BA"}, 
+	{HPHW_BA, 0x00C, 0x0008E, 0x0, "Gecko Optional Wax BA"}, 
+	{HPHW_BA, 0x010, 0x0008E, 0x0, "Pace Wax BA"}, 
+	{HPHW_BA, 0x011, 0x0008E, 0x0, "SuperPace Wax BA"}, 
+	{HPHW_BA, 0x012, 0x0008E, 0x0, "Mirage Jr Wax BA"}, 
+	{HPHW_BA, 0x013, 0x0008E, 0x0, "Mirage Wax BA"}, 
+	{HPHW_BA, 0x014, 0x0008E, 0x0, "Electra Wax BA"}, 
+	{HPHW_BA, 0x017, 0x0008E, 0x0, "Raven Backplane Wax BA"}, 
+	{HPHW_BA, 0x01E, 0x0008E, 0x0, "Raven T' Wax BA"}, 
+	{HPHW_BA, 0x01F, 0x0008E, 0x0, "SkyHawk Wax BA"}, 
+	{HPHW_BA, 0x023, 0x0008E, 0x0, "Rocky1 Wax BA"}, 
+	{HPHW_BA, 0x02B, 0x0008E, 0x0, "Mirage 80 Wax BA"}, 
+	{HPHW_BA, 0x02C, 0x0008E, 0x0, "Mirage 100+ Wax BA"}, 
+	{HPHW_BA, 0x030, 0x0008E, 0x0, "UL 350 Core Wax BA"}, 
+	{HPHW_BA, 0x031, 0x0008E, 0x0, "UL 550 Core Wax BA"}, 
+	{HPHW_BA, 0x034, 0x0008E, 0x0, "SAIC L-80 Wax BA"}, 
+	{HPHW_BA, 0x03A, 0x0008E, 0x0, "Merlin+ Wax BA"}, 
+	{HPHW_BA, 0x040, 0x0008E, 0x0, "Merlin 132 Wax BA"}, 
+	{HPHW_BA, 0x041, 0x0008E, 0x0, "Merlin 160 Wax BA"}, 
+	{HPHW_BA, 0x043, 0x0008E, 0x0, "Merlin 132/160 Wax BA"}, 
+	{HPHW_BA, 0x052, 0x0008E, 0x0, "Raven+ Hi Power Backplane w/EISA Wax BA"}, 
+	{HPHW_BA, 0x054, 0x0008E, 0x0, "Raven+ Lo Power Backplane w/EISA Wax BA"}, 
+	{HPHW_BA, 0x059, 0x0008E, 0x0, "FireHawk 200 Wax BA"}, 
+	{HPHW_BA, 0x05A, 0x0008E, 0x0, "Raven+ L2 Backplane w/EISA Wax BA"}, 
+	{HPHW_BA, 0x05D, 0x0008E, 0x0, "SummitHawk Wax BA"}, 
+	{HPHW_BA, 0x800, 0x0008E, 0x0, "Hitachi Tiny 64 Wax BA"}, 
+	{HPHW_BA, 0x801, 0x0008E, 0x0, "Hitachi Tiny 80 Wax BA"}, 
+	{HPHW_BA, 0x011, 0x00090, 0x0, "SuperPace Wax EISA BA"}, 
+	{HPHW_BA, 0x017, 0x00090, 0x0, "Raven Backplane Wax EISA BA"}, 
+	{HPHW_BA, 0x01E, 0x00090, 0x0, "Raven T' Wax EISA BA"}, 
+	{HPHW_BA, 0x01F, 0x00090, 0x0, "SkyHawk 100/120 Wax EISA BA"}, 
+	{HPHW_BA, 0x027, 0x00090, 0x0, "Piranha 100 Wax EISA BA"}, 
+	{HPHW_BA, 0x028, 0x00090, 0x0, "Mirage Jr Wax EISA BA"}, 
+	{HPHW_BA, 0x029, 0x00090, 0x0, "Mirage Wax EISA BA"}, 
+	{HPHW_BA, 0x02A, 0x00090, 0x0, "Electra Wax EISA BA"}, 
+	{HPHW_BA, 0x02B, 0x00090, 0x0, "Mirage 80 Wax EISA BA"}, 
+	{HPHW_BA, 0x02C, 0x00090, 0x0, "Mirage 100+ Wax EISA BA"}, 
+	{HPHW_BA, 0x030, 0x00090, 0x0, "UL 350 Wax EISA BA"}, 
+	{HPHW_BA, 0x031, 0x00090, 0x0, "UL 550 Wax EISA BA"}, 
+	{HPHW_BA, 0x034, 0x00090, 0x0, "SAIC L-80 Wax EISA BA"}, 
+	{HPHW_BA, 0x03A, 0x00090, 0x0, "Merlin+ Wax EISA BA"}, 
+	{HPHW_BA, 0x040, 0x00090, 0x0, "Merlin 132 Wax EISA BA"}, 
+	{HPHW_BA, 0x041, 0x00090, 0x0, "Merlin 160 Wax EISA BA"}, 
+	{HPHW_BA, 0x043, 0x00090, 0x0, "Merlin 132/160 Wax EISA BA"}, 
+	{HPHW_BA, 0x052, 0x00090, 0x0, "Raven Hi Power Backplane Wax EISA BA"}, 
+	{HPHW_BA, 0x054, 0x00090, 0x0, "Raven Lo Power Backplane Wax EISA BA"}, 
+	{HPHW_BA, 0x059, 0x00090, 0x0, "FireHawk 200 Wax EISA BA"}, 
+	{HPHW_BA, 0x05A, 0x00090, 0x0, "Raven L2 Backplane Wax EISA BA"}, 
+	{HPHW_BA, 0x05D, 0x00090, 0x0, "SummitHawk Wax EISA BA"}, 
+	{HPHW_BA, 0x800, 0x00090, 0x0, "Hitachi Tiny 64 Wax EISA BA"}, 
+	{HPHW_BA, 0x801, 0x00090, 0x0, "Hitachi Tiny 80 Wax EISA BA"}, 
+	{HPHW_BA, 0x01A, 0x00093, 0x0, "Anole 64 TIMI BA"}, 
+	{HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 100 TIMI BA"}, 
+	{HPHW_BA, 0x034, 0x00093, 0x0, "Anole T TIMI BA"}, 
+	{HPHW_BA, 0x04A, 0x00093, 0x0, "Anole L2 132 TIMI BA"}, 
+	{HPHW_BA, 0x04C, 0x00093, 0x0, "Anole L2 165 TIMI BA"}, 
+	{HPHW_BA, 0x582, 0x000A5, 0x00, "Epic PCI Bridge"}, 
+	{HPHW_BCPORT, 0x504, 0x00000, 0x00, "Phantom PseudoBC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x505, 0x00000, 0x00, "Phantom PseudoBC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x503, 0x0000C, 0x00, "Java BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x57F, 0x0000C, 0x00, "Hitachi Ghostview GSC+ Port"}, 
+	{HPHW_BCPORT, 0x501, 0x0000C, 0x00, "U2-IOA BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x502, 0x0000C, 0x00, "Uturn-IOA BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x780, 0x0000C, 0x00, "Astro BC Ropes Port"}, 
+	{HPHW_BCPORT, 0x506, 0x0000C, 0x00, "NEC-IOS BC HSC Port"}, 
+	{HPHW_BCPORT, 0x004, 0x0000C, 0x00, "Cheetah BC SMB Port"}, 
+	{HPHW_BCPORT, 0x006, 0x0000C, 0x00, "Cheetah BC MID_BUS Port"}, 
+	{HPHW_BCPORT, 0x005, 0x0000C, 0x00, "Condor BC MID_BUS Port"}, 
+	{HPHW_BCPORT, 0x100, 0x0000C, 0x00, "Condor BC HP-PB Port"}, 
+	{HPHW_BCPORT, 0x184, 0x0000C, 0x00, "Summit BC Port"}, 
+	{HPHW_BCPORT, 0x101, 0x0000C, 0x00, "Summit BC HP-PB Port"}, 
+	{HPHW_BCPORT, 0x102, 0x0000C, 0x00, "HP-PB Port (prefetch)"}, 
+	{HPHW_BCPORT, 0x500, 0x0000C, 0x00, "Gecko BOA BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x103, 0x0000C, 0x00, "Gecko BOA BC HP-PB Port"}, 
+	{HPHW_BCPORT, 0x507, 0x0000C, 0x00, "Keyaki BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x508, 0x0000C, 0x00, "Keyaki-DX BC GSC+ Port"}, 
+	{HPHW_BCPORT, 0x584, 0x0000C, 0x10, "DEW BC Runway Port"}, 
+	{HPHW_BCPORT, 0x800, 0x0000C, 0x10, "DEW BC Merced Port"}, 
+	{HPHW_BCPORT, 0x801, 0x0000C, 0x10, "SMC Bus Interface Merced Bus0"}, 
+	{HPHW_BCPORT, 0x802, 0x0000C, 0x10, "SMC Bus INterface Merced Bus1"}, 
+	{HPHW_BCPORT, 0x803, 0x0000C, 0x10, "IKE I/O BC Merced Port"}, 
+	{HPHW_BCPORT, 0x781, 0x0000C, 0x00, "IKE I/O BC Ropes Port"}, 
+	{HPHW_BCPORT, 0x804, 0x0000C, 0x10, "REO I/O BC Merced Port"}, 
+	{HPHW_BCPORT, 0x782, 0x0000C, 0x00, "REO I/O BC Ropes Port"}, 
+	{HPHW_BCPORT, 0x784, 0x0000C, 0x00, "Pluto I/O BC Ropes Port"}, 
+	{HPHW_BRIDGE, 0x05D, 0x0000A, 0x00, "SummitHawk Dino PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x680, 0x0000A, 0x00, "Dino PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x682, 0x0000A, 0x00, "Cujo PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x782, 0x0000A, 0x00, "Elroy PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x583, 0x000A5, 0x00, "Saga PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x783, 0x0000A, 0x00, "Mercury PCI Bridge"}, 
+	{HPHW_BRIDGE, 0x784, 0x0000A, 0x00, "Quicksilver AGP Bridge"}, 
+	{HPHW_B_DMA, 0x004, 0x00018, 0x00, "Parallel I/O"}, 
+	{HPHW_B_DMA, 0x004, 0x00019, 0x00, "Parallel RDB"}, 
+	{HPHW_B_DMA, 0x004, 0x00020, 0x80, "MID_BUS PSI"}, 
+	{HPHW_B_DMA, 0x004, 0x0002F, 0x80, "HP-PB Transit PSI (36960A)"}, 
+	{HPHW_B_DMA, 0x008, 0x00051, 0x80, "HP-PB Transit 802.3"}, 
+	{HPHW_B_DMA, 0x004, 0x00052, 0x80, "Miura LAN/Console (J2146A)"}, 
+	{HPHW_B_DMA, 0x008, 0x00058, 0x80, "HP-PB Transit 802.4"}, 
+	{HPHW_B_DMA, 0x005, 0x00060, 0x80, "KittyHawk CSY Core LAN/Console"}, 
+	{HPHW_B_DMA, 0x014, 0x00060, 0x80, "Diablo LAN/Console"}, 
+	{HPHW_B_DMA, 0x054, 0x00060, 0x80, "Countach LAN/Console"}, 
+	{HPHW_B_DMA, 0x004, 0x00094, 0x80, "KittyHawk GSC+ Exerciser"}, 
+	{HPHW_B_DMA, 0x004, 0x00100, 0x80, "HP-PB HF Interface"}, 
+	{HPHW_B_DMA, 0x000, 0x00206, 0x80, "MELCO HMPHA"}, 
+	{HPHW_B_DMA, 0x005, 0x00206, 0x80, "MELCO HMPHA_10"}, 
+	{HPHW_B_DMA, 0x006, 0x00206, 0x80, "MELCO HMQHA"}, 
+	{HPHW_B_DMA, 0x007, 0x00206, 0x80, "MELCO HMQHA_10"}, 
+	{HPHW_B_DMA, 0x004, 0x207, 0x80, "MELCO HNDWA MDWS-70"}, 
+	{HPHW_CIO, 0x004, 0x00010, 0x00, "VLSI CIO"}, 
+	{HPHW_CIO, 0x005, 0x00010, 0x00, "Silverfox CIO"}, 
+	{HPHW_CIO, 0x006, 0x00010, 0x00, "Emerald CIO"}, 
+	{HPHW_CIO, 0x008, 0x00010, 0x00, "Discrete CIO"}, 
+	{HPHW_CONSOLE, 0x004, 0x0001C, 0x00, "Cheetah console"}, 
+	{HPHW_CONSOLE, 0x005, 0x0001C, 0x00, "Emerald console"}, 
+	{HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 
+	{HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 
+	{HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 
+	{HPHW_FABRIC, 0x005, 0x000AA, 0x80, "Keystone DNA Central Agent"},
+	{HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 
+	{HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 
+	{HPHW_FABRIC, 0x005, 0x000AB, 0x00, "Keystone TOGO Fabric Crossbar"},
+	{HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 
+	{HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 
+	{HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"}, 
+	{HPHW_FIO, 0x004, 0x00071, 0x0, "Cobra Core SCSI"}, 
+	{HPHW_FIO, 0x005, 0x00071, 0x0, "Coral Core SCSI"}, 
+	{HPHW_FIO, 0x006, 0x00071, 0x0, "Bushmaster Core SCSI"}, 
+	{HPHW_FIO, 0x007, 0x00071, 0x0, "Scorpio Core SCSI"}, 
+	{HPHW_FIO, 0x008, 0x00071, 0x0, "Flounder Core SCSI"}, 
+	{HPHW_FIO, 0x009, 0x00071, 0x0, "Outfield Core SCSI"}, 
+	{HPHW_FIO, 0x00A, 0x00071, 0x0, "CoralII Core SCSI"}, 
+	{HPHW_FIO, 0x00B, 0x00071, 0x0, "Scorpio Jr. Core SCSI"}, 
+	{HPHW_FIO, 0x00C, 0x00071, 0x0, "Strider-50 Core SCSI"}, 
+	{HPHW_FIO, 0x00D, 0x00071, 0x0, "Strider-33 Core SCSI"}, 
+	{HPHW_FIO, 0x00E, 0x00071, 0x0, "Trailways-50 Core SCSI"}, 
+	{HPHW_FIO, 0x00F, 0x00071, 0x0, "Trailways-33 Core SCSI"}, 
+	{HPHW_FIO, 0x010, 0x00071, 0x0, "Pace Core SCSI"}, 
+	{HPHW_FIO, 0x011, 0x00071, 0x0, "Sidewinder Core SCSI"}, 
+	{HPHW_FIO, 0x019, 0x00071, 0x0, "Scorpio Sr. Core SCSI"}, 
+	{HPHW_FIO, 0x020, 0x00071, 0x0, "Scorpio 100 Core SCSI"}, 
+	{HPHW_FIO, 0x021, 0x00071, 0x0, "Spectra 50 Core SCSI"}, 
+	{HPHW_FIO, 0x022, 0x00071, 0x0, "Spectra 75 Core SCSI"}, 
+	{HPHW_FIO, 0x023, 0x00071, 0x0, "Spectra 100 Core SCSI"}, 
+	{HPHW_FIO, 0x024, 0x00071, 0x0, "Fast Pace Core SCSI"}, 
+	{HPHW_FIO, 0x026, 0x00071, 0x0, "CoralII Jaguar Core SCSI"}, 
+	{HPHW_FIO, 0x004, 0x00072, 0x0, "Cobra Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x005, 0x00072, 0x0, "Coral Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x006, 0x00072, 0x0, "Bushmaster Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x007, 0x00072, 0x0, "Scorpio Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x008, 0x00072, 0x0, "Flounder Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x009, 0x00072, 0x0, "Outfield Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00A, 0x00072, 0x0, "CoralII Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00B, 0x00072, 0x0, "Scorpio Jr. Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00C, 0x00072, 0x0, "Strider-50 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00D, 0x00072, 0x0, "Strider-33 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00E, 0x00072, 0x0, "Trailways-50 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x00F, 0x00072, 0x0, "Trailways-33 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x019, 0x00072, 0x0, "Scorpio Sr. Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x020, 0x00072, 0x0, "Scorpio 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x021, 0x00072, 0x0, "Spectra 50 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x022, 0x00072, 0x0, "Spectra 75 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x023, 0x00072, 0x0, "Spectra 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x026, 0x00072, 0x0, "CoralII Jaguar Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x004, 0x00073, 0x0, "Cobra Core HIL"}, 
+	{HPHW_FIO, 0x005, 0x00073, 0x0, "Coral Core HIL"}, 
+	{HPHW_FIO, 0x006, 0x00073, 0x0, "Bushmaster Core HIL"}, 
+	{HPHW_FIO, 0x007, 0x00073, 0x0, "Scorpio Core HIL"}, 
+	{HPHW_FIO, 0x008, 0x00073, 0x0, "Flounder Core HIL"}, 
+	{HPHW_FIO, 0x009, 0x00073, 0x0, "Outfield Core HIL"}, 
+	{HPHW_FIO, 0x00A, 0x00073, 0x0, "CoralII Core HIL"}, 
+	{HPHW_FIO, 0x00B, 0x00073, 0x0, "Scorpio Jr. Core HIL"}, 
+	{HPHW_FIO, 0x00C, 0x00073, 0x0, "Strider-50 Core HIL"}, 
+	{HPHW_FIO, 0x00D, 0x00073, 0x0, "Strider-33 Core HIL"}, 
+	{HPHW_FIO, 0x00E, 0x00073, 0x0, "Trailways-50 Core HIL"}, 
+	{HPHW_FIO, 0x00F, 0x00073, 0x0, "Trailways-33 Core HIL"}, 
+	{HPHW_FIO, 0x010, 0x00073, 0x0, "Pace Core HIL"}, 
+	{HPHW_FIO, 0x011, 0x00073, 0xcc, "SuperPace Wax HIL"}, 
+	{HPHW_FIO, 0x012, 0x00073, 0x0, "Mirage Jr Wax HIL"}, 
+	{HPHW_FIO, 0x013, 0x00073, 0x0, "Mirage 100 Wax HIL"}, 
+	{HPHW_FIO, 0x014, 0x00073, 0x0, "Electra Wax HIL"}, 
+	{HPHW_FIO, 0x017, 0x00073, 0x0, "Raven Backplane Wax HIL"}, 
+	{HPHW_FIO, 0x019, 0x00073, 0x0, "Scorpio Sr. Core HIL"}, 
+	{HPHW_FIO, 0x01E, 0x00073, 0x0, "Raven T' Wax HIL"}, 
+	{HPHW_FIO, 0x01F, 0x00073, 0x0, "SkyHawk 100/120 Wax HIL"}, 
+	{HPHW_FIO, 0x020, 0x00073, 0x0, "Scorpio 100 Core HIL"}, 
+	{HPHW_FIO, 0x021, 0x00073, 0x0, "Spectra 50 Core HIL"}, 
+	{HPHW_FIO, 0x022, 0x00073, 0x0, "Spectra 75 Core HIL"}, 
+	{HPHW_FIO, 0x023, 0x00073, 0x0, "Spectra 100 Core HIL"}, 
+	{HPHW_FIO, 0x024, 0x00073, 0x0, "Fast Pace Core HIL"}, 
+	{HPHW_FIO, 0x026, 0x00073, 0x0, "CoralII Jaguar Core HIL"}, 
+	{HPHW_FIO, 0x02B, 0x00073, 0x0, "Mirage 80 Wax HIL"}, 
+	{HPHW_FIO, 0x02C, 0x00073, 0x0, "Mirage 100+ Wax HIL"}, 
+	{HPHW_FIO, 0x03A, 0x00073, 0x0, "Merlin+ Wax HIL"}, 
+	{HPHW_FIO, 0x040, 0x00073, 0x0, "Merlin 132 Wax HIL"}, 
+	{HPHW_FIO, 0x041, 0x00073, 0x0, "Merlin 160 Wax HIL"}, 
+	{HPHW_FIO, 0x043, 0x00073, 0x0, "Merlin 132/160 Wax HIL"}, 
+	{HPHW_FIO, 0x052, 0x00073, 0x0, "Raven+ Hi Power Backplane w/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x053, 0x00073, 0x0, "Raven+ Hi Power Backplane wo/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x054, 0x00073, 0x0, "Raven+ Lo Power Backplane w/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x055, 0x00073, 0x0, "Raven+ Lo Power Backplane wo/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x059, 0x00073, 0x0, "FireHawk 200 Wax HIL"}, 
+	{HPHW_FIO, 0x05A, 0x00073, 0x0, "Raven+ L2 Backplane w/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x05B, 0x00073, 0x0, "Raven+ L2 Backplane wo/EISA Wax HIL"}, 
+	{HPHW_FIO, 0x05D, 0x00073, 0x0, "SummitHawk Wax HIL"}, 
+	{HPHW_FIO, 0x800, 0x00073, 0x0, "Hitachi Tiny 64 Wax HIL"}, 
+	{HPHW_FIO, 0x801, 0x00073, 0x0, "Hitachi Tiny 80 Wax HIL"}, 
+	{HPHW_FIO, 0x004, 0x00074, 0x0, "Cobra Core Centronics"}, 
+	{HPHW_FIO, 0x005, 0x00074, 0x0, "Coral Core Centronics"}, 
+	{HPHW_FIO, 0x006, 0x00074, 0x0, "Bushmaster Core Centronics"}, 
+	{HPHW_FIO, 0x007, 0x00074, 0x0, "Scorpio Core Centronics"}, 
+	{HPHW_FIO, 0x008, 0x00074, 0x0, "Flounder Core Centronics"}, 
+	{HPHW_FIO, 0x009, 0x00074, 0x0, "Outfield Core Centronics"}, 
+	{HPHW_FIO, 0x00A, 0x00074, 0x0, "CoralII Core Centronics"}, 
+	{HPHW_FIO, 0x00B, 0x00074, 0x0, "Scorpio Jr. Core Centronics"}, 
+	{HPHW_FIO, 0x00C, 0x00074, 0x0, "Strider-50 Core Centronics"}, 
+	{HPHW_FIO, 0x00D, 0x00074, 0x0, "Strider-33 Core Centronics"}, 
+	{HPHW_FIO, 0x00E, 0x00074, 0x0, "Trailways-50 Core Centronics"}, 
+	{HPHW_FIO, 0x00F, 0x00074, 0x0, "Trailways-33 Core Centronics"}, 
+	{HPHW_FIO, 0x010, 0x00074, 0x0, "Pace Core Centronics"}, 
+	{HPHW_FIO, 0x011, 0x00074, 0x0, "Sidewinder Core Centronics"}, 
+	{HPHW_FIO, 0x015, 0x00074, 0x0, "KittyHawk GSY Core Centronics"}, 
+	{HPHW_FIO, 0x016, 0x00074, 0x0, "Gecko Core Centronics"}, 
+	{HPHW_FIO, 0x019, 0x00074, 0x0, "Scorpio Sr. Core Centronics"}, 
+	{HPHW_FIO, 0x01A, 0x00074, 0x0, "Anole 64 Core Centronics"}, 
+	{HPHW_FIO, 0x01B, 0x00074, 0x0, "Anole 100 Core Centronics"}, 
+	{HPHW_FIO, 0x01C, 0x00074, 0x0, "Gecko 80 Core Centronics"}, 
+	{HPHW_FIO, 0x01D, 0x00074, 0x0, "Gecko 100 Core Centronics"}, 
+	{HPHW_FIO, 0x01F, 0x00074, 0x0, "SkyHawk 100/120 Core Centronics"}, 
+	{HPHW_FIO, 0x020, 0x00074, 0x0, "Scorpio 100 Core Centronics"}, 
+	{HPHW_FIO, 0x021, 0x00074, 0x0, "Spectra 50 Core Centronics"}, 
+	{HPHW_FIO, 0x022, 0x00074, 0x0, "Spectra 75 Core Centronics"}, 
+	{HPHW_FIO, 0x023, 0x00074, 0x0, "Spectra 100 Core Centronics"}, 
+	{HPHW_FIO, 0x024, 0x00074, 0x0, "Fast Pace Core Centronics"}, 
+	{HPHW_FIO, 0x026, 0x00074, 0x0, "CoralII Jaguar Core Centronics"}, 
+	{HPHW_FIO, 0x027, 0x00074, 0x0, "Piranha 100 Core Centronics"}, 
+	{HPHW_FIO, 0x028, 0x00074, 0x0, "Mirage Jr Core Centronics"}, 
+	{HPHW_FIO, 0x029, 0x00074, 0x0, "Mirage Core Centronics"}, 
+	{HPHW_FIO, 0x02A, 0x00074, 0x0, "Electra Core Centronics"}, 
+	{HPHW_FIO, 0x02B, 0x00074, 0x0, "Mirage 80 Core Centronics"}, 
+	{HPHW_FIO, 0x02C, 0x00074, 0x0, "Mirage 100+ Core Centronics"}, 
+	{HPHW_FIO, 0x02E, 0x00074, 0x0, "UL 350 Core Centronics"}, 
+	{HPHW_FIO, 0x02F, 0x00074, 0x0, "UL 550 Core Centronics"}, 
+	{HPHW_FIO, 0x032, 0x00074, 0x0, "Raven T' Core Centronics"}, 
+	{HPHW_FIO, 0x033, 0x00074, 0x0, "Anole T Core Centronics"}, 
+	{HPHW_FIO, 0x034, 0x00074, 0x0, "SAIC L-80 Core Centronics"}, 
+	{HPHW_FIO, 0x035, 0x00074, 0x0, "PCX-L2 712/132 Core Centronics"}, 
+	{HPHW_FIO, 0x036, 0x00074, 0x0, "PCX-L2 712/160 Core Centronics"}, 
+	{HPHW_FIO, 0x03B, 0x00074, 0x0, "Raven U/L2 Core Centronics"}, 
+	{HPHW_FIO, 0x03C, 0x00074, 0x0, "Merlin 132 Core Centronics"}, 
+	{HPHW_FIO, 0x03D, 0x00074, 0x0, "Merlin 160 Core Centronics"}, 
+	{HPHW_FIO, 0x03E, 0x00074, 0x0, "Merlin+ 132 Core Centronics"}, 
+	{HPHW_FIO, 0x03F, 0x00074, 0x0, "Merlin+ 180 Core Centronics"}, 
+	{HPHW_FIO, 0x044, 0x00074, 0x0, "Mohawk Core Centronics"}, 
+	{HPHW_FIO, 0x045, 0x00074, 0x0, "Rocky1 Core Centronics"}, 
+	{HPHW_FIO, 0x046, 0x00074, 0x0, "Rocky2 120 Core Centronics"}, 
+	{HPHW_FIO, 0x047, 0x00074, 0x0, "Rocky2 150 Core Centronics"}, 
+	{HPHW_FIO, 0x04B, 0x00074, 0x0, "Anole L2 132 Core Centronics"}, 
+	{HPHW_FIO, 0x04D, 0x00074, 0x0, "Anole L2 165 Core Centronics"}, 
+	{HPHW_FIO, 0x050, 0x00074, 0x0, "Merlin Jr 132 Core Centronics"}, 
+	{HPHW_FIO, 0x051, 0x00074, 0x0, "Firehawk Core Centronics"}, 
+	{HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ w SE FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ w Diff FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x058, 0x00074, 0x0, "FireHawk 200 Core Centronics"}, 
+	{HPHW_FIO, 0x05C, 0x00074, 0x0, "SummitHawk 230 Core Centronics"}, 
+	{HPHW_FIO, 0x800, 0x00074, 0x0, "Hitachi Tiny 64 Core Centronics"}, 
+	{HPHW_FIO, 0x801, 0x00074, 0x0, "Hitachi Tiny 80 Core Centronics"}, 
+	{HPHW_FIO, 0x004, 0x00075, 0x0, "Cobra Core RS-232"}, 
+	{HPHW_FIO, 0x005, 0x00075, 0x0, "Coral Core RS-232"}, 
+	{HPHW_FIO, 0x006, 0x00075, 0x0, "Bushmaster Core RS-232"}, 
+	{HPHW_FIO, 0x007, 0x00075, 0x0, "Scorpio Core RS-232"}, 
+	{HPHW_FIO, 0x008, 0x00075, 0x0, "Flounder Core RS-232"}, 
+	{HPHW_FIO, 0x009, 0x00075, 0x0, "Outfield Core RS-232"}, 
+	{HPHW_FIO, 0x00A, 0x00075, 0x0, "CoralII Core RS-232"}, 
+	{HPHW_FIO, 0x00B, 0x00075, 0x0, "Scorpio Jr. Core RS-232"}, 
+	{HPHW_FIO, 0x00C, 0x00075, 0x0, "Strider-50 Core RS-232"}, 
+	{HPHW_FIO, 0x00D, 0x00075, 0x0, "Strider-33 Core RS-232"}, 
+	{HPHW_FIO, 0x00E, 0x00075, 0x0, "Trailways-50 Core RS-232"}, 
+	{HPHW_FIO, 0x00F, 0x00075, 0x0, "Trailways-33 Core RS-232"}, 
+	{HPHW_FIO, 0x010, 0x00075, 0x0, "Pace Core RS-232"}, 
+	{HPHW_FIO, 0x011, 0x00075, 0x0, "Sidewinder Core RS-232"}, 
+	{HPHW_FIO, 0x019, 0x00075, 0x0, "Scorpio Sr. Core RS-232"}, 
+	{HPHW_FIO, 0x020, 0x00075, 0x0, "Scorpio 100 Core RS-232"}, 
+	{HPHW_FIO, 0x021, 0x00075, 0x0, "Spectra 50 Core RS-232"}, 
+	{HPHW_FIO, 0x022, 0x00075, 0x0, "Spectra 75 Core RS-232"}, 
+	{HPHW_FIO, 0x023, 0x00075, 0x0, "Spectra 100 Core RS-232"}, 
+	{HPHW_FIO, 0x024, 0x00075, 0x0, "Fast Pace Core RS-232"}, 
+	{HPHW_FIO, 0x026, 0x00075, 0x0, "CoralII Jaguar Core RS-232"}, 
+	{HPHW_FIO, 0x004, 0x00077, 0x0, "Coral SGC Graphics"}, 
+	{HPHW_FIO, 0x005, 0x00077, 0x0, "Hyperdrive Optional Graphics"}, 
+	{HPHW_FIO, 0x006, 0x00077, 0x0, "Stinger Optional Graphics"}, 
+	{HPHW_FIO, 0x007, 0x00077, 0x0, "Scorpio Builtin Graphics"}, 
+	{HPHW_FIO, 0x008, 0x00077, 0x0, "Anole Hyperdrive Optional Graphics"}, 
+	{HPHW_FIO, 0x009, 0x00077, 0x0, "Thunder II graphics EISA form"}, 
+	{HPHW_FIO, 0x00A, 0x00077, 0x0, "Thunder II graphics GSA form"}, 
+	{HPHW_FIO, 0x00B, 0x00077, 0x0, "Scorpio Jr Builtin Graphics"}, 
+	{HPHW_FIO, 0x00C, 0x00077, 0x0, "Strider-50 SSC Graphics"}, 
+	{HPHW_FIO, 0x00D, 0x00077, 0x0, "Strider-33 SSC Graphics"}, 
+	{HPHW_FIO, 0x00E, 0x00077, 0x0, "Trailways-50 SSC Graphics"}, 
+	{HPHW_FIO, 0x00F, 0x00077, 0x0, "Trailways-33 SSC Graphics"}, 
+	{HPHW_FIO, 0x010, 0x00077, 0x0, "Pace SGC Graphics"}, 
+	{HPHW_FIO, 0x011, 0x00077, 0x0, "Mohawk Opt. 2D Graphics (Kid)"}, 
+	{HPHW_FIO, 0x012, 0x00077, 0x0, "Raven Opt. 2D Graphics (Goat)"}, 
+	{HPHW_FIO, 0x016, 0x00077, 0x0, "Lego 24 SCG Graphics"}, 
+	{HPHW_FIO, 0x017, 0x00077, 0x0, "Lego 24Z SCG Graphics"}, 
+	{HPHW_FIO, 0x018, 0x00077, 0x0, "Lego 48Z SCG Graphics"}, 
+	{HPHW_FIO, 0x019, 0x00077, 0x0, "Scorpio Sr Builtin Graphics"}, 
+	{HPHW_FIO, 0x020, 0x00077, 0x0, "Scorpio 100 Builtin Graphics"}, 
+	{HPHW_FIO, 0x021, 0x00077, 0x0, "Spectra 50 Builtin Graphics"}, 
+	{HPHW_FIO, 0x022, 0x00077, 0x0, "Spectra 75 Builtin Graphics"}, 
+	{HPHW_FIO, 0x023, 0x00077, 0x0, "Spectra 100 Builtin Graphics"}, 
+	{HPHW_FIO, 0x024, 0x00077, 0x0, "Fast Pace SGC Graphics"}, 
+	{HPHW_FIO, 0x006, 0x0007A, 0x0, "Bushmaster Audio"}, 
+	{HPHW_FIO, 0x008, 0x0007A, 0x0, "Flounder Audio"}, 
+	{HPHW_FIO, 0x004, 0x0007B, 0x0, "UL Optional Audio"}, 
+	{HPHW_FIO, 0x007, 0x0007B, 0x0, "Scorpio Audio"}, 
+	{HPHW_FIO, 0x00B, 0x0007B, 0x0, "Scorpio Jr. Audio"}, 
+	{HPHW_FIO, 0x00C, 0x0007B, 0x0, "Strider-50 Audio"}, 
+	{HPHW_FIO, 0x00D, 0x0007B, 0x0, "Strider-33 Audio"}, 
+	{HPHW_FIO, 0x00E, 0x0007B, 0x0, "Trailways-50 Audio"}, 
+	{HPHW_FIO, 0x00F, 0x0007B, 0x0, "Trailways-33 Audio"}, 
+	{HPHW_FIO, 0x015, 0x0007B, 0x0, "KittyHawk GSY Core Audio"}, 
+	{HPHW_FIO, 0x016, 0x0007B, 0x0, "Gecko Audio"}, 
+	{HPHW_FIO, 0x019, 0x0007B, 0x0, "Scorpio Sr. Audio"}, 
+	{HPHW_FIO, 0x01A, 0x0007B, 0x0, "Anole 64 Audio"}, 
+	{HPHW_FIO, 0x01B, 0x0007B, 0x0, "Anole 100 Audio"}, 
+	{HPHW_FIO, 0x01C, 0x0007B, 0x0, "Gecko 80 Audio"}, 
+	{HPHW_FIO, 0x01D, 0x0007B, 0x0, "Gecko 100 Audio"}, 
+	{HPHW_FIO, 0x01F, 0x0007B, 0x0, "SkyHawk 100/120 Audio"}, 
+	{HPHW_FIO, 0x020, 0x0007B, 0x0, "Scorpio 100 Audio"}, 
+	{HPHW_FIO, 0x021, 0x0007B, 0x0, "Spectra 50 Audio"}, 
+	{HPHW_FIO, 0x022, 0x0007B, 0x0, "Spectra 75 Audio"}, 
+	{HPHW_FIO, 0x023, 0x0007B, 0x0, "Spectra 100 Audio"}, 
+	{HPHW_FIO, 0x028, 0x0007B, 0x0, "Mirage Jr Audio"}, 
+	{HPHW_FIO, 0x029, 0x0007B, 0x0, "Mirage Audio"}, 
+	{HPHW_FIO, 0x02A, 0x0007B, 0x0, "Electra Audio"}, 
+	{HPHW_FIO, 0x02B, 0x0007B, 0x0, "Mirage 80 Audio"}, 
+	{HPHW_FIO, 0x02C, 0x0007B, 0x0, "Mirage 100+ Audio"}, 
+	{HPHW_FIO, 0x032, 0x0007B, 0x0, "Raven T' Audio"}, 
+	{HPHW_FIO, 0x034, 0x0007B, 0x0, "SAIC L-80 Audio"}, 
+	{HPHW_FIO, 0x035, 0x0007B, 0x0, "PCX-L2 712/132 Core Audio"}, 
+	{HPHW_FIO, 0x036, 0x0007B, 0x0, "PCX-L2 712/160 Core Audio"}, 
+	{HPHW_FIO, 0x03B, 0x0007B, 0x0, "Raven U/L2 Core Audio"}, 
+	{HPHW_FIO, 0x03C, 0x0007B, 0x0, "Merlin 132 Core Audio"}, 
+	{HPHW_FIO, 0x03D, 0x0007B, 0x0, "Merlin 160 Core Audio"}, 
+	{HPHW_FIO, 0x03E, 0x0007B, 0x0, "Merlin+ 132 Core Audio"}, 
+	{HPHW_FIO, 0x03F, 0x0007B, 0x0, "Merlin+ 180 Core Audio"}, 
+	{HPHW_FIO, 0x044, 0x0007B, 0x0, "Mohawk Core Audio"}, 
+	{HPHW_FIO, 0x046, 0x0007B, 0x0, "Rocky2 120 Core Audio"}, 
+	{HPHW_FIO, 0x047, 0x0007B, 0x0, "Rocky2 150 Core Audio"}, 
+	{HPHW_FIO, 0x04B, 0x0007B, 0x0, "Anole L2 132 Core Audio"}, 
+	{HPHW_FIO, 0x04D, 0x0007B, 0x0, "Anole L2 165 Core Audio"}, 
+	{HPHW_FIO, 0x04E, 0x0007B, 0x0, "Kiji L2 132 Core Audio"}, 
+	{HPHW_FIO, 0x050, 0x0007B, 0x0, "Merlin Jr 132 Core Audio"}, 
+	{HPHW_FIO, 0x051, 0x0007B, 0x0, "Firehawk Audio"}, 
+	{HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSI Core Audio"}, 
+	{HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSI Core Audio"}, 
+	{HPHW_FIO, 0x058, 0x0007B, 0x0, "FireHawk 200 Audio"}, 
+	{HPHW_FIO, 0x05C, 0x0007B, 0x0, "SummitHawk 230 Core Audio"}, 
+	{HPHW_FIO, 0x800, 0x0007B, 0x0, "Hitachi Tiny 64 Audio"}, 
+	{HPHW_FIO, 0x801, 0x0007B, 0x0, "Hitachi Tiny 80 Audio"}, 
+	{HPHW_FIO, 0x009, 0x0007C, 0x0, "Outfield FW SCSI"}, 
+	{HPHW_FIO, 0x00A, 0x0007C, 0x0, "CoralII FW SCSI"}, 
+	{HPHW_FIO, 0x026, 0x0007C, 0x0, "CoralII Jaguar FW SCSI"}, 
+	{HPHW_FIO, 0x009, 0x0007D, 0x0, "Outfield FDDI"}, 
+	{HPHW_FIO, 0x00A, 0x0007D, 0x0, "CoralII FDDI"}, 
+	{HPHW_FIO, 0x026, 0x0007D, 0x0, "CoralII Jaguar FDDI"}, 
+	{HPHW_FIO, 0x010, 0x0007E, 0x0, "Pace Audio"}, 
+	{HPHW_FIO, 0x024, 0x0007E, 0x0, "Fast Pace Audio"}, 
+	{HPHW_FIO, 0x009, 0x0007F, 0x0, "Outfield Audio"}, 
+	{HPHW_FIO, 0x00A, 0x0007F, 0x0, "CoralII Audio"}, 
+	{HPHW_FIO, 0x026, 0x0007F, 0x0, "CoralII Jaguar Audio"}, 
+	{HPHW_FIO, 0x010, 0x00080, 0x0, "Pace Core HPIB"}, 
+	{HPHW_FIO, 0x024, 0x00080, 0x0, "Fast Pace Core HPIB"}, 
+	{HPHW_FIO, 0x015, 0x00082, 0x0, "KittyHawk GSY Core SCSI"},
+	{HPHW_FIO, 0x016, 0x00082, 0x0, "Gecko Core SCSI"}, 
+	{HPHW_FIO, 0x01A, 0x00082, 0x0, "Anole 64 Core SCSI"}, 
+	{HPHW_FIO, 0x01B, 0x00082, 0x0, "Anole 100 Core SCSI"}, 
+	{HPHW_FIO, 0x01C, 0x00082, 0x0, "Gecko 80 Core SCSI"}, 
+	{HPHW_FIO, 0x01D, 0x00082, 0x0, "Gecko 100 Core SCSI"}, 
+	{HPHW_FIO, 0x01F, 0x00082, 0x0, "SkyHawk 100/120 Core SCSI"}, 
+	{HPHW_FIO, 0x027, 0x00082, 0x0, "Piranha 100 Core SCSI"}, 
+	{HPHW_FIO, 0x028, 0x00082, 0x0, "Mirage Jr Core SCSI"}, 
+	{HPHW_FIO, 0x029, 0x00082, 0x0, "Mirage Core SCSI"}, 
+	{HPHW_FIO, 0x02A, 0x00082, 0x0, "Electra Core SCSI"}, 
+	{HPHW_FIO, 0x02B, 0x00082, 0x0, "Mirage 80 Core SCSI"}, 
+	{HPHW_FIO, 0x02C, 0x00082, 0x0, "Mirage 100+ Core SCSI"}, 
+	{HPHW_FIO, 0x02E, 0x00082, 0x0, "UL 350 Core SCSI"}, 
+	{HPHW_FIO, 0x02F, 0x00082, 0x0, "UL 550 Core SCSI"}, 
+	{HPHW_FIO, 0x032, 0x00082, 0x0, "Raven T' Core SCSI"}, 
+	{HPHW_FIO, 0x033, 0x00082, 0x0, "Anole T Core SCSI"}, 
+	{HPHW_FIO, 0x034, 0x00082, 0x0, "SAIC L-80 Core SCSI"}, 
+	{HPHW_FIO, 0x035, 0x00082, 0x0, "PCX-L2 712/132 Core SCSI"}, 
+	{HPHW_FIO, 0x036, 0x00082, 0x0, "PCX-L2 712/160 Core SCSI"}, 
+	{HPHW_FIO, 0x03B, 0x00082, 0x0, "Raven U/L2 Core SCSI"}, 
+	{HPHW_FIO, 0x03C, 0x00082, 0x0, "Merlin 132 Core SCSI"}, 
+	{HPHW_FIO, 0x03D, 0x00082, 0x0, "Merlin 160 Core SCSI"}, 
+	{HPHW_FIO, 0x03E, 0x00082, 0x0, "Merlin+ 132 Core SCSI"}, 
+	{HPHW_FIO, 0x03F, 0x00082, 0x0, "Merlin+ 180 Core SCSI"}, 
+	{HPHW_FIO, 0x044, 0x00082, 0x0, "Mohawk Core SCSI"}, 
+	{HPHW_FIO, 0x045, 0x00082, 0x0, "Rocky1 Core SCSI"}, 
+	{HPHW_FIO, 0x046, 0x00082, 0x0, "Rocky2 120 Core SCSI"}, 
+	{HPHW_FIO, 0x047, 0x00082, 0x0, "Rocky2 150 Core SCSI"}, 
+	{HPHW_FIO, 0x04B, 0x00082, 0x0, "Anole L2 132 Core SCSI"}, 
+	{HPHW_FIO, 0x04D, 0x00082, 0x0, "Anole L2 165 Core SCSI"}, 
+	{HPHW_FIO, 0x04E, 0x00082, 0x0, "Kiji L2 132 Core SCSI"}, 
+	{HPHW_FIO, 0x050, 0x00082, 0x0, "Merlin Jr 132 Core SCSI"}, 
+	{HPHW_FIO, 0x051, 0x00082, 0x0, "Firehawk Core SCSI"}, 
+	{HPHW_FIO, 0x056, 0x00082, 0x0, "Raven+ w SE FWSCSI Core SCSI"}, 
+	{HPHW_FIO, 0x057, 0x00082, 0x0, "Raven+ w Diff FWSCSI Core SCSI"}, 
+	{HPHW_FIO, 0x058, 0x00082, 0x0, "FireHawk 200 Core SCSI"}, 
+	{HPHW_FIO, 0x05C, 0x00082, 0x0, "SummitHawk 230 Core SCSI"}, 
+	{HPHW_FIO, 0x05E, 0x00082, 0x0, "Staccato 132 Core SCSI"}, 
+	{HPHW_FIO, 0x05F, 0x00082, 0x0, "Staccato 180 Core SCSI"}, 
+	{HPHW_FIO, 0x800, 0x00082, 0x0, "Hitachi Tiny 64 Core SCSI"}, 
+	{HPHW_FIO, 0x801, 0x00082, 0x0, "Hitachi Tiny 80 Core SCSI"}, 
+	{HPHW_FIO, 0x016, 0x00083, 0x0, "Gecko Core PC Floppy"}, 
+	{HPHW_FIO, 0x01C, 0x00083, 0x0, "Gecko 80 Core PC Floppy"}, 
+	{HPHW_FIO, 0x01D, 0x00083, 0x0, "Gecko 100 Core PC Floppy"}, 
+	{HPHW_FIO, 0x051, 0x00083, 0x0, "Firehawk Core PC Floppy"}, 
+	{HPHW_FIO, 0x058, 0x00083, 0x0, "FireHawk 200 Core PC Floppy"}, 
+	{HPHW_FIO, 0x027, 0x00083, 0x0, "Piranha 100 Core PC Floppy"}, 
+	{HPHW_FIO, 0x028, 0x00083, 0x0, "Mirage Jr Core PC Floppy"}, 
+	{HPHW_FIO, 0x029, 0x00083, 0x0, "Mirage Core PC Floppy"}, 
+	{HPHW_FIO, 0x02A, 0x00083, 0x0, "Electra Core PC Floppy"}, 
+	{HPHW_FIO, 0x02B, 0x00083, 0x0, "Mirage 80 Core PC Floppy"}, 
+	{HPHW_FIO, 0x02C, 0x00083, 0x0, "Mirage 100+ Core PC Floppy"}, 
+	{HPHW_FIO, 0x02E, 0x00083, 0x0, "UL 350 Core PC Floppy"}, 
+	{HPHW_FIO, 0x02F, 0x00083, 0x0, "UL 550 Core PC Floppy"}, 
+	{HPHW_FIO, 0x032, 0x00083, 0x0, "Raven T' Core PC Floppy"}, 
+	{HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floppy"}, 
+	{HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floppy"}, 
+	{HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floppy"}, 
+	{HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floppy"}, 
+	{HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floppy"}, 
+	{HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floppy"}, 
+	{HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floppy"}, 
+	{HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floppy"}, 
+	{HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floppy"},
+	{HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PS/2 Port"}, 
+	{HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PS/2 Port"}, 
+	{HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PS/2 Port"}, 
+	{HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PS/2 Port"}, 
+	{HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PS/2 Port"}, 
+	{HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PS/2 Port"}, 
+	{HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x004, 0x00085, 0x0, "Solo GSC Optional Graphics"}, 
+	{HPHW_FIO, 0x005, 0x00085, 0x0, "Duet GSC Optional Graphics"}, 
+	{HPHW_FIO, 0x008, 0x00085, 0x0, "Anole Artist Optional Graphics"}, 
+	{HPHW_FIO, 0x010, 0x00085, 0x0, "Mirage 80 GSC Builtin Graphics"}, 
+	{HPHW_FIO, 0x011, 0x00085, 0x0, "Mirage 100+ GSC Builtin Graphics"}, 
+	{HPHW_FIO, 0x012, 0x00085, 0x0, "Mirage Jr GSC Builtin Graphics"}, 
+	{HPHW_FIO, 0x013, 0x00085, 0x0, "Mirage GSC Builtin Graphics"}, 
+	{HPHW_FIO, 0x014, 0x00085, 0x0, "Electra GSC Builtin Graphics"}, 
+	{HPHW_FIO, 0x016, 0x00085, 0x0, "Gecko GSC Core Graphics"}, 
+	{HPHW_FIO, 0x017, 0x00085, 0x0, "Gecko GSC Optional Graphics"}, 
+	{HPHW_FIO, 0x01A, 0x00085, 0x0, "Anole 64 Artist Builtin Graphics"}, 
+	{HPHW_FIO, 0x01B, 0x00085, 0x0, "Anole 100 Artist Builtin Graphics"}, 
+	{HPHW_FIO, 0x01C, 0x00085, 0x0, "Gecko 80 GSC Core Graphics"}, 
+	{HPHW_FIO, 0x01D, 0x00085, 0x0, "Gecko 100 GSC Core Graphics"}, 
+	{HPHW_FIO, 0x032, 0x00085, 0x0, "Raven T' GSC Core Graphics"}, 
+	{HPHW_FIO, 0x033, 0x00085, 0x0, "Anole T Artist Builtin Graphics"}, 
+	{HPHW_FIO, 0x034, 0x00085, 0x0, "SAIC L-80 GSC Core Graphics"}, 
+	{HPHW_FIO, 0x035, 0x00085, 0x0, "PCX-L2 712/132 Core Graphics"}, 
+	{HPHW_FIO, 0x036, 0x00085, 0x0, "PCX-L2 712/160 Core Graphics"}, 
+	{HPHW_FIO, 0x03B, 0x00085, 0x0, "Raven U/L2 Core Graphics"}, 
+	{HPHW_FIO, 0x03C, 0x00085, 0x0, "Merlin 132 Core Graphics"}, 
+	{HPHW_FIO, 0x03D, 0x00085, 0x0, "Merlin 160 Core Graphics"}, 
+	{HPHW_FIO, 0x03E, 0x00085, 0x0, "Merlin+ 132 Core Graphics"}, 
+	{HPHW_FIO, 0x03F, 0x00085, 0x0, "Merlin+ 180 Core Graphics"}, 
+	{HPHW_FIO, 0x045, 0x00085, 0x0, "Rocky1 Core Graphics"}, 
+	{HPHW_FIO, 0x046, 0x00085, 0x0, "Rocky2 120 Core Graphics"}, 
+	{HPHW_FIO, 0x047, 0x00085, 0x0, "Rocky2 150 Core Graphics"}, 
+	{HPHW_FIO, 0x04B, 0x00085, 0x0, "Anole L2 132 Core Graphics"}, 
+	{HPHW_FIO, 0x04D, 0x00085, 0x0, "Anole L2 165 Core Graphics"}, 
+	{HPHW_FIO, 0x04E, 0x00085, 0x0, "Kiji L2 132 Core Graphics"}, 
+	{HPHW_FIO, 0x050, 0x00085, 0x0, "Merlin Jr 132 Core Graphics"}, 
+	{HPHW_FIO, 0x056, 0x00085, 0x0, "Raven+ w SE FWSCSI Core Graphics"}, 
+	{HPHW_FIO, 0x057, 0x00085, 0x0, "Raven+ w Diff FWSCSI Core Graphics"}, 
+	{HPHW_FIO, 0x800, 0x00085, 0x0, "Hitachi Tiny 64 Core Graphics"}, 
+	{HPHW_FIO, 0x801, 0x00085, 0x0, "Hitachi Tiny 80 Core Graphics"}, 
+	{HPHW_FIO, 0x004, 0x00086, 0x0, "GSC IBM Token Ring"}, 
+	{HPHW_FIO, 0x015, 0x00087, 0x0, "Gecko Optional ISDN"}, 
+	{HPHW_FIO, 0x016, 0x00087, 0x0, "Gecko Core ISDN"}, 
+	{HPHW_FIO, 0x01C, 0x00087, 0x0, "Gecko 80 Core ISDN"}, 
+	{HPHW_FIO, 0x01D, 0x00087, 0x0, "Gecko 100 Core ISDN"}, 
+	{HPHW_FIO, 0x010, 0x00088, 0x0, "Pace VME Networking"}, 
+	{HPHW_FIO, 0x011, 0x00088, 0x0, "Sidewinder VME Networking"}, 
+	{HPHW_FIO, 0x01A, 0x00088, 0x0, "Anole 64 VME Networking"}, 
+	{HPHW_FIO, 0x01B, 0x00088, 0x0, "Anole 100 VME Networking"}, 
+	{HPHW_FIO, 0x024, 0x00088, 0x0, "Fast Pace VME Networking"}, 
+	{HPHW_FIO, 0x034, 0x00088, 0x0, "Anole T VME Networking"}, 
+	{HPHW_FIO, 0x04A, 0x00088, 0x0, "Anole L2 132 VME Networking"}, 
+	{HPHW_FIO, 0x04C, 0x00088, 0x0, "Anole L2 165 VME Networking"}, 
+	{HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional LAN (802.3)"}, 
+	{HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01F, 0x0008A, 0x0, "SkyHawk 100/120 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x027, 0x0008A, 0x0, "Piranha 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x028, 0x0008A, 0x0, "Mirage Jr Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x029, 0x0008A, 0x0, "Mirage Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x02A, 0x0008A, 0x0, "Electra Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x02B, 0x0008A, 0x0, "Mirage 80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x02C, 0x0008A, 0x0, "Mirage 100+ Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x02E, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x02F, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x032, 0x0008A, 0x0, "Raven T' Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x045, 0x0008A, 0x0, "Rocky1 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x046, 0x0008A, 0x0, "Rocky2 120 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x047, 0x0008A, 0x0, "Rocky2 150 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x04B, 0x0008A, 0x0, "Anole L2 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x04D, 0x0008A, 0x0, "Anole L2 165 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x04E, 0x0008A, 0x0, "Kiji L2 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x058, 0x0008A, 0x0, "FireHawk 200 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x004, 0x0008C, 0x0, "SkyHawk 100/120 Wax RS-232"}, 
+	{HPHW_FIO, 0x005, 0x0008C, 0x0, "SAIC L-80 Wax RS-232"}, 
+	{HPHW_FIO, 0x006, 0x0008C, 0x0, "Raven U/L2 Dino RS-232"}, 
+	{HPHW_FIO, 0x007, 0x0008C, 0x0, "Dino RS-232"}, 
+	{HPHW_FIO, 0x008, 0x0008C, 0x0, "Merlin 132 Dino RS-232"}, 
+	{HPHW_FIO, 0x009, 0x0008C, 0x0, "Merlin 160 Dino RS-232"}, 
+	{HPHW_FIO, 0x00A, 0x0008C, 0x0, "Merlin Jr 132 Dino RS-232"}, 
+	{HPHW_FIO, 0x010, 0x0008C, 0x0, "Mirage 80 Wax RS-232"}, 
+	{HPHW_FIO, 0x011, 0x0008C, 0x0, "Mirage 100+ Wax RS-232"}, 
+	{HPHW_FIO, 0x012, 0x0008C, 0x0, "Mirage Jr Wax RS-232"}, 
+	{HPHW_FIO, 0x013, 0x0008C, 0x0, "Mirage Wax RS-232"}, 
+	{HPHW_FIO, 0x014, 0x0008C, 0x0, "Electra Wax RS-232"}, 
+	{HPHW_FIO, 0x015, 0x0008C, 0x0, "KittyHawk GSY Core RS-232"}, 
+	{HPHW_FIO, 0x016, 0x0008C, 0x0, "Gecko Core RS-232"}, 
+	{HPHW_FIO, 0x017, 0x0008C, 0x0, "Raven Backplane RS-232"}, 
+	{HPHW_FIO, 0x018, 0x0008C, 0x0, "Gecko Optional RS-232"}, 
+	{HPHW_FIO, 0x019, 0x0008C, 0x0, "Merlin+ 180 Dino RS-232"}, 
+	{HPHW_FIO, 0x01A, 0x0008C, 0x0, "Anole 64 Core RS-232"}, 
+	{HPHW_FIO, 0x01B, 0x0008C, 0x0, "Anole 100 Core RS-232"}, 
+	{HPHW_FIO, 0x01C, 0x0008C, 0x0, "Gecko 80 Core RS-232"}, 
+	{HPHW_FIO, 0x01D, 0x0008C, 0x0, "Gecko 100 Core RS-232"}, 
+	{HPHW_FIO, 0x01E, 0x0008C, 0x0, "Raven T' Wax RS-232"}, 
+	{HPHW_FIO, 0x01F, 0x0008C, 0x0, "SkyHawk 100/120 Core RS-232"}, 
+	{HPHW_FIO, 0x020, 0x0008C, 0x0, "Anole 64 Timi RS-232"}, 
+	{HPHW_FIO, 0x021, 0x0008C, 0x0, "Anole 100 Timi RS-232"}, 
+	{HPHW_FIO, 0x022, 0x0008C, 0x0, "Merlin+ 132 Dino RS-232"}, 
+	{HPHW_FIO, 0x023, 0x0008C, 0x0, "Rocky1 Wax RS-232"}, 
+	{HPHW_FIO, 0x025, 0x0008C, 0x0, "Armyknife Optional RS-232"}, 
+	{HPHW_FIO, 0x026, 0x0008C, 0x0, "Piranha 100 Wax RS-232"}, 
+	{HPHW_FIO, 0x027, 0x0008C, 0x0, "Piranha 100 Core RS-232"}, 
+	{HPHW_FIO, 0x028, 0x0008C, 0x0, "Mirage Jr Core RS-232"}, 
+	{HPHW_FIO, 0x029, 0x0008C, 0x0, "Mirage Core RS-232"}, 
+	{HPHW_FIO, 0x02A, 0x0008C, 0x0, "Electra Core RS-232"}, 
+	{HPHW_FIO, 0x02B, 0x0008C, 0x0, "Mirage 80 Core RS-232"}, 
+	{HPHW_FIO, 0x02C, 0x0008C, 0x0, "Mirage 100+ Core RS-232"}, 
+	{HPHW_FIO, 0x02E, 0x0008C, 0x0, "UL 350 Lasi Core RS-232"}, 
+	{HPHW_FIO, 0x02F, 0x0008C, 0x0, "UL 550 Lasi Core RS-232"}, 
+	{HPHW_FIO, 0x030, 0x0008C, 0x0, "UL 350 Wax Core RS-232"}, 
+	{HPHW_FIO, 0x031, 0x0008C, 0x0, "UL 550 Wax Core RS-232"}, 
+	{HPHW_FIO, 0x032, 0x0008C, 0x0, "Raven T' Lasi Core RS-232"}, 
+	{HPHW_FIO, 0x033, 0x0008C, 0x0, "Anole T Core RS-232"}, 
+	{HPHW_FIO, 0x034, 0x0008C, 0x0, "SAIC L-80 Core RS-232"}, 
+	{HPHW_FIO, 0x035, 0x0008C, 0x0, "PCX-L2 712/132 Core RS-232"}, 
+	{HPHW_FIO, 0x036, 0x0008C, 0x0, "PCX-L2 712/160 Core RS-232"}, 
+	{HPHW_FIO, 0x03A, 0x0008C, 0x0, "Merlin+ Wax RS-232"}, 
+	{HPHW_FIO, 0x03B, 0x0008C, 0x0, "Raven U/L2 Core RS-232"}, 
+	{HPHW_FIO, 0x03C, 0x0008C, 0x0, "Merlin 132 Core RS-232"}, 
+	{HPHW_FIO, 0x03D, 0x0008C, 0x0, "Merlin 160 Core RS-232"}, 
+	{HPHW_FIO, 0x03E, 0x0008C, 0x0, "Merlin+ 132 Core RS-232"}, 
+	{HPHW_FIO, 0x03F, 0x0008C, 0x0, "Merlin+ 180 Core RS-232"}, 
+	{HPHW_FIO, 0x040, 0x0008C, 0x0, "Merlin 132 Wax RS-232"}, 
+	{HPHW_FIO, 0x041, 0x0008C, 0x0, "Merlin 160 Wax RS-232"}, 
+	{HPHW_FIO, 0x043, 0x0008C, 0x0, "Merlin 132/160 Wax RS-232"}, 
+	{HPHW_FIO, 0x044, 0x0008C, 0x0, "Mohawk Core RS-232"}, 
+	{HPHW_FIO, 0x045, 0x0008C, 0x0, "Rocky1 Core RS-232"}, 
+	{HPHW_FIO, 0x046, 0x0008C, 0x0, "Rocky2 120 Core RS-232"}, 
+	{HPHW_FIO, 0x047, 0x0008C, 0x0, "Rocky2 150 Core RS-232"}, 
+	{HPHW_FIO, 0x048, 0x0008C, 0x0, "Rocky2 120 Dino RS-232"}, 
+	{HPHW_FIO, 0x049, 0x0008C, 0x0, "Rocky2 150 Dino RS-232"}, 
+	{HPHW_FIO, 0x04A, 0x0008C, 0x0, "Anole L2 132 TIMI RS-232"}, 
+	{HPHW_FIO, 0x04B, 0x0008C, 0x0, "Anole L2 l32 Core RS-232"}, 
+	{HPHW_FIO, 0x04C, 0x0008D, 0x0, "Anole L2 165 TIMI RS-232"}, 
+	{HPHW_FIO, 0x04D, 0x0008C, 0x0, "Anole L2 165 Core RS-232"}, 
+	{HPHW_FIO, 0x04E, 0x0008C, 0x0, "Kiji L2 132 Core RS-232"}, 
+	{HPHW_FIO, 0x04F, 0x0008C, 0x0, "Kiji L2 132 Dino RS-232"}, 
+	{HPHW_FIO, 0x050, 0x0008C, 0x0, "Merlin Jr 132 Core RS-232"}, 
+	{HPHW_FIO, 0x051, 0x0008C, 0x0, "Firehawk Core RS-232"}, 
+	{HPHW_FIO, 0x052, 0x0008C, 0x0, "Raven+ Hi Power Backplane w EISA RS-232"}, 
+	{HPHW_FIO, 0x053, 0x0008C, 0x0, "Raven+ Hi Power Backplane w/o EISA RS-232"}, 
+	{HPHW_FIO, 0x054, 0x0008C, 0x0, "Raven+ Lo Power Backplane w EISA RS-232"}, 
+	{HPHW_FIO, 0x055, 0x0008C, 0x0, "Raven+ Lo Power Backplane w/o EISA RS-232"}, 
+	{HPHW_FIO, 0x056, 0x0008C, 0x0, "Raven+ w SE FWSCSI Core RS-232"}, 
+	{HPHW_FIO, 0x057, 0x0008C, 0x0, "Raven+ w Diff FWSCSI Core RS-232"}, 
+	{HPHW_FIO, 0x058, 0x0008C, 0x0, "FireHawk 200 Core RS-232"}, 
+	{HPHW_FIO, 0x059, 0x0008C, 0x0, "FireHawk 200 Wax RS-232"}, 
+	{HPHW_FIO, 0x05A, 0x0008C, 0x0, "Raven+ L2 Backplane w EISA RS-232"}, 
+	{HPHW_FIO, 0x05B, 0x0008C, 0x0, "Raven+ L2 Backplane w/o EISA RS-232"}, 
+	{HPHW_FIO, 0x05D, 0x0008C, 0x0, "SummitHawk Dino RS-232"}, 
+	{HPHW_FIO, 0x05E, 0x0008C, 0x0, "Staccato 132 Core LAN RS-232"}, 
+	{HPHW_FIO, 0x05F, 0x0008C, 0x0, "Staccato 180 Core LAN RS-232"}, 
+	{HPHW_FIO, 0x800, 0x0008C, 0x0, "Hitachi Tiny 64 Core RS-232"}, 
+	{HPHW_FIO, 0x801, 0x0008C, 0x0, "Hitachi Tiny 80 Core RS-232"}, 
+	{HPHW_FIO, 0x015, 0x0008D, 0x0, "Gecko Optional RJ-16"}, 
+	{HPHW_FIO, 0x016, 0x0008D, 0x0, "Gecko Core RJ-16"}, 
+	{HPHW_FIO, 0x01C, 0x0008D, 0x0, "Gecko 80 Core RJ-16"}, 
+	{HPHW_FIO, 0x01D, 0x0008D, 0x0, "Gecko 100 Core RJ-16"}, 
+	{HPHW_FIO, 0x004, 0x0008F, 0x0, "Anole Boot Rom"}, 
+	{HPHW_FIO, 0x005, 0x0008F, 0x0, "Rocky1 Boot Rom"}, 
+	{HPHW_FIO, 0x006, 0x0008F, 0x0, "Rocky2 120 Boot Rom"}, 
+	{HPHW_FIO, 0x007, 0x0008F, 0x0, "Rocky2 150 Boot Rom"}, 
+	{HPHW_FIO, 0x01B, 0x0008F, 0x0, "Anole 100 Boot Rom"}, 
+	{HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG LAN"}, 
+	{HPHW_FIO, 0x023, 0x00099, 0x0, "Rocky1 Wax HPIB"}, 
+	{HPHW_FIO, 0x048, 0x00099, 0x0, "Rocky2 120 Clark/Dino HPIB"}, 
+	{HPHW_FIO, 0x049, 0x00099, 0x0, "Rocky2 150 Clark/Dino HPIB"}, 
+	{HPHW_FIO, 0x004, 0x000A1, 0x0, "SPP2000 Console TTY"}, 
+	{HPHW_FIO, 0x004, 0x000A2, 0x0, "Forte Core PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x005, 0x000A2, 0x0, "AllegroLow PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x006, 0x000A2, 0x0, "AllegroHIgh Core PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in LAN"}, 
+	{HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI LAN"}, 
+	{HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI LAN"}, 
+	{HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI LAN"}, 
+	{HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI LAN"}, 
+	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI LVD Ultra2 SCSI"}, 
+	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI SE UltraSCSI"}, 
+	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI IDE/ATAPI CD-ROM"}, 
+	{HPHW_FIO, 0x005, 0x000A3, 0x0, "AllegroLow Core PCI LVD Ultra2 SCSI"}, 
+	{HPHW_FIO, 0x005, 0x000A3, 0x0, "AllegroLow Core PCI IDE/ATAPI CD-ROM"}, 
+	{HPHW_FIO, 0x006, 0x000A3, 0x0, "AllegroHigh Core PCI LVD Ultra2 SCSI"}, 
+	{HPHW_FIO, 0x006, 0x000A3, 0x0, "AllegroHigh Core PCI IDE/ATAPI CD-ROM"}, 
+	{HPHW_FIO, 0x007, 0x000A3, 0x0, "PCI Plug-in Disk"}, 
+	{HPHW_FIO, 0x008, 0x000A3, 0x0, "A5158A S FC Tachlite HBA"}, 
+	{HPHW_FIO, 0x009, 0x000A3, 0x0, "A5157A D FC HBA"}, 
+	{HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI LVD Ultra2 SCSI"}, 
+	{HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI NSE UltraSCSI"}, 
+	{HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI WSE UltraSCSI"}, 
+	{HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI IDE/ATAPI CD-ROM"}, 
+	{HPHW_FIO, 0x03E, 0x000A3, 0x0, "Merlin+ 132 Core SE FWSCSI PCI Disk"}, 
+	{HPHW_FIO, 0x03F, 0x000A3, 0x0, "Merlin+ 180 Core SE FWSCSI PCI Disk"}, 
+	{HPHW_FIO, 0x056, 0x000A3, 0x0, "Raven+ w SE FWSCSI Core PCI Disk"}, 
+	{HPHW_FIO, 0x057, 0x000A3, 0x0, "Raven+ w Diff FWSCSI Core PCI Disk"}, 
+	{HPHW_FIO, 0x004, 0x000A4, 0x0, "SPP2000 Core BA"}, 
+	{HPHW_FIO, 0x004, 0x000A6, 0x0, "Sonic Ethernet 802.3 Card"}, 
+	{HPHW_FIO, 0x004, 0x000A9, 0x00, "Forte Core PCI SuperIO RS-232"}, 
+	{HPHW_FIO, 0x004, 0x000A9, 0x00, "Forte Core PCI USB KB"}, 
+	{HPHW_FIO, 0x005, 0x000A9, 0x00, "AllegroLow Core PCI SuperIO RS-232"}, 
+	{HPHW_FIO, 0x005, 0x000A9, 0x00, "AllegroLow Core PCI USB KB"}, 
+	{HPHW_FIO, 0x006, 0x000A9, 0x00, "AllegroHigh Core PCI SuperIO RS-232"}, 
+	{HPHW_FIO, 0x006, 0x000A9, 0x00, "AllegroHigh Core PCI USB KB"}, 
+	{HPHW_FIO, 0x007, 0x000A9, 0x0, "Miscellaneous PCI Plug-in"},
+	{HPHW_FIO, 0x00A, 0x000A9, 0x0, "Lego 360 Core PCI SuperIO RS-232"}, 
+	{HPHW_FIO, 0x00A, 0x000A9, 0x0, "Lego 360 Core PCI USB KB"}, 
+	{HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, 
+	{HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, 
+	{HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, 
+	{HPHW_FIO, 0x076, 0x000AD, 0x0, "Crestone Peak Core RS-232"},
+	{HPHW_FIO, 0x077, 0x000AD, 0x0, "Crestone Peak Fast? Core RS-232"},
+	{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, 
+	{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, 
+	{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, 
+	{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"},
+	{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"},
+	{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"},
+	{HPHW_IOA, 0x880, 0x0000C, 0x10, "Pluto BC McKinley Port"},
+	{HPHW_MEMORY, 0x002, 0x00008, 0x00, "MID_BUS"}, 
+	{HPHW_MEMORY, 0x063, 0x00009, 0x00, "712/132 L2 Upgrade"}, 
+	{HPHW_MEMORY, 0x064, 0x00009, 0x00, "712/160 L2 Upgrade"}, 
+	{HPHW_MEMORY, 0x065, 0x00009, 0x00, "715/132 L2 Upgrade"}, 
+	{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"},
+	{HPHW_MEMORY, 0x0AF, 0x00009, 0x00, "Everest Mako Memory"},
+	{HPHW_OTHER, 0x004, 0x00030, 0x00, "Master"}, 
+	{HPHW_OTHER, 0x004, 0x00034, 0x00, "Slave"}, 
+	{HPHW_OTHER, 0x004, 0x00038, 0x00, "EDU"}, 
+	{HPHW_OTHER, 0x004, 0x00049, 0x00, "LGB Control"}, 
+	{HPHW_MC, 0x004, 0x000C0, 0x00, "BMC IPMI Mgmt Ctlr"}, 
+	{HPHW_FAULTY, 0, }  /* Special Marker for last entry */
+};
+
+
+static struct hp_cpu_type_mask {
+	unsigned short model;
+	unsigned short mask;
+	enum cpu_type cpu;
+} hp_cpu_type_mask_list[] __initdata = {
+
+	{ 0x0000, 0x0ff0, pcx    },  /* 0x0000 - 0x000f */
+	{ 0x0048, 0x0ff0, pcxl   },  /* 0x0040 - 0x004f */
+	{ 0x0080, 0x0ff0, pcx    },  /* 0x0080 - 0x008f */
+	{ 0x0100, 0x0ff0, pcx    },  /* 0x0100 - 0x010f */
+	{ 0x0182, 0x0ffe, pcx    },  /* 0x0182 - 0x0183 */
+	{ 0x0182, 0x0ffe, pcxt   },  /* 0x0182 - 0x0183 */
+	{ 0x0184, 0x0fff, pcxu   },  /* 0x0184 - 0x0184 */
+	{ 0x0200, 0x0ffe, pcxs   },  /* 0x0200 - 0x0201 */
+	{ 0x0202, 0x0fff, pcxs   },  /* 0x0202 - 0x0202 */
+	{ 0x0203, 0x0fff, pcxt   },  /* 0x0203 - 0x0203 */
+	{ 0x0204, 0x0ffc, pcxt   },  /* 0x0204 - 0x0207 */
+	{ 0x0280, 0x0ffc, pcxs   },  /* 0x0280 - 0x0283 */
+	{ 0x0284, 0x0ffc, pcxt   },  /* 0x0284 - 0x0287 */
+	{ 0x0288, 0x0fff, pcxt   },  /* 0x0288 - 0x0288 */
+	{ 0x0300, 0x0ffc, pcxs   },  /* 0x0300 - 0x0303 */
+	{ 0x0310, 0x0ff0, pcxt   },  /* 0x0310 - 0x031f */
+	{ 0x0320, 0x0ff0, pcxt   },  /* 0x0320 - 0x032f */
+	{ 0x0400, 0x0ff0, pcxt   },  /* 0x0400 - 0x040f */
+	{ 0x0480, 0x0ff0, pcxl   },  /* 0x0480 - 0x048f */
+	{ 0x0500, 0x0ff0, pcxl2  },  /* 0x0500 - 0x050f */
+	{ 0x0510, 0x0ff0, pcxl2  },  /* 0x0510 - 0x051f */
+	{ 0x0580, 0x0ff8, pcxt_  },  /* 0x0580 - 0x0587 */
+	{ 0x0588, 0x0ffc, pcxt_  },  /* 0x0588 - 0x058b */
+	{ 0x058c, 0x0ffe, pcxt_  },  /* 0x058c - 0x058d */
+	{ 0x058e, 0x0fff, pcxt_  },  /* 0x058e - 0x058e */
+	{ 0x058f, 0x0fff, pcxu   },  /* 0x058f - 0x058f */
+	{ 0x0590, 0x0ffe, pcxu   },  /* 0x0590 - 0x0591 */
+	{ 0x0592, 0x0fff, pcxt_  },  /* 0x0592 - 0x0592 */
+	{ 0x0593, 0x0fff, pcxu   },  /* 0x0593 - 0x0593 */
+	{ 0x0594, 0x0ffc, pcxu   },  /* 0x0594 - 0x0597 */
+	{ 0x0598, 0x0ffe, pcxu_  },  /* 0x0598 - 0x0599 */
+	{ 0x059a, 0x0ffe, pcxu   },  /* 0x059a - 0x059b */
+	{ 0x059c, 0x0fff, pcxu   },  /* 0x059c - 0x059c */
+	{ 0x059d, 0x0fff, pcxu_  },  /* 0x059d - 0x059d */
+	{ 0x059e, 0x0fff, pcxt_  },  /* 0x059e - 0x059e */
+	{ 0x059f, 0x0fff, pcxu   },  /* 0x059f - 0x059f */
+	{ 0x05a0, 0x0ffe, pcxt_  },  /* 0x05a0 - 0x05a1 */
+	{ 0x05a2, 0x0ffe, pcxu   },  /* 0x05a2 - 0x05a3 */
+	{ 0x05a4, 0x0ffc, pcxu   },  /* 0x05a4 - 0x05a7 */
+	{ 0x05a8, 0x0ffc, pcxu   },  /* 0x05a8 - 0x05ab */
+	{ 0x05ad, 0x0fff, pcxu_  },  /* 0x05ad - 0x05ad */
+	{ 0x05ae, 0x0ffe, pcxu_  },  /* 0x05ae - 0x05af */
+	{ 0x05b0, 0x0ffe, pcxu_  },  /* 0x05b0 - 0x05b1 */
+	{ 0x05b2, 0x0fff, pcxu_  },  /* 0x05b2 - 0x05b2 */
+	{ 0x05b3, 0x0fff, pcxu   },  /* 0x05b3 - 0x05b3 */
+	{ 0x05b4, 0x0fff, pcxw   },  /* 0x05b4 - 0x05b4 */
+	{ 0x05b5, 0x0fff, pcxu_  },  /* 0x05b5 - 0x05b5 */
+	{ 0x05b6, 0x0ffe, pcxu_  },  /* 0x05b6 - 0x05b7 */
+	{ 0x05b8, 0x0ffe, pcxu_  },  /* 0x05b8 - 0x05b9 */
+	{ 0x05ba, 0x0fff, pcxu_  },  /* 0x05ba - 0x05ba */
+	{ 0x05bb, 0x0fff, pcxw   },  /* 0x05bb - 0x05bb */
+	{ 0x05bc, 0x0ffc, pcxw   },  /* 0x05bc - 0x05bf */
+	{ 0x05c0, 0x0ffc, pcxw 	 },  /* 0x05c0 - 0x05c3 */
+	{ 0x05c4, 0x0ffe, pcxw 	 },  /* 0x05c4 - 0x05c5 */
+	{ 0x05c6, 0x0fff, pcxw 	 },  /* 0x05c6 - 0x05c6 */
+	{ 0x05c7, 0x0fff, pcxw_  },  /* 0x05c7 - 0x05c7 */
+	{ 0x05c8, 0x0ffc, pcxw 	 },  /* 0x05c8 - 0x05cb */
+	{ 0x05cc, 0x0ffe, pcxw 	 },  /* 0x05cc - 0x05cd */
+	{ 0x05ce, 0x0ffe, pcxw_  },  /* 0x05ce - 0x05cf */
+	{ 0x05d0, 0x0ffc, pcxw_  },  /* 0x05d0 - 0x05d3 */
+	{ 0x05d4, 0x0ffe, pcxw_  },  /* 0x05d4 - 0x05d5 */
+	{ 0x05d6, 0x0fff, pcxw 	 },  /* 0x05d6 - 0x05d6 */
+	{ 0x05d7, 0x0fff, pcxw_  },  /* 0x05d7 - 0x05d7 */
+	{ 0x05d8, 0x0ffc, pcxw_  },  /* 0x05d8 - 0x05db */
+	{ 0x05dc, 0x0ffe, pcxw2  },  /* 0x05dc - 0x05dd */
+	{ 0x05de, 0x0fff, pcxw_  },  /* 0x05de - 0x05de */
+	{ 0x05df, 0x0fff, pcxw2  },  /* 0x05df - 0x05df */
+	{ 0x05e0, 0x0ffc, pcxw2  },  /* 0x05e0 - 0x05e3 */
+	{ 0x05e4, 0x0fff, pcxw2  },  /* 0x05e4 - 0x05e4 */
+	{ 0x05e5, 0x0fff, pcxw_  },  /* 0x05e5 - 0x05e5 */
+	{ 0x05e6, 0x0ffe, pcxw2  },  /* 0x05e6 - 0x05e7 */
+	{ 0x05e8, 0x0ff8, pcxw2  },  /* 0x05e8 - 0x05ef */
+	{ 0x05f0, 0x0ff0, pcxw2  },  /* 0x05f0 - 0x05ff */
+	{ 0x0600, 0x0fe0, pcxl   },  /* 0x0600 - 0x061f */
+	{ 0x0880, 0x0ff0, mako   },  /* 0x0880 - 0x088f */
+	{ 0x0890, 0x0ff0, mako2  },  /* 0x0890 - 0x089f */
+	{ 0x0000, 0x0000, pcx    }	/* terminate table */
+};
+
+const char * const cpu_name_version[][2] = {
+	[pcx]	= { "PA7000 (PCX)",	"1.0" },
+	[pcxs]	= { "PA7000 (PCX-S)",	"1.1a" },
+	[pcxt]	= { "PA7100 (PCX-T)",	"1.1b" },
+	[pcxt_]	= { "PA7200 (PCX-T')",	"1.1c" },
+	[pcxl]	= { "PA7100LC (PCX-L)",	"1.1d" },
+	[pcxl2]	= { "PA7300LC (PCX-L2)","1.1e" },
+	[pcxu]	= { "PA8000 (PCX-U)",	"2.0" },
+	[pcxu_]	= { "PA8200 (PCX-U+)",	"2.0" },
+	[pcxw]	= { "PA8500 (PCX-W)",	"2.0" },
+	[pcxw_]	= { "PA8600 (PCX-W+)",	"2.0" },
+	[pcxw2]	= { "PA8700 (PCX-W2)",	"2.0" },
+	[mako]	= { "PA8800 (Mako)",	"2.0" },
+	[mako2] = { "PA8900 (Shortfin)","2.0" }
+};
+
+const char * __init parisc_hardware_description(struct parisc_device_id *id)
+{
+	struct hp_hardware *listptr;
+	
+	for (listptr = hp_hardware_list; listptr->hw_type != HPHW_FAULTY; listptr++) {
+		if ((listptr->hw_type == id->hw_type) &&
+				(listptr->hversion == id->hversion) &&
+				(listptr->sversion == id->sversion)){
+			return listptr->name;
+		}
+	}
+
+	/*
+	 * ok, the above hardware table isn't complete, and we haven't found
+	 * our device in this table. So let's now try to find a generic name
+	 * to describe the given hardware...
+	 */
+	switch (id->hw_type) {
+		case HPHW_NPROC:
+			return "Unknown machine";
+
+		case HPHW_A_DIRECT:
+			switch (id->sversion) {
+				case 0x0D: return "MUX port";
+				case 0x0E: return "RS-232 port";
+			}
+			break;
+			
+		case HPHW_MEMORY:
+			return "Memory";
+			
+	}
+	
+	return "unknown device";
+}
+
+
+/* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */
+enum cpu_type __init
+parisc_get_cpu_type(unsigned long hversion)
+{
+	struct hp_cpu_type_mask *ptr;
+	unsigned short model = ((unsigned short) (hversion)) >> 4;
+
+	for (ptr = hp_cpu_type_mask_list; 0 != ptr->mask; ptr++) {
+		if (ptr->model == (model & ptr->mask))
+			return ptr->cpu;
+	}
+	panic("could not identify CPU type\n");
+
+	return pcx;	/* not reached: */
+}
+
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
new file mode 100644
index 0000000..fbb4e43
--- /dev/null
+++ b/arch/parisc/kernel/head.S
@@ -0,0 +1,375 @@
+/* This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2007 by Helge Deller <deller@gmx.de>
+ * Copyright 1999 SuSE GmbH (Philipp Rumpf)
+ * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
+ * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
+ * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
+ * Copyright (C) 2004 Kyle McMartin <kyle@debian.org>
+ *
+ * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/psw.h>
+#include <asm/pdc.h>
+	
+#include <asm/assembly.h>
+#include <asm/pgtable.h>
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	.level	LEVEL
+
+	__INITDATA
+ENTRY(boot_args)
+	.word 0 /* arg0 */
+	.word 0 /* arg1 */
+	.word 0 /* arg2 */
+	.word 0 /* arg3 */
+END(boot_args)
+
+	__HEAD
+
+	.align	4
+	.import init_thread_union,data
+	.import fault_vector_20,code    /* IVA parisc 2.0 32 bit */
+#ifndef CONFIG_64BIT
+        .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
+	.import	$global$		/* forward declaration */
+#endif /*!CONFIG_64BIT*/
+ENTRY(parisc_kernel_start)
+	.proc
+	.callinfo
+
+	/* Make sure sr4-sr7 are set to zero for the kernel address space */
+	mtsp	%r0,%sr4
+	mtsp	%r0,%sr5
+	mtsp	%r0,%sr6
+	mtsp	%r0,%sr7
+
+	/* Clear BSS (shouldn't the boot loader do this?) */
+
+	.import __bss_start,data
+	.import __bss_stop,data
+
+	load32		PA(__bss_start),%r3
+	load32		PA(__bss_stop),%r4
+$bss_loop:
+	cmpb,<<,n       %r3,%r4,$bss_loop
+	stw,ma          %r0,4(%r3)
+
+	/* Save away the arguments the boot loader passed in (32 bit args) */
+	load32		PA(boot_args),%r1
+	stw,ma          %arg0,4(%r1)
+	stw,ma          %arg1,4(%r1)
+	stw,ma          %arg2,4(%r1)
+	stw,ma          %arg3,4(%r1)
+
+	/* Initialize startup VM. Just map first 16/32 MB of memory */
+	load32		PA(swapper_pg_dir),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+#if CONFIG_PGTABLE_LEVELS == 3
+	/* Set pmd in pgd */
+	load32		PA(pmd0),%r5
+	shrd            %r5,PxD_VALUE_SHIFT,%r3	
+	ldo		(PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
+	stw		%r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
+	ldo		ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
+#else
+	/* 2-level page table, so pmd == pgd */
+	ldo		ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
+#endif
+
+	/* Fill in pmd with enough pte directories */
+	load32		PA(pg0),%r1
+	SHRREG		%r1,PxD_VALUE_SHIFT,%r3
+	ldo		(PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
+
+	ldi		ASM_PT_INITIAL,%r1
+
+1:
+	stw		%r3,0(%r4)
+	ldo		(PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+	addib,>		-1,%r1,1b
+#if CONFIG_PGTABLE_LEVELS == 3
+	ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
+#else
+	ldo             ASM_PGD_ENTRY_SIZE(%r4),%r4
+#endif
+
+
+	/* Now initialize the PTEs themselves.  We use RWX for
+	 * everything ... it will get remapped correctly later */
+	ldo		0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
+	load32		(1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
+	load32		PA(pg0),%r1
+
+$pgt_fill_loop:
+	STREGM          %r3,ASM_PTE_ENTRY_SIZE(%r1)
+	ldo		(1<<PFN_PTE_SHIFT)(%r3),%r3 /* add one PFN */
+	addib,>		-1,%r11,$pgt_fill_loop
+	nop
+
+	/* Load the return address...er...crash 'n burn */
+	copy		%r0,%r2
+
+	/* And the RFI Target address too */
+	load32		start_parisc,%r11
+
+	/* And the initial task pointer */
+	load32		init_thread_union,%r6
+	mtctl           %r6,%cr30
+
+	/* And the stack pointer too */
+	ldo             THREAD_SZ_ALGN(%r6),%sp
+
+#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
+	.import _mcount,data
+	/* initialize mcount FPTR */
+	/* Get the global data pointer */
+	loadgp
+	load32		PA(_mcount), %r10
+	std		%dp,0x18(%r10)
+#endif
+
+#ifdef CONFIG_64BIT
+	/* Get PDCE_PROC for monarch CPU. */
+#define MEM_PDC_LO 0x388
+#define MEM_PDC_HI 0x35C
+	ldw             MEM_PDC_LO(%r0),%r3
+	ldw             MEM_PDC_HI(%r0),%r10
+	depd            %r10, 31, 32, %r3        /* move to upper word */
+#endif
+
+
+#ifdef CONFIG_SMP
+	/* Set the smp rendezvous address into page zero.
+	** It would be safer to do this in init_smp_config() but
+	** it's just way easier to deal with here because
+	** of 64-bit function ptrs and the address is local to this file.
+	*/
+	load32		PA(smp_slave_stext),%r10
+	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
+
+	/* FALLTHROUGH */
+	.procend
+
+	/*
+	** Code Common to both Monarch and Slave processors.
+	** Entry:
+	**
+	**  1.1:	
+	**    %r11 must contain RFI target address.
+	**    %r25/%r26 args to pass to target function
+	**    %r2  in case rfi target decides it didn't like something
+	**
+	**  2.0w:
+	**    %r3  PDCE_PROC address
+	**    %r11 RFI target address
+	**
+	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
+	*/
+common_stext:
+	.proc
+	.callinfo
+#else
+	/* Clear PDC entry point - we won't use it */
+	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+#endif /*CONFIG_SMP*/
+
+#ifdef CONFIG_64BIT
+	tophys_r1	%sp
+
+	/* Save the rfi target address */
+	ldd             TI_TASK-THREAD_SZ_ALGN(%sp), %r10
+	tophys_r1       %r10
+	std             %r11,  TASK_PT_GR11(%r10)
+	/* Switch to wide mode Superdome doesn't support narrow PDC
+	** calls.
+	*/
+1:	mfia            %rp             /* clear upper part of pcoq */
+	ldo             2f-1b(%rp),%rp
+	depdi           0,31,32,%rp
+	bv              (%rp)
+	ssm             PSW_SM_W,%r0
+
+        /* Set Wide mode as the "Default" (eg for traps)
+        ** First trap occurs *right* after (or part of) rfi for slave CPUs.
+        ** Someday, palo might not do this for the Monarch either.
+        */
+2:
+	mfctl		%cr30,%r6		/* PCX-W2 firmware bug */
+
+	ldo             PDC_PSW(%r0),%arg0              /* 21 */
+	ldo             PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
+	ldo             PDC_PSW_WIDE_BIT(%r0),%arg2     /* 2 */
+	load32          PA(stext_pdc_ret), %rp
+	bv              (%r3)
+	copy            %r0,%arg3
+
+stext_pdc_ret:
+	mtctl		%r6,%cr30		/* restore task thread info */
+
+	/* restore rfi target address*/
+	ldd             TI_TASK-THREAD_SZ_ALGN(%sp), %r10
+	tophys_r1       %r10
+	ldd             TASK_PT_GR11(%r10), %r11
+	tovirt_r1       %sp
+#endif
+	
+	/* PARANOID: clear user scratch/user space SR's */
+	mtsp	%r0,%sr0
+	mtsp	%r0,%sr1
+	mtsp	%r0,%sr2
+	mtsp	%r0,%sr3
+
+	/* Initialize Protection Registers */
+	mtctl	%r0,%cr8
+	mtctl	%r0,%cr9
+	mtctl	%r0,%cr12
+	mtctl	%r0,%cr13
+
+	/* Initialize the global data pointer */
+	loadgp
+
+	/* Set up our interrupt table.  HPMCs might not work after this! 
+	 *
+	 * We need to install the correct iva for PA1.1 or PA2.0. The
+	 * following short sequence of instructions can determine this
+	 * (without being illegal on a PA1.1 machine).
+	 */
+#ifndef CONFIG_64BIT
+	ldi		32,%r10
+	mtctl		%r10,%cr11
+	.level 2.0
+	mfctl,w		%cr11,%r10
+	.level 1.1
+	comib,<>,n	0,%r10,$is_pa20
+	ldil		L%PA(fault_vector_11),%r10
+	b		$install_iva
+	ldo		R%PA(fault_vector_11)(%r10),%r10
+
+$is_pa20:
+	.level		LEVEL /* restore 1.1 || 2.0w */
+#endif /*!CONFIG_64BIT*/
+	load32		PA(fault_vector_20),%r10
+
+$install_iva:
+	mtctl		%r10,%cr14
+
+	b		aligned_rfi  /* Prepare to RFI! Man all the cannons! */
+	nop
+
+	.align 128
+aligned_rfi:
+	pcxt_ssm_bug
+
+	copy		%r3, %arg0	/* PDCE_PROC for smp_callin() */
+
+	rsm		PSW_SM_QUIET,%r0	/* off troublesome PSW bits */
+	/* Don't need NOPs, have 8 compliant insn before rfi */
+
+	mtctl		%r0,%cr17	/* Clear IIASQ tail */
+	mtctl		%r0,%cr17	/* Clear IIASQ head */
+
+	/* Load RFI target into PC queue */
+	mtctl		%r11,%cr18	/* IIAOQ head */
+	ldo		4(%r11),%r11
+	mtctl		%r11,%cr18	/* IIAOQ tail */
+
+	load32		KERNEL_PSW,%r10
+	mtctl		%r10,%ipsw
+	
+	/* Jump through hyperspace to Virt Mode */
+	rfi
+	nop
+
+	.procend
+
+#ifdef CONFIG_SMP
+
+	.import smp_init_current_idle_task,data
+	.import	smp_callin,code
+
+#ifndef CONFIG_64BIT
+smp_callin_rtn:
+        .proc
+	.callinfo
+	break	1,1		/*  Break if returned from start_secondary */
+	nop
+	nop
+        .procend
+#endif /*!CONFIG_64BIT*/
+
+/***************************************************************************
+* smp_slave_stext is executed by all non-monarch Processors when the Monarch
+* pokes the slave CPUs in smp.c:smp_boot_cpus().
+*
+* Once here, registers values are initialized in order to branch to virtual
+* mode. Once all available/eligible CPUs are in virtual mode, all are
+* released and start out by executing their own idle task.
+*****************************************************************************/
+smp_slave_stext:
+        .proc
+	.callinfo
+
+	/*
+	** Initialize Space registers
+	*/
+	mtsp	   %r0,%sr4
+	mtsp	   %r0,%sr5
+	mtsp	   %r0,%sr6
+	mtsp	   %r0,%sr7
+
+	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
+	load32		PA(smp_init_current_idle_task),%sp
+	LDREG		0(%sp),%sp	/* load task address */
+	tophys_r1	%sp
+	LDREG		TASK_THREAD_INFO(%sp),%sp
+	mtctl           %sp,%cr30       /* store in cr30 */
+	ldo             THREAD_SZ_ALGN(%sp),%sp
+
+	/* point CPU to kernel page tables */
+	load32		PA(swapper_pg_dir),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+#ifdef CONFIG_64BIT
+	/* Setup PDCE_PROC entry */
+	copy            %arg0,%r3
+#else
+	/* Load RFI *return* address in case smp_callin bails */
+	load32		smp_callin_rtn,%r2
+#endif
+	
+	/* Load RFI target address.  */
+	load32		smp_callin,%r11
+	
+	/* ok...common code can handle the rest */
+	b		common_stext
+	nop
+
+	.procend
+#endif /* CONFIG_SMP */
+
+ENDPROC(parisc_kernel_start)
+
+#ifndef CONFIG_64BIT
+	.section .data..read_mostly
+
+	.align	4
+	.export	$global$,data
+
+	.type	$global$,@object
+	.size	$global$,4
+$global$:	
+	.word 0
+#endif /*!CONFIG_64BIT*/
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
new file mode 100644
index 0000000..fde6541
--- /dev/null
+++ b/arch/parisc/kernel/hpmc.S
@@ -0,0 +1,314 @@
+/* 
+ * HPMC (High Priority Machine Check) handler.
+ *
+ * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
+ * Copyright (C) 2000 Hewlett-Packard (John Marvin)
+ *
+ *    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, 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
+ */
+
+
+/*
+ * This HPMC handler retrieves the HPMC pim data, resets IO and
+ * returns to the default trap handler with code set to 1 (HPMC).
+ * The default trap handler calls handle interruption, which
+ * does a stack and register dump. This at least allows kernel
+ * developers to get back to C code in virtual mode, where they
+ * have the option to examine and print values from memory that
+ * would help in debugging an HPMC caused by a software bug.
+ *
+ * There is more to do here:
+ *
+ *      1) On MP systems we need to synchronize processors
+ *         before calling pdc/iodc.
+ *      2) We should be checking the system state and not
+ *         returning to the fault handler if things are really
+ *         bad.
+ *
+ */
+
+	.level		1.1
+
+#include <asm/assembly.h>
+#include <asm/pdc.h>
+#include <asm/psw.h>
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	/*
+	 * stack for os_hpmc, the HPMC handler.
+	 * buffer for IODC procedures (for the HPMC handler).
+	 *
+	 * IODC requires 7K byte stack.  That leaves 1K byte for os_hpmc.
+	 */
+
+	__PAGE_ALIGNED_BSS
+	.align 4096
+hpmc_stack:
+	.block 16384
+
+#define HPMC_IODC_BUF_SIZE 0x8000
+
+	__PAGE_ALIGNED_BSS
+	.align 4096
+hpmc_iodc_buf:
+	.block HPMC_IODC_BUF_SIZE
+
+	.section .bss
+	.align 8
+hpmc_raddr:
+	.block 128
+
+#define HPMC_PIM_DATA_SIZE 896 /* Enough to hold all architected 2.0 state */
+
+	.section .bss
+	.align 8
+ENTRY(hpmc_pim_data)
+	.block HPMC_PIM_DATA_SIZE
+END(hpmc_pim_data)
+
+	.text
+
+	.import intr_save, code
+	.align 16
+ENTRY(os_hpmc)
+.os_hpmc:
+
+	/*
+	 * registers modified:
+	 *
+	 *   Using callee saves registers without saving them.  The
+	 *   original values are in the pim dump if we need them.
+	 *
+	 *   r2   (rp)  return pointer
+	 *   r3   address of PDCE_PROC
+	 *   r4   scratch
+	 *   r5   scratch
+	 *   r23  (arg3) procedure arg
+	 *   r24  (arg2) procedure arg
+	 *   r25  (arg1) procedure arg
+	 *   r26  (arg0) procedure arg
+	 *   r30  (sp)   stack pointer
+	 *
+	 * registers read:
+	 *
+	 *   r26  contains address of PDCE_PROC on entry
+	 *   r28  (ret0) return value from procedure
+	 */
+
+	copy    arg0, %r3       /* save address of PDCE_PROC */
+
+	/*
+	 *  disable nested HPMCs
+	 *
+	 * Increment os_hpmc checksum to invalidate it.
+	 * Do this before turning the PSW M bit off.
+	 */
+
+	mfctl   %cr14, %r4
+	ldw     52(%r4),%r5
+	addi    1,%r5,%r5
+	stw     %r5,52(%r4)
+
+	/* MP_FIXME: synchronize all processors. */
+
+	/* Setup stack pointer. */
+
+	load32	PA(hpmc_stack),sp
+	
+	ldo     128(sp),sp /* leave room for arguments */
+
+	/*
+	 * Most PDC routines require that the M bit be off.
+	 * So turn on the Q bit and turn off the M bit.
+	 */
+
+	ldi     PSW_SM_Q,%r4                   /* PSW Q on, PSW M off */
+	mtctl   %r4,ipsw
+	mtctl   %r0,pcsq
+	mtctl   %r0,pcsq
+	load32	PA(os_hpmc_1),%r4
+	mtctl   %r4,pcoq
+	ldo     4(%r4),%r4
+	mtctl   %r4,pcoq
+	rfi
+	nop
+
+os_hpmc_1:
+
+	/* Call PDC_PIM to get HPMC pim info */
+
+	/*
+	 * Note that on some newer boxes, PDC_PIM must be called
+	 * before PDC_IO if you want IO to be reset. PDC_PIM sets
+	 * a flag that PDC_IO examines.
+	 */
+
+	ldo     PDC_PIM(%r0), arg0
+	ldo     PDC_PIM_HPMC(%r0),arg1          /* Transfer HPMC data */
+	load32	PA(hpmc_raddr),arg2
+	load32	PA(hpmc_pim_data),arg3
+	load32	HPMC_PIM_DATA_SIZE,%r4
+	stw     %r4,-52(sp)
+
+	ldil    L%PA(os_hpmc_2), rp
+	bv      (r3)                            /* call pdce_proc */
+	ldo     R%PA(os_hpmc_2)(rp), rp
+
+os_hpmc_2:
+	comib,<>  0,ret0, os_hpmc_fail
+
+	/* Reset IO by calling the hversion dependent PDC_IO routine */
+
+	ldo     PDC_IO(%r0),arg0
+	ldo     0(%r0),arg1                     /* log IO errors */
+	ldo     0(%r0),arg2                     /* reserved */
+	ldo     0(%r0),arg3                     /* reserved */
+	stw     %r0,-52(sp)                     /* reserved */
+
+	ldil    L%PA(os_hpmc_3),rp
+	bv      (%r3)                           /* call pdce_proc */
+	ldo     R%PA(os_hpmc_3)(rp),rp
+
+os_hpmc_3:
+
+	/* FIXME? Check for errors from PDC_IO (-1 might be OK) */
+
+	/*
+	 * Initialize the IODC console device (HPA,SPA, path etc.
+	 * are stored on page 0.
+	 */
+
+	/*
+	 * Load IODC into hpmc_iodc_buf by calling PDC_IODC.
+	 * Note that PDC_IODC handles flushing the appropriate
+	 * data and instruction cache lines.
+	 */
+
+	ldo     PDC_IODC(%r0),arg0
+	ldo     PDC_IODC_READ(%r0),arg1
+	load32	PA(hpmc_raddr),arg2
+	ldw     BOOT_CONSOLE_HPA_OFFSET(%r0),arg3 /* console hpa */
+	ldo     PDC_IODC_RI_INIT(%r0),%r4
+	stw     %r4,-52(sp)
+	load32	PA(hpmc_iodc_buf),%r4
+	stw     %r4,-56(sp)
+	load32	HPMC_IODC_BUF_SIZE,%r4
+	stw     %r4,-60(sp)
+
+	ldil    L%PA(os_hpmc_4),rp
+	bv      (%r3)                            /* call pdce_proc */
+	ldo     R%PA(os_hpmc_4)(rp),rp
+
+os_hpmc_4:
+	comib,<>  0,ret0,os_hpmc_fail
+
+	/* Call the entry init (just loaded by PDC_IODC) */
+
+	ldw     BOOT_CONSOLE_HPA_OFFSET(%r0),arg0  /* console hpa */
+	ldo     ENTRY_INIT_MOD_DEV(%r0), arg1
+	ldw     BOOT_CONSOLE_SPA_OFFSET(%r0),arg2  /* console spa */
+	depi    0,31,11,arg2                       /* clear bits 21-31    */
+	ldo     BOOT_CONSOLE_PATH_OFFSET(%r0),arg3 /* console path */
+	load32	PA(hpmc_raddr),%r4
+	stw     %r4, -52(sp)
+	stw     %r0, -56(sp)                    /* HV                  */
+	stw     %r0, -60(sp)                    /* HV                  */
+	stw     %r0, -64(sp)                    /* HV                  */
+	stw     %r0, -68(sp)                    /* lang, must be zero  */
+
+	load32	PA(hpmc_iodc_buf),%r5
+	ldil    L%PA(os_hpmc_5),rp
+	bv      (%r5)
+	ldo     R%PA(os_hpmc_5)(rp),rp
+
+os_hpmc_5:
+	comib,<>  0,ret0,os_hpmc_fail
+
+	/* Prepare to call intr_save */
+
+	/*
+	 * Load kernel page directory (load into user also, since
+	 * we don't intend to ever return to user land anyway)
+	 */
+
+	load32		PA(swapper_pg_dir),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+	/* Clear sr4-sr7 */
+
+	mtsp	%r0, %sr4
+	mtsp	%r0, %sr5
+	mtsp	%r0, %sr6
+	mtsp	%r0, %sr7
+
+	tovirt_r1 %r30      /* make sp virtual */
+
+	rsm     PSW_SM_Q,%r0           /* Clear Q bit */
+	ldi     1,%r8       /* Set trap code to "1" for HPMC */
+	load32	PA(intr_save),%r1
+	be      0(%sr7,%r1)
+	nop
+
+os_hpmc_fail:
+
+	/*
+	 * Reset the system
+	 *
+	 * Some systems may lockup from a broadcast reset, so try the
+	 * hversion PDC_BROADCAST_RESET() first.
+	 * MP_FIXME: reset all processors if more than one central bus.
+	 */
+
+	/* PDC_BROADCAST_RESET() */
+
+	ldo     PDC_BROADCAST_RESET(%r0),arg0
+	ldo     0(%r0),arg1                     /* do reset */
+
+	ldil    L%PA(os_hpmc_6),rp
+	bv      (%r3)                           /* call pdce_proc */
+	ldo     R%PA(os_hpmc_6)(rp),rp
+
+os_hpmc_6:
+
+	/*
+	 * possible return values:
+	 *  -1  non-existent procedure
+	 *  -2  non-existent option
+	 *  -16 unaligned stack
+	 *
+	 * If call returned, do a broadcast reset.
+	 */
+
+	ldil    L%0xfffc0000,%r4        /* IO_BROADCAST */
+	ldo     5(%r0),%r5
+	stw     %r5,48(%r4)             /*  CMD_RESET to IO_COMMAND offset */
+
+	b .
+	nop
+	.align 16	/* make function length multiple of 16 bytes */
+.os_hpmc_end:
+
+
+	__INITRODATA
+.globl os_hpmc_size
+	.align 4
+	.type   os_hpmc_size, @object
+	.size   os_hpmc_size, 4
+os_hpmc_size:
+	.word .os_hpmc_end-.os_hpmc
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
new file mode 100644
index 0000000..b0fe19a
--- /dev/null
+++ b/arch/parisc/kernel/inventory.c
@@ -0,0 +1,631 @@
+/*
+ * inventory.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1999 The Puffin Group (David Kennedy and Alex deVries)
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett-Packard
+ *
+ * These are the routines to discover what hardware exists in this box.
+ * This task is complicated by there being 3 different ways of
+ * performing an inventory, depending largely on the age of the box.
+ * The recommended way to do this is to check to see whether the machine
+ * is a `Snake' first, then try System Map, then try PAT.  We try System
+ * Map before checking for a Snake -- this probably doesn't cause any
+ * problems, but...
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mmzone.h>
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/parisc-device.h>
+
+/*
+** Debug options
+** DEBUG_PAT Dump details which PDC PAT provides about ranges/devices.
+*/
+#undef DEBUG_PAT
+
+int pdc_type __read_mostly = PDC_TYPE_ILLEGAL;
+
+/* cell number and location (PAT firmware only) */
+unsigned long parisc_cell_num __read_mostly;
+unsigned long parisc_cell_loc __read_mostly;
+
+
+void __init setup_pdc(void)
+{
+	long status;
+	unsigned int bus_id;
+	struct pdc_system_map_mod_info module_result;
+	struct pdc_module_path module_path;
+	struct pdc_model model;
+#ifdef CONFIG_64BIT
+	struct pdc_pat_cell_num cell_info;
+#endif
+
+	/* Determine the pdc "type" used on this machine */
+
+	printk(KERN_INFO "Determining PDC firmware type: ");
+
+	status = pdc_system_map_find_mods(&module_result, &module_path, 0);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_SYSTEM_MAP;
+		pr_cont("System Map.\n");
+		return;
+	}
+
+	/*
+	 * If the machine doesn't support PDC_SYSTEM_MAP then either it
+	 * is a pdc pat box, or it is an older box. All 64 bit capable
+	 * machines are either pdc pat boxes or they support PDC_SYSTEM_MAP.
+	 */
+
+	/*
+	 * TODO: We should test for 64 bit capability and give a
+	 * clearer message.
+	 */
+
+#ifdef CONFIG_64BIT
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_PAT;
+		pr_cont("64 bit PAT.\n");
+		parisc_cell_num = cell_info.cell_num;
+		parisc_cell_loc = cell_info.cell_loc;
+		pr_info("PAT: Running on cell %lu and location %lu.\n",
+			parisc_cell_num, parisc_cell_loc);
+		return;
+	}
+#endif
+
+	/* Check the CPU's bus ID.  There's probably a better test.  */
+
+	status = pdc_model_info(&model);
+
+	bus_id = (model.hversion >> (4 + 7)) & 0x1f;
+
+	switch (bus_id) {
+	case 0x4:		/* 720, 730, 750, 735, 755 */
+	case 0x6:		/* 705, 710 */
+	case 0x7:		/* 715, 725 */
+	case 0x8:		/* 745, 747, 742 */
+	case 0xA:		/* 712 and similar */
+	case 0xC:		/* 715/64, at least */
+
+		pdc_type = PDC_TYPE_SNAKE;
+		pr_cont("Snake.\n");
+		return;
+
+	default:		/* Everything else */
+
+		pr_cont("Unsupported.\n");
+		panic("If this is a 64-bit machine, please try a 64-bit kernel.\n");
+	}
+}
+
+#define PDC_PAGE_ADJ_SHIFT (PAGE_SHIFT - 12) /* pdc pages are always 4k */
+
+static void __init
+set_pmem_entry(physmem_range_t *pmem_ptr, unsigned long start,
+	       unsigned long pages4k)
+{
+	/* Rather than aligning and potentially throwing away
+	 * memory, we'll assume that any ranges are already
+	 * nicely aligned with any reasonable page size, and
+	 * panic if they are not (it's more likely that the
+	 * pdc info is bad in this case).
+	 */
+
+	if (unlikely( ((start & (PAGE_SIZE - 1)) != 0)
+	    || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) )) {
+
+		panic("Memory range doesn't align with page size!\n");
+	}
+
+	pmem_ptr->start_pfn = (start >> PAGE_SHIFT);
+	pmem_ptr->pages = (pages4k >> PDC_PAGE_ADJ_SHIFT);
+}
+
+static void __init pagezero_memconfig(void)
+{
+	unsigned long npages;
+
+	/* Use the 32 bit information from page zero to create a single
+	 * entry in the pmem_ranges[] table.
+	 *
+	 * We currently don't support machines with contiguous memory
+	 * >= 4 Gb, who report that memory using 64 bit only fields
+	 * on page zero. It's not worth doing until it can be tested,
+	 * and it is not clear we can support those machines for other
+	 * reasons.
+	 *
+	 * If that support is done in the future, this is where it
+	 * should be done.
+	 */
+
+	npages = (PAGE_ALIGN(PAGE0->imm_max_mem) >> PAGE_SHIFT);
+	set_pmem_entry(pmem_ranges,0UL,npages);
+	npmem_ranges = 1;
+}
+
+#ifdef CONFIG_64BIT
+
+/* All of the PDC PAT specific code is 64-bit only */
+
+/*
+**  The module object is filled via PDC_PAT_CELL[Return Cell Module].
+**  If a module is found, register module will get the IODC bytes via
+**  pdc_iodc_read() using the PA view of conf_base_addr for the hpa parameter.
+**
+**  The IO view can be used by PDC_PAT_CELL[Return Cell Module]
+**  only for SBAs and LBAs.  This view will cause an invalid
+**  argument error for all other cell module types.
+**
+*/
+
+static int __init 
+pat_query_module(ulong pcell_loc, ulong mod_index)
+{
+	pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell;
+	unsigned long bytecnt;
+	unsigned long temp;	/* 64-bit scratch value */
+	long status;		/* PDC return value status */
+	struct parisc_device *dev;
+
+	pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL);
+	if (!pa_pdc_cell)
+		panic("couldn't allocate memory for PDC_PAT_CELL!");
+
+	/* return cell module (PA or Processor view) */
+	status = pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				     PA_VIEW, pa_pdc_cell);
+
+	if (status != PDC_OK) {
+		/* no more cell modules or error */
+		kfree(pa_pdc_cell);
+		return status;
+	}
+
+	temp = pa_pdc_cell->cba;
+	dev = alloc_pa_dev(PAT_GET_CBA(temp), &(pa_pdc_cell->mod_path));
+	if (!dev) {
+		kfree(pa_pdc_cell);
+		return PDC_OK;
+	}
+
+	/* alloc_pa_dev sets dev->hpa */
+
+	/*
+	** save parameters in the parisc_device
+	** (The idea being the device driver will call pdc_pat_cell_module()
+	** and store the results in its own data structure.)
+	*/
+	dev->pcell_loc = pcell_loc;
+	dev->mod_index = mod_index;
+
+	/* save generic info returned from the call */
+	/* REVISIT: who is the consumer of this? not sure yet... */
+	dev->mod_info = pa_pdc_cell->mod_info;	/* pass to PAT_GET_ENTITY() */
+	dev->pmod_loc = pa_pdc_cell->mod_location;
+	dev->mod0 = pa_pdc_cell->mod[0];
+
+	register_parisc_device(dev);	/* advertise device */
+
+#ifdef DEBUG_PAT
+	/* dump what we see so far... */
+	switch (PAT_GET_ENTITY(dev->mod_info)) {
+		pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
+		unsigned long i;
+
+	case PAT_ENTITY_PROC:
+		printk(KERN_DEBUG "PAT_ENTITY_PROC: id_eid 0x%lx\n",
+			pa_pdc_cell->mod[0]);
+		break;
+
+	case PAT_ENTITY_MEM:
+		printk(KERN_DEBUG 
+			"PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
+			pa_pdc_cell->mod[0], pa_pdc_cell->mod[1],
+			pa_pdc_cell->mod[2]);
+		break;
+	case PAT_ENTITY_CA:
+		printk(KERN_DEBUG "PAT_ENTITY_CA: %ld\n", pcell_loc);
+		break;
+
+	case PAT_ENTITY_PBC:
+		printk(KERN_DEBUG "PAT_ENTITY_PBC: ");
+		goto print_ranges;
+
+	case PAT_ENTITY_SBA:
+		printk(KERN_DEBUG "PAT_ENTITY_SBA: ");
+		goto print_ranges;
+
+	case PAT_ENTITY_LBA:
+		printk(KERN_DEBUG "PAT_ENTITY_LBA: ");
+
+ print_ranges:
+		pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				    IO_VIEW, &io_pdc_cell);
+		printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell->mod[1]);
+		for (i = 0; i < pa_pdc_cell->mod[1]; i++) {
+			printk(KERN_DEBUG 
+				"  PA_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, pa_pdc_cell->mod[2 + i * 3],	/* type */
+				pa_pdc_cell->mod[3 + i * 3],	/* start */
+				pa_pdc_cell->mod[4 + i * 3]);	/* finish (ie end) */
+			printk(KERN_DEBUG 
+				"  IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, io_pdc_cell.mod[2 + i * 3],	/* type */
+				io_pdc_cell.mod[3 + i * 3],	/* start */
+				io_pdc_cell.mod[4 + i * 3]);	/* finish (ie end) */
+		}
+		printk(KERN_DEBUG "\n");
+		break;
+	}
+#endif /* DEBUG_PAT */
+
+	kfree(pa_pdc_cell);
+
+	return PDC_OK;
+}
+
+
+/* pat pdc can return information about a variety of different
+ * types of memory (e.g. firmware,i/o, etc) but we only care about
+ * the usable physical ram right now. Since the firmware specific
+ * information is allocated on the stack, we'll be generous, in
+ * case there is a lot of other information we don't care about.
+ */
+
+#define PAT_MAX_RANGES (4 * MAX_PHYSMEM_RANGES)
+
+static void __init pat_memconfig(void)
+{
+	unsigned long actual_len;
+	struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
+	struct pdc_pat_pd_addr_map_entry *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
+	long status;
+	int entries;
+	unsigned long length;
+	int i;
+
+	length = (PAT_MAX_RANGES + 1) * sizeof(struct pdc_pat_pd_addr_map_entry);
+
+	status = pdc_pat_pd_get_addr_map(&actual_len, mem_table, length, 0L);
+
+	if ((status != PDC_OK)
+	    || ((actual_len % sizeof(struct pdc_pat_pd_addr_map_entry)) != 0)) {
+
+		/* The above pdc call shouldn't fail, but, just in
+		 * case, just use the PAGE0 info.
+		 */
+
+		printk("\n\n\n");
+		printk(KERN_WARNING "WARNING! Could not get full memory configuration. "
+			"All memory may not be used!\n\n\n");
+		pagezero_memconfig();
+		return;
+	}
+
+	entries = actual_len / sizeof(struct pdc_pat_pd_addr_map_entry);
+
+	if (entries > PAT_MAX_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+	}
+
+	/* Copy information into the firmware independent pmem_ranges
+	 * array, skipping types we don't care about. Notice we said
+	 * "may" above. We'll use all the entries that were returned.
+	 */
+
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		if (   (mtbl_ptr->entry_type != PAT_MEMORY_DESCRIPTOR)
+		    || (mtbl_ptr->memory_type != PAT_MEMTYPE_MEMORY)
+		    || (mtbl_ptr->pages == 0)
+		    || (   (mtbl_ptr->memory_usage != PAT_MEMUSE_GENERAL)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GI)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GNI) ) ) {
+
+			continue;
+		}
+
+		if (npmem_ranges == MAX_PHYSMEM_RANGES) {
+			printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+			printk(KERN_WARNING "Some memory will not be used!\n");
+			break;
+		}
+
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
+}
+
+static int __init pat_inventory(void)
+{
+	int status;
+	ulong mod_index = 0;
+	struct pdc_pat_cell_num cell_info;
+
+	/*
+	** Note:  Prelude (and it's successors: Lclass, A400/500) only
+	**        implement PDC_PAT_CELL sub-options 0 and 2.
+	*/
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status != PDC_OK) {
+		return 0;
+	}
+
+#ifdef DEBUG_PAT
+	printk(KERN_DEBUG "CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_info.cell_num, 
+	       cell_info.cell_loc);
+#endif
+
+	while (PDC_OK == pat_query_module(cell_info.cell_loc, mod_index)) {
+		mod_index++;
+	}
+
+	return mod_index;
+}
+
+/* We only look for extended memory ranges on a 64 bit capable box */
+static void __init sprockets_memconfig(void)
+{
+	struct pdc_memory_table_raddr r_addr;
+	struct pdc_memory_table mem_table[MAX_PHYSMEM_RANGES];
+	struct pdc_memory_table *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
+	long status;
+	int entries;
+	int i;
+
+	status = pdc_mem_mem_table(&r_addr,mem_table,
+				(unsigned long)MAX_PHYSMEM_RANGES);
+
+	if (status != PDC_OK) {
+
+		/* The above pdc call only works on boxes with sprockets
+		 * firmware (newer B,C,J class). Other non PAT PDC machines
+		 * do support more than 3.75 Gb of memory, but we don't
+		 * support them yet.
+		 */
+
+		pagezero_memconfig();
+		return;
+	}
+
+	if (r_addr.entries_total > MAX_PHYSMEM_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory will not be used!\n");
+	}
+
+	entries = (int)r_addr.entries_returned;
+
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
+}
+
+#else   /* !CONFIG_64BIT */
+
+#define pat_inventory() do { } while (0)
+#define pat_memconfig() do { } while (0)
+#define sprockets_memconfig() pagezero_memconfig()
+
+#endif	/* !CONFIG_64BIT */
+
+
+#ifndef CONFIG_PA20
+
+/* Code to support Snake machines (7[2350], 7[235]5, 715/Scorpio) */
+
+static struct parisc_device * __init
+legacy_create_device(struct pdc_memory_map *r_addr,
+		struct pdc_module_path *module_path)
+{
+	struct parisc_device *dev;
+	int status = pdc_mem_map_hpa(r_addr, module_path);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = alloc_pa_dev(r_addr->hpa, &module_path->path);
+	if (dev == NULL)
+		return NULL;
+
+	register_parisc_device(dev);
+	return dev;
+}
+
+/**
+ * snake_inventory
+ *
+ * Before PDC_SYSTEM_MAP was invented, the PDC_MEM_MAP call was used.
+ * To use it, we initialise the mod_path.bc to 0xff and try all values of
+ * mod to get the HPA for the top-level devices.  Bus adapters may have
+ * sub-devices which are discovered by setting bc[5] to 0 and bc[4] to the
+ * module, then trying all possible functions.
+ */
+static void __init snake_inventory(void)
+{
+	int mod;
+	for (mod = 0; mod < 16; mod++) {
+		struct parisc_device *dev;
+		struct pdc_module_path module_path;
+		struct pdc_memory_map r_addr;
+		unsigned int func;
+
+		memset(module_path.path.bc, 0xff, 6);
+		module_path.path.mod = mod;
+		dev = legacy_create_device(&r_addr, &module_path);
+		if ((!dev) || (dev->id.hw_type != HPHW_BA))
+			continue;
+
+		memset(module_path.path.bc, 0xff, 4);
+		module_path.path.bc[4] = mod;
+
+		for (func = 0; func < 16; func++) {
+			module_path.path.bc[5] = 0;
+			module_path.path.mod = func;
+			legacy_create_device(&r_addr, &module_path);
+		}
+	}
+}
+
+#else /* CONFIG_PA20 */
+#define snake_inventory() do { } while (0)
+#endif  /* CONFIG_PA20 */
+
+/* Common 32/64 bit based code goes here */
+
+/**
+ * add_system_map_addresses - Add additional addresses to the parisc device.
+ * @dev: The parisc device.
+ * @num_addrs: Then number of addresses to add;
+ * @module_instance: The system_map module instance.
+ *
+ * This function adds any additional addresses reported by the system_map
+ * firmware to the parisc device.
+ */
+static void __init
+add_system_map_addresses(struct parisc_device *dev, int num_addrs, 
+			 int module_instance)
+{
+	int i;
+	long status;
+	struct pdc_system_map_addr_info addr_result;
+
+	dev->addr = kmalloc_array(num_addrs, sizeof(*dev->addr), GFP_KERNEL);
+	if(!dev->addr) {
+		printk(KERN_ERR "%s %s(): memory allocation failure\n",
+		       __FILE__, __func__);
+		return;
+	}
+
+	for(i = 1; i <= num_addrs; ++i) {
+		status = pdc_system_map_find_addrs(&addr_result, 
+						   module_instance, i);
+		if(PDC_OK == status) {
+			dev->addr[dev->num_addrs] = (unsigned long)addr_result.mod_addr;
+			dev->num_addrs++;
+		} else {
+			printk(KERN_WARNING 
+			       "Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
+			       status, i);
+		}
+	}
+}
+
+/**
+ * system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ *
+ * This function attempts to retrieve and register all the devices firmware
+ * knows about via the SYSTEM_MAP PDC call.
+ */
+static void __init system_map_inventory(void)
+{
+	int i;
+	long status = PDC_OK;
+    
+	for (i = 0; i < 256; i++) {
+		struct parisc_device *dev;
+		struct pdc_system_map_mod_info module_result;
+		struct pdc_module_path module_path;
+
+		status = pdc_system_map_find_mods(&module_result,
+				&module_path, i);
+		if ((status == PDC_BAD_PROC) || (status == PDC_NE_MOD))
+			break;
+		if (status != PDC_OK)
+			continue;
+
+		dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
+		if (!dev)
+			continue;
+		
+		register_parisc_device(dev);
+
+		/* if available, get the additional addresses for a module */
+		if (!module_result.add_addrs)
+			continue;
+
+		add_system_map_addresses(dev, module_result.add_addrs, i);
+	}
+
+	walk_central_bus();
+	return;
+}
+
+void __init do_memory_inventory(void)
+{
+	switch (pdc_type) {
+
+	case PDC_TYPE_PAT:
+		pat_memconfig();
+		break;
+
+	case PDC_TYPE_SYSTEM_MAP:
+		sprockets_memconfig();
+		break;
+
+	case PDC_TYPE_SNAKE:
+		pagezero_memconfig();
+		return;
+
+	default:
+		panic("Unknown PDC type!\n");
+	}
+
+	if (npmem_ranges == 0 || pmem_ranges[0].start_pfn != 0) {
+		printk(KERN_WARNING "Bad memory configuration returned!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+		pagezero_memconfig();
+	}
+}
+
+void __init do_device_inventory(void)
+{
+	printk(KERN_INFO "Searching for devices...\n");
+
+	init_parisc_bus();
+
+	switch (pdc_type) {
+
+	case PDC_TYPE_PAT:
+		pat_inventory();
+		break;
+
+	case PDC_TYPE_SYSTEM_MAP:
+		system_map_inventory();
+		break;
+
+	case PDC_TYPE_SNAKE:
+		snake_inventory();
+		break;
+
+	default:
+		panic("Unknown PDC type!\n");
+	}
+	printk(KERN_INFO "Found devices:\n");
+	print_parisc_devices();
+}
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
new file mode 100644
index 0000000..0ca2540
--- /dev/null
+++ b/arch/parisc/kernel/irq.c
@@ -0,0 +1,611 @@
+/* 
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
+ * Copyright (C) 1999-2000 Grant Grundler
+ * Copyright (c) 2005 Matthew Wilcox
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#include <asm/smp.h>
+#include <asm/ldcw.h>
+
+#undef PARISC_IRQ_CR16_COUNTS
+
+extern irqreturn_t timer_interrupt(int, void *);
+extern irqreturn_t ipi_interrupt(int, void *);
+
+#define EIEM_MASK(irq)       (1UL<<(CPU_IRQ_MAX - irq))
+
+/* Bits in EIEM correlate with cpu_irq_action[].
+** Numbered *Big Endian*! (ie bit 0 is MSB)
+*/
+static volatile unsigned long cpu_eiem = 0;
+
+/*
+** local ACK bitmap ... habitually set to 1, but reset to zero
+** between ->ack() and ->end() of the interrupt to prevent
+** re-interruption of a processing interrupt.
+*/
+static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
+
+static void cpu_mask_irq(struct irq_data *d)
+{
+	unsigned long eirr_bit = EIEM_MASK(d->irq);
+
+	cpu_eiem &= ~eirr_bit;
+	/* Do nothing on the other CPUs.  If they get this interrupt,
+	 * The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
+	 * handle it, and the set_eiem() at the bottom will ensure it
+	 * then gets disabled */
+}
+
+static void __cpu_unmask_irq(unsigned int irq)
+{
+	unsigned long eirr_bit = EIEM_MASK(irq);
+
+	cpu_eiem |= eirr_bit;
+
+	/* This is just a simple NOP IPI.  But what it does is cause
+	 * all the other CPUs to do a set_eiem(cpu_eiem) at the end
+	 * of the interrupt handler */
+	smp_send_all_nop();
+}
+
+static void cpu_unmask_irq(struct irq_data *d)
+{
+	__cpu_unmask_irq(d->irq);
+}
+
+void cpu_ack_irq(struct irq_data *d)
+{
+	unsigned long mask = EIEM_MASK(d->irq);
+	int cpu = smp_processor_id();
+
+	/* Clear in EIEM so we can no longer process */
+	per_cpu(local_ack_eiem, cpu) &= ~mask;
+
+	/* disable the interrupt */
+	set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
+
+	/* and now ack it */
+	mtctl(mask, 23);
+}
+
+void cpu_eoi_irq(struct irq_data *d)
+{
+	unsigned long mask = EIEM_MASK(d->irq);
+	int cpu = smp_processor_id();
+
+	/* set it in the eiems---it's no longer in process */
+	per_cpu(local_ack_eiem, cpu) |= mask;
+
+	/* enable the interrupt */
+	set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
+}
+
+#ifdef CONFIG_SMP
+int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest)
+{
+	int cpu_dest;
+
+	/* timer and ipi have to always be received on all CPUs */
+	if (irqd_is_per_cpu(d))
+		return -EINVAL;
+
+	/* whatever mask they set, we just allow one CPU */
+	cpu_dest = cpumask_first_and(dest, cpu_online_mask);
+
+	return cpu_dest;
+}
+
+static int cpu_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
+				bool force)
+{
+	int cpu_dest;
+
+	cpu_dest = cpu_check_affinity(d, dest);
+	if (cpu_dest < 0)
+		return -1;
+
+	cpumask_copy(irq_data_get_affinity_mask(d), dest);
+
+	return 0;
+}
+#endif
+
+static struct irq_chip cpu_interrupt_type = {
+	.name			= "CPU",
+	.irq_mask		= cpu_mask_irq,
+	.irq_unmask		= cpu_unmask_irq,
+	.irq_ack		= cpu_ack_irq,
+	.irq_eoi		= cpu_eoi_irq,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= cpu_set_affinity_irq,
+#endif
+	/* XXX: Needs to be written.  We managed without it so far, but
+	 * we really ought to write it.
+	 */
+	.irq_retrigger	= NULL,
+};
+
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+#define irq_stats(x)		(&per_cpu(irq_stat, x))
+
+/*
+ * /proc/interrupts printing for arch specific interrupts
+ */
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+	int j;
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	seq_printf(p, "%*s: ", prec, "STK");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage);
+	seq_puts(p, "  Kernel stack usage\n");
+# ifdef CONFIG_IRQSTACKS
+	seq_printf(p, "%*s: ", prec, "IST");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
+	seq_puts(p, "  Interrupt stack usage\n");
+# endif
+#endif
+#ifdef CONFIG_SMP
+	seq_printf(p, "%*s: ", prec, "RES");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
+	seq_puts(p, "  Rescheduling interrupts\n");
+#endif
+	seq_printf(p, "%*s: ", prec, "UAH");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
+	seq_puts(p, "  Unaligned access handler traps\n");
+	seq_printf(p, "%*s: ", prec, "FPA");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
+	seq_puts(p, "  Floating point assist traps\n");
+	seq_printf(p, "%*s: ", prec, "TLB");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
+	seq_puts(p, "  TLB shootdowns\n");
+	return 0;
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v, j;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_puts(p, "    ");
+		for_each_online_cpu(j)
+			seq_printf(p, "       CPU%d", j);
+
+#ifdef PARISC_IRQ_CR16_COUNTS
+		seq_printf(p, " [min/avg/max] (CPU cycle counts)");
+#endif
+		seq_putc(p, '\n');
+	}
+
+	if (i < NR_IRQS) {
+		struct irq_desc *desc = irq_to_desc(i);
+		struct irqaction *action;
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+		action = desc->action;
+		if (!action)
+			goto skip;
+		seq_printf(p, "%3d: ", i);
+#ifdef CONFIG_SMP
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+#else
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#endif
+
+		seq_printf(p, " %14s", irq_desc_get_chip(desc)->name);
+#ifndef PARISC_IRQ_CR16_COUNTS
+		seq_printf(p, "  %s", action->name);
+
+		while ((action = action->next))
+			seq_printf(p, ", %s", action->name);
+#else
+		for ( ;action; action = action->next) {
+			unsigned int k, avg, min, max;
+
+			min = max = action->cr16_hist[0];
+
+			for (avg = k = 0; k < PARISC_CR16_HIST_SIZE; k++) {
+				int hist = action->cr16_hist[k];
+
+				if (hist) {
+					avg += hist;
+				} else
+					break;
+
+				if (hist > max) max = hist;
+				if (hist < min) min = hist;
+			}
+
+			avg /= k;
+			seq_printf(p, " %s[%d/%d/%d]", action->name,
+					min,avg,max);
+		}
+#endif
+
+		seq_putc(p, '\n');
+ skip:
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+	}
+
+	if (i == NR_IRQS)
+		arch_show_interrupts(p, 3);
+
+	return 0;
+}
+
+
+
+/*
+** The following form a "set": Virtual IRQ, Transaction Address, Trans Data.
+** Respectively, these map to IRQ region+EIRR, Processor HPA, EIRR bit.
+**
+** To use txn_XXX() interfaces, get a Virtual IRQ first.
+** Then use that to get the Transaction address and data.
+*/
+
+int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
+{
+	if (irq_has_action(irq))
+		return -EBUSY;
+	if (irq_get_chip(irq) != &cpu_interrupt_type)
+		return -EBUSY;
+
+	/* for iosapic interrupts */
+	if (type) {
+		irq_set_chip_and_handler(irq, type, handle_percpu_irq);
+		irq_set_chip_data(irq, data);
+		__cpu_unmask_irq(irq);
+	}
+	return 0;
+}
+
+int txn_claim_irq(int irq)
+{
+	return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq;
+}
+
+/*
+ * The bits_wide parameter accommodates the limitations of the HW/SW which
+ * use these bits:
+ * Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register)
+ * V-class (EPIC):          6 bits
+ * N/L/A-class (iosapic):   8 bits
+ * PCI 2.2 MSI:            16 bits
+ * Some PCI devices:       32 bits (Symbios SCSI/ATM/HyperFabric)
+ *
+ * On the service provider side:
+ * o PA 1.1 (and PA2.0 narrow mode)     5-bits (width of EIR register)
+ * o PA 2.0 wide mode                   6-bits (per processor)
+ * o IA64                               8-bits (0-256 total)
+ *
+ * So a Legacy PA I/O device on a PA 2.0 box can't use all the bits supported
+ * by the processor...and the N/L-class I/O subsystem supports more bits than
+ * PA2.0 has. The first case is the problem.
+ */
+int txn_alloc_irq(unsigned int bits_wide)
+{
+	int irq;
+
+	/* never return irq 0 cause that's the interval timer */
+	for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) {
+		if (cpu_claim_irq(irq, NULL, NULL) < 0)
+			continue;
+		if ((irq - CPU_IRQ_BASE) >= (1 << bits_wide))
+			continue;
+		return irq;
+	}
+
+	/* unlikely, but be prepared */
+	return -1;
+}
+
+
+unsigned long txn_affinity_addr(unsigned int irq, int cpu)
+{
+#ifdef CONFIG_SMP
+	struct irq_data *d = irq_get_irq_data(irq);
+	cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(cpu));
+#endif
+
+	return per_cpu(cpu_data, cpu).txn_addr;
+}
+
+
+unsigned long txn_alloc_addr(unsigned int virt_irq)
+{
+	static int next_cpu = -1;
+
+	next_cpu++; /* assign to "next" CPU we want this bugger on */
+
+	/* validate entry */
+	while ((next_cpu < nr_cpu_ids) &&
+		(!per_cpu(cpu_data, next_cpu).txn_addr ||
+		 !cpu_online(next_cpu)))
+		next_cpu++;
+
+	if (next_cpu >= nr_cpu_ids) 
+		next_cpu = 0;	/* nothing else, assign monarch */
+
+	return txn_affinity_addr(virt_irq, next_cpu);
+}
+
+
+unsigned int txn_alloc_data(unsigned int virt_irq)
+{
+	return virt_irq - CPU_IRQ_BASE;
+}
+
+static inline int eirr_to_irq(unsigned long eirr)
+{
+	int bit = fls_long(eirr);
+	return (BITS_PER_LONG - bit) + TIMER_IRQ;
+}
+
+#ifdef CONFIG_IRQSTACKS
+/*
+ * IRQ STACK - used for irq handler
+ */
+#define IRQ_STACK_SIZE      (4096 << 3) /* 32k irq stack size */
+
+union irq_stack_union {
+	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+	volatile unsigned int slock[4];
+	volatile unsigned int lock[1];
+};
+
+DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
+		.slock = { 1,1,1,1 },
+	};
+#endif
+
+
+int sysctl_panic_on_stackoverflow = 1;
+
+static inline void stack_overflow_check(struct pt_regs *regs)
+{
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	#define STACK_MARGIN	(256*6)
+
+	/* Our stack starts directly behind the thread_info struct. */
+	unsigned long stack_start = (unsigned long) current_thread_info();
+	unsigned long sp = regs->gr[30];
+	unsigned long stack_usage;
+	unsigned int *last_usage;
+	int cpu = smp_processor_id();
+
+	/* if sr7 != 0, we interrupted a userspace process which we do not want
+	 * to check for stack overflow. We will only check the kernel stack. */
+	if (regs->sr[7])
+		return;
+
+	/* exit if already in panic */
+	if (sysctl_panic_on_stackoverflow < 0)
+		return;
+
+	/* calculate kernel stack usage */
+	stack_usage = sp - stack_start;
+#ifdef CONFIG_IRQSTACKS
+	if (likely(stack_usage <= THREAD_SIZE))
+		goto check_kernel_stack; /* found kernel stack */
+
+	/* check irq stack usage */
+	stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack;
+	stack_usage = sp - stack_start;
+
+	last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu);
+	if (unlikely(stack_usage > *last_usage))
+		*last_usage = stack_usage;
+
+	if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN)))
+		return;
+
+	pr_emerg("stackcheck: %s will most likely overflow irq stack "
+		 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
+		current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE);
+	goto panic_check;
+
+check_kernel_stack:
+#endif
+
+	/* check kernel stack usage */
+	last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu);
+
+	if (unlikely(stack_usage > *last_usage))
+		*last_usage = stack_usage;
+
+	if (likely(stack_usage < (THREAD_SIZE - STACK_MARGIN)))
+		return;
+
+	pr_emerg("stackcheck: %s will most likely overflow kernel stack "
+		 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
+		current->comm, sp, stack_start, stack_start + THREAD_SIZE);
+
+#ifdef CONFIG_IRQSTACKS
+panic_check:
+#endif
+	if (sysctl_panic_on_stackoverflow) {
+		sysctl_panic_on_stackoverflow = -1; /* disable further checks */
+		panic("low stack detected by irq handler - check messages\n");
+	}
+#endif
+}
+
+#ifdef CONFIG_IRQSTACKS
+/* in entry.S: */
+void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
+
+static void execute_on_irq_stack(void *func, unsigned long param1)
+{
+	union irq_stack_union *union_ptr;
+	unsigned long irq_stack;
+	volatile unsigned int *irq_stack_in_use;
+
+	union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
+	irq_stack = (unsigned long) &union_ptr->stack;
+	irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
+			 64); /* align for stack frame usage */
+
+	/* We may be called recursive. If we are already using the irq stack,
+	 * just continue to use it. Use spinlocks to serialize
+	 * the irq stack usage.
+	 */
+	irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr);
+	if (!__ldcw(irq_stack_in_use)) {
+		void (*direct_call)(unsigned long p1) = func;
+
+		/* We are using the IRQ stack already.
+		 * Do direct call on current stack. */
+		direct_call(param1);
+		return;
+	}
+
+	/* This is where we switch to the IRQ stack. */
+	call_on_stack(param1, func, irq_stack);
+
+	/* free up irq stack usage. */
+	*irq_stack_in_use = 1;
+}
+
+void do_softirq_own_stack(void)
+{
+	execute_on_irq_stack(__do_softirq, 0);
+}
+#endif /* CONFIG_IRQSTACKS */
+
+/* ONLY called from entry.S:intr_extint() */
+void do_cpu_irq_mask(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs;
+	unsigned long eirr_val;
+	int irq, cpu = smp_processor_id();
+	struct irq_data *irq_data;
+#ifdef CONFIG_SMP
+	cpumask_t dest;
+#endif
+
+	old_regs = set_irq_regs(regs);
+	local_irq_disable();
+	irq_enter();
+
+	eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
+	if (!eirr_val)
+		goto set_out;
+	irq = eirr_to_irq(eirr_val);
+
+	irq_data = irq_get_irq_data(irq);
+
+	/* Filter out spurious interrupts, mostly from serial port at bootup */
+	if (unlikely(!irq_desc_has_action(irq_data_to_desc(irq_data))))
+		goto set_out;
+
+#ifdef CONFIG_SMP
+	cpumask_copy(&dest, irq_data_get_affinity_mask(irq_data));
+	if (irqd_is_per_cpu(irq_data) &&
+	    !cpumask_test_cpu(smp_processor_id(), &dest)) {
+		int cpu = cpumask_first(&dest);
+
+		printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+		       irq, smp_processor_id(), cpu);
+		gsc_writel(irq + CPU_IRQ_BASE,
+			   per_cpu(cpu_data, cpu).hpa);
+		goto set_out;
+	}
+#endif
+	stack_overflow_check(regs);
+
+#ifdef CONFIG_IRQSTACKS
+	execute_on_irq_stack(&generic_handle_irq, irq);
+#else
+	generic_handle_irq(irq);
+#endif /* CONFIG_IRQSTACKS */
+
+ out:
+	irq_exit();
+	set_irq_regs(old_regs);
+	return;
+
+ set_out:
+	set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
+	goto out;
+}
+
+static struct irqaction timer_action = {
+	.handler = timer_interrupt,
+	.name = "timer",
+	.flags = IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL,
+};
+
+#ifdef CONFIG_SMP
+static struct irqaction ipi_action = {
+	.handler = ipi_interrupt,
+	.name = "IPI",
+	.flags = IRQF_PERCPU,
+};
+#endif
+
+static void claim_cpu_irqs(void)
+{
+	int i;
+	for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
+		irq_set_chip_and_handler(i, &cpu_interrupt_type,
+					 handle_percpu_irq);
+	}
+
+	irq_set_handler(TIMER_IRQ, handle_percpu_irq);
+	setup_irq(TIMER_IRQ, &timer_action);
+#ifdef CONFIG_SMP
+	irq_set_handler(IPI_IRQ, handle_percpu_irq);
+	setup_irq(IPI_IRQ, &ipi_action);
+#endif
+}
+
+void __init init_IRQ(void)
+{
+	local_irq_disable();	/* PARANOID - should already be disabled */
+	mtctl(~0UL, 23);	/* EIRR : clear all pending external intr */
+#ifdef CONFIG_SMP
+	if (!cpu_eiem) {
+		claim_cpu_irqs();
+		cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
+	}
+#else
+	claim_cpu_irqs();
+	cpu_eiem = EIEM_MASK(TIMER_IRQ);
+#endif
+        set_eiem(cpu_eiem);	/* EIEM : enable all external intr */
+}
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
new file mode 100644
index 0000000..b5b3cb0
--- /dev/null
+++ b/arch/parisc/kernel/module.c
@@ -0,0 +1,972 @@
+/*    Kernel dynamically loadable module help for PARISC.
+ *
+ *    The best reference for this stuff is probably the Processor-
+ *    Specific ELF Supplement for PA-RISC:
+ *        http://ftp.parisc-linux.org/docs/arch/elf-pa-hp.pdf
+ *
+ *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
+ *    Copyright (C) 2003 Randolph Chung <tausq at debian . org>
+ *    Copyright (C) 2008 Helge Deller <deller@gmx.de>
+ *
+ *
+ *    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
+ *
+ *
+ *    Notes:
+ *    - PLT stub handling
+ *      On 32bit (and sometimes 64bit) and with big kernel modules like xfs or
+ *      ipv6 the relocation types R_PARISC_PCREL17F and R_PARISC_PCREL22F may
+ *      fail to reach their PLT stub if we only create one big stub array for
+ *      all sections at the beginning of the core or init section.
+ *      Instead we now insert individual PLT stub entries directly in front of
+ *      of the code sections where the stubs are actually called.
+ *      This reduces the distance between the PCREL location and the stub entry
+ *      so that the relocations can be fulfilled.
+ *      While calculating the final layout of the kernel module in memory, the
+ *      kernel module loader calls arch_mod_section_prepend() to request the
+ *      to be reserved amount of memory in front of each individual section.
+ *
+ *    - SEGREL32 handling
+ *      We are not doing SEGREL32 handling correctly. According to the ABI, we
+ *      should do a value offset, like this:
+ *			if (in_init(me, (void *)val))
+ *				val -= (uint32_t)me->init_layout.base;
+ *			else
+ *				val -= (uint32_t)me->core_layout.base;
+ *	However, SEGREL32 is used only for PARISC unwind entries, and we want
+ *	those entries to have an absolute address, and not just an offset.
+ *
+ *	The unwind table mechanism has the ability to specify an offset for 
+ *	the unwind table; however, because we split off the init functions into
+ *	a different piece of memory, it is not possible to do this using a 
+ *	single offset. Instead, we use the above hack for now.
+ */
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/pgtable.h>
+#include <asm/unwind.h>
+#include <asm/sections.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+#define RELOC_REACHABLE(val, bits) \
+	(( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 )  ||	\
+	     ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) ? \
+	0 : 1)
+
+#define CHECK_RELOC(val, bits) \
+	if (!RELOC_REACHABLE(val, bits)) { \
+		printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \
+		me->name, strtab + sym->st_name, (unsigned long)val, bits); \
+		return -ENOEXEC;			\
+	}
+
+/* Maximum number of GOT entries. We use a long displacement ldd from
+ * the bottom of the table, which has a maximum signed displacement of
+ * 0x3fff; however, since we're only going forward, this becomes
+ * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
+ * at most 1023 entries.
+ * To overcome this 14bit displacement with some kernel modules, we'll
+ * use instead the unusal 16bit displacement method (see reassemble_16a)
+ * which gives us a maximum positive displacement of 0x7fff, and as such
+ * allows us to allocate up to 4095 GOT entries. */
+#define MAX_GOTS	4095
+
+/* three functions to determine where in the module core
+ * or init pieces the location is */
+static inline int in_init(struct module *me, void *loc)
+{
+	return (loc >= me->init_layout.base &&
+		loc <= (me->init_layout.base + me->init_layout.size));
+}
+
+static inline int in_core(struct module *me, void *loc)
+{
+	return (loc >= me->core_layout.base &&
+		loc <= (me->core_layout.base + me->core_layout.size));
+}
+
+static inline int in_local(struct module *me, void *loc)
+{
+	return in_init(me, loc) || in_core(me, loc);
+}
+
+#ifndef CONFIG_64BIT
+struct got_entry {
+	Elf32_Addr addr;
+};
+
+struct stub_entry {
+	Elf32_Word insns[2]; /* each stub entry has two insns */
+};
+#else
+struct got_entry {
+	Elf64_Addr addr;
+};
+
+struct stub_entry {
+	Elf64_Word insns[4]; /* each stub entry has four insns */
+};
+#endif
+
+/* Field selection types defined by hppa */
+#define rnd(x)			(((x)+0x1000)&~0x1fff)
+/* fsel: full 32 bits */
+#define fsel(v,a)		((v)+(a))
+/* lsel: select left 21 bits */
+#define lsel(v,a)		(((v)+(a))>>11)
+/* rsel: select right 11 bits */
+#define rsel(v,a)		(((v)+(a))&0x7ff)
+/* lrsel with rounding of addend to nearest 8k */
+#define lrsel(v,a)		(((v)+rnd(a))>>11)
+/* rrsel with rounding of addend to nearest 8k */
+#define rrsel(v,a)		((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
+
+#define mask(x,sz)		((x) & ~((1<<(sz))-1))
+
+
+/* The reassemble_* functions prepare an immediate value for
+   insertion into an opcode. pa-risc uses all sorts of weird bitfields
+   in the instruction to hold the value.  */
+static inline int sign_unext(int x, int len)
+{
+	int len_ones;
+
+	len_ones = (1 << len) - 1;
+	return x & len_ones;
+}
+
+static inline int low_sign_unext(int x, int len)
+{
+	int sign, temp;
+
+	sign = (x >> (len-1)) & 1;
+	temp = sign_unext(x, len-1);
+	return (temp << 1) | sign;
+}
+
+static inline int reassemble_14(int as14)
+{
+	return (((as14 & 0x1fff) << 1) |
+		((as14 & 0x2000) >> 13));
+}
+
+static inline int reassemble_16a(int as16)
+{
+	int s, t;
+
+	/* Unusual 16-bit encoding, for wide mode only.  */
+	t = (as16 << 1) & 0xffff;
+	s = (as16 & 0x8000);
+	return (t ^ s ^ (s >> 1)) | (s >> 15);
+}
+
+
+static inline int reassemble_17(int as17)
+{
+	return (((as17 & 0x10000) >> 16) |
+		((as17 & 0x0f800) << 5) |
+		((as17 & 0x00400) >> 8) |
+		((as17 & 0x003ff) << 3));
+}
+
+static inline int reassemble_21(int as21)
+{
+	return (((as21 & 0x100000) >> 20) |
+		((as21 & 0x0ffe00) >> 8) |
+		((as21 & 0x000180) << 7) |
+		((as21 & 0x00007c) << 14) |
+		((as21 & 0x000003) << 12));
+}
+
+static inline int reassemble_22(int as22)
+{
+	return (((as22 & 0x200000) >> 21) |
+		((as22 & 0x1f0000) << 5) |
+		((as22 & 0x00f800) << 5) |
+		((as22 & 0x000400) >> 8) |
+		((as22 & 0x0003ff) << 3));
+}
+
+void *module_alloc(unsigned long size)
+{
+	/* using RWX means less protection for modules, but it's
+	 * easier than trying to map the text, data, init_text and
+	 * init_data correctly */
+	return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
+				    GFP_KERNEL,
+				    PAGE_KERNEL_RWX, 0, NUMA_NO_NODE,
+				    __builtin_return_address(0));
+}
+
+#ifndef CONFIG_64BIT
+static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
+{
+	return 0;
+}
+
+static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
+{
+	return 0;
+}
+
+static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF32_R_TYPE(rela->r_info)) {
+			case R_PARISC_PCREL17F:
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+#else
+static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_LTOFF21L:
+			case R_PARISC_LTOFF14R:
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+
+static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_FPTR64:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+
+static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+#endif
+
+void module_arch_freeing_init(struct module *mod)
+{
+	kfree(mod->arch.section);
+	mod->arch.section = NULL;
+}
+
+/* Additional bytes needed in front of individual sections */
+unsigned int arch_mod_section_prepend(struct module *mod,
+				      unsigned int section)
+{
+	/* size needed for all stubs of this section (including
+	 * one additional for correct alignment of the stubs) */
+	return (mod->arch.section[section].stub_entries + 1)
+		* sizeof(struct stub_entry);
+}
+
+#define CONST 
+int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
+			      CONST Elf_Shdr *sechdrs,
+			      CONST char *secstrings,
+			      struct module *me)
+{
+	unsigned long gots = 0, fdescs = 0, len;
+	unsigned int i;
+
+	len = hdr->e_shnum * sizeof(me->arch.section[0]);
+	me->arch.section = kzalloc(len, GFP_KERNEL);
+	if (!me->arch.section)
+		return -ENOMEM;
+
+	for (i = 1; i < hdr->e_shnum; i++) {
+		const Elf_Rela *rels = (void *)sechdrs[i].sh_addr;
+		unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
+		unsigned int count, s;
+
+		if (strncmp(secstrings + sechdrs[i].sh_name,
+			    ".PARISC.unwind", 14) == 0)
+			me->arch.unwind_section = i;
+
+		if (sechdrs[i].sh_type != SHT_RELA)
+			continue;
+
+		/* some of these are not relevant for 32-bit/64-bit
+		 * we leave them here to make the code common. the
+		 * compiler will do its thing and optimize out the
+		 * stuff we don't need
+		 */
+		gots += count_gots(rels, nrels);
+		fdescs += count_fdescs(rels, nrels);
+
+		/* XXX: By sorting the relocs and finding duplicate entries
+		 *  we could reduce the number of necessary stubs and save
+		 *  some memory. */
+		count = count_stubs(rels, nrels);
+		if (!count)
+			continue;
+
+		/* so we need relocation stubs. reserve necessary memory. */
+		/* sh_info gives the section for which we need to add stubs. */
+		s = sechdrs[i].sh_info;
+
+		/* each code section should only have one relocation section */
+		WARN_ON(me->arch.section[s].stub_entries);
+
+		/* store number of stubs we need for this section */
+		me->arch.section[s].stub_entries += count;
+	}
+
+	/* align things a bit */
+	me->core_layout.size = ALIGN(me->core_layout.size, 16);
+	me->arch.got_offset = me->core_layout.size;
+	me->core_layout.size += gots * sizeof(struct got_entry);
+
+	me->core_layout.size = ALIGN(me->core_layout.size, 16);
+	me->arch.fdesc_offset = me->core_layout.size;
+	me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
+
+	me->arch.got_max = gots;
+	me->arch.fdesc_max = fdescs;
+
+	return 0;
+}
+
+#ifdef CONFIG_64BIT
+static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
+{
+	unsigned int i;
+	struct got_entry *got;
+
+	value += addend;
+
+	BUG_ON(value == 0);
+
+	got = me->core_layout.base + me->arch.got_offset;
+	for (i = 0; got[i].addr; i++)
+		if (got[i].addr == value)
+			goto out;
+
+	BUG_ON(++me->arch.got_count > me->arch.got_max);
+
+	got[i].addr = value;
+ out:
+	DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
+	       value);
+	return i * sizeof(struct got_entry);
+}
+#endif /* CONFIG_64BIT */
+
+#ifdef CONFIG_64BIT
+static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+{
+	Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
+
+	if (!value) {
+		printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+		return 0;
+	}
+
+	/* Look for existing fdesc entry. */
+	while (fdesc->addr) {
+		if (fdesc->addr == value)
+			return (Elf_Addr)fdesc;
+		fdesc++;
+	}
+
+	BUG_ON(++me->arch.fdesc_count > me->arch.fdesc_max);
+
+	/* Create new one */
+	fdesc->addr = value;
+	fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
+	return (Elf_Addr)fdesc;
+}
+#endif /* CONFIG_64BIT */
+
+enum elf_stub_type {
+	ELF_STUB_GOT,
+	ELF_STUB_MILLI,
+	ELF_STUB_DIRECT,
+};
+
+static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
+	enum elf_stub_type stub_type, Elf_Addr loc0, unsigned int targetsec)
+{
+	struct stub_entry *stub;
+	int __maybe_unused d;
+
+	/* initialize stub_offset to point in front of the section */
+	if (!me->arch.section[targetsec].stub_offset) {
+		loc0 -= (me->arch.section[targetsec].stub_entries + 1) *
+				sizeof(struct stub_entry);
+		/* get correct alignment for the stubs */
+		loc0 = ALIGN(loc0, sizeof(struct stub_entry));
+		me->arch.section[targetsec].stub_offset = loc0;
+	}
+
+	/* get address of stub entry */
+	stub = (void *) me->arch.section[targetsec].stub_offset;
+	me->arch.section[targetsec].stub_offset += sizeof(struct stub_entry);
+
+	/* do not write outside available stub area */
+	BUG_ON(0 == me->arch.section[targetsec].stub_entries--);
+
+
+#ifndef CONFIG_64BIT
+/* for 32-bit the stub looks like this:
+ * 	ldil L'XXX,%r1
+ * 	be,n R'XXX(%sr4,%r1)
+ */
+	//value = *(unsigned long *)((value + addend) & ~3); /* why? */
+
+	stub->insns[0] = 0x20200000;	/* ldil L'XXX,%r1	*/
+	stub->insns[1] = 0xe0202002;	/* be,n R'XXX(%sr4,%r1)	*/
+
+	stub->insns[0] |= reassemble_21(lrsel(value, addend));
+	stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
+
+#else
+/* for 64-bit we have three kinds of stubs:
+ * for normal function calls:
+ * 	ldd 0(%dp),%dp
+ * 	ldd 10(%dp), %r1
+ * 	bve (%r1)
+ * 	ldd 18(%dp), %dp
+ *
+ * for millicode:
+ * 	ldil 0, %r1
+ * 	ldo 0(%r1), %r1
+ * 	ldd 10(%r1), %r1
+ * 	bve,n (%r1)
+ *
+ * for direct branches (jumps between different section of the
+ * same module):
+ *	ldil 0, %r1
+ *	ldo 0(%r1), %r1
+ *	bve,n (%r1)
+ */
+	switch (stub_type) {
+	case ELF_STUB_GOT:
+		d = get_got(me, value, addend);
+		if (d <= 15) {
+			/* Format 5 */
+			stub->insns[0] = 0x0f6010db; /* ldd 0(%dp),%dp	*/
+			stub->insns[0] |= low_sign_unext(d, 5) << 16;
+		} else {
+			/* Format 3 */
+			stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp	*/
+			stub->insns[0] |= reassemble_16a(d);
+		}
+		stub->insns[1] = 0x53610020;	/* ldd 10(%dp),%r1	*/
+		stub->insns[2] = 0xe820d000;	/* bve (%r1)		*/
+		stub->insns[3] = 0x537b0030;	/* ldd 18(%dp),%dp	*/
+		break;
+	case ELF_STUB_MILLI:
+		stub->insns[0] = 0x20200000;	/* ldil 0,%r1		*/
+		stub->insns[1] = 0x34210000;	/* ldo 0(%r1), %r1	*/
+		stub->insns[2] = 0x50210020;	/* ldd 10(%r1),%r1	*/
+		stub->insns[3] = 0xe820d002;	/* bve,n (%r1)		*/
+
+		stub->insns[0] |= reassemble_21(lrsel(value, addend));
+		stub->insns[1] |= reassemble_14(rrsel(value, addend));
+		break;
+	case ELF_STUB_DIRECT:
+		stub->insns[0] = 0x20200000;    /* ldil 0,%r1           */
+		stub->insns[1] = 0x34210000;    /* ldo 0(%r1), %r1      */
+		stub->insns[2] = 0xe820d002;    /* bve,n (%r1)          */
+
+		stub->insns[0] |= reassemble_21(lrsel(value, addend));
+		stub->insns[1] |= reassemble_14(rrsel(value, addend));
+		break;
+	}
+
+#endif
+
+	return (Elf_Addr)stub;
+}
+
+#ifndef CONFIG_64BIT
+int apply_relocate_add(Elf_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	int i;
+	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	Elf32_Word *loc;
+	Elf32_Addr val;
+	Elf32_Sword addend;
+	Elf32_Addr dot;
+	Elf_Addr loc0;
+	unsigned int targetsec = sechdrs[relsec].sh_info;
+	//unsigned long dp = (unsigned long)$global$;
+	register unsigned long dp asm ("r27");
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       targetsec);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[targetsec].sh_addr
+		      + rel[i].r_offset;
+		/* This is the start of the target section */
+		loc0 = sechdrs[targetsec].sh_addr;
+		/* This is the symbol it is referring to */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+		//dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
+		dot =  (Elf32_Addr)loc & ~0x03;
+
+		val = sym->st_value;
+		addend = rel[i].r_addend;
+
+#if 0
+#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
+		DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
+			strtab + sym->st_name,
+			(uint32_t)loc, val, addend,
+			r(R_PARISC_PLABEL32)
+			r(R_PARISC_DIR32)
+			r(R_PARISC_DIR21L)
+			r(R_PARISC_DIR14R)
+			r(R_PARISC_SEGREL32)
+			r(R_PARISC_DPREL21L)
+			r(R_PARISC_DPREL14R)
+			r(R_PARISC_PCREL17F)
+			r(R_PARISC_PCREL22F)
+			"UNKNOWN");
+#undef r
+#endif
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_PARISC_PLABEL32:
+			/* 32-bit function address */
+			/* no function descriptors... */
+			*loc = fsel(val, addend);
+			break;
+		case R_PARISC_DIR32:
+			/* direct 32-bit ref */
+			*loc = fsel(val, addend);
+			break;
+		case R_PARISC_DIR21L:
+			/* left 21 bits of effective address */
+			val = lrsel(val, addend);
+			*loc = mask(*loc, 21) | reassemble_21(val);
+			break;
+		case R_PARISC_DIR14R:
+			/* right 14 bits of effective address */
+			val = rrsel(val, addend);
+			*loc = mask(*loc, 14) | reassemble_14(val);
+			break;
+		case R_PARISC_SEGREL32:
+			/* 32-bit segment relative address */
+			/* See note about special handling of SEGREL32 at
+			 * the beginning of this file.
+			 */
+			*loc = fsel(val, addend); 
+			break;
+		case R_PARISC_SECREL32:
+			/* 32-bit section relative address. */
+			*loc = fsel(val, addend);
+			break;
+		case R_PARISC_DPREL21L:
+			/* left 21 bit of relative address */
+			val = lrsel(val - dp, addend);
+			*loc = mask(*loc, 21) | reassemble_21(val);
+			break;
+		case R_PARISC_DPREL14R:
+			/* right 14 bit of relative address */
+			val = rrsel(val - dp, addend);
+			*loc = mask(*loc, 14) | reassemble_14(val);
+			break;
+		case R_PARISC_PCREL17F:
+			/* 17-bit PC relative address */
+			/* calculate direct call offset */
+			val += addend;
+			val = (val - dot - 8)/4;
+			if (!RELOC_REACHABLE(val, 17)) {
+				/* direct distance too far, create
+				 * stub entry instead */
+				val = get_stub(me, sym->st_value, addend,
+					ELF_STUB_DIRECT, loc0, targetsec);
+				val = (val - dot - 8)/4;
+				CHECK_RELOC(val, 17);
+			}
+			*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
+			break;
+		case R_PARISC_PCREL22F:
+			/* 22-bit PC relative address; only defined for pa20 */
+			/* calculate direct call offset */
+			val += addend;
+			val = (val - dot - 8)/4;
+			if (!RELOC_REACHABLE(val, 22)) {
+				/* direct distance too far, create
+				 * stub entry instead */
+				val = get_stub(me, sym->st_value, addend,
+					ELF_STUB_DIRECT, loc0, targetsec);
+				val = (val - dot - 8)/4;
+				CHECK_RELOC(val, 22);
+			}
+			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
+			break;
+		case R_PARISC_PCREL32:
+			/* 32-bit PC relative address */
+			*loc = val - dot - 8 + addend;
+			break;
+
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
+
+#else
+int apply_relocate_add(Elf_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	int i;
+	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	Elf64_Word *loc;
+	Elf64_Xword *loc64;
+	Elf64_Addr val;
+	Elf64_Sxword addend;
+	Elf64_Addr dot;
+	Elf_Addr loc0;
+	unsigned int targetsec = sechdrs[relsec].sh_info;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       targetsec);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[targetsec].sh_addr
+		      + rel[i].r_offset;
+		/* This is the start of the target section */
+		loc0 = sechdrs[targetsec].sh_addr;
+		/* This is the symbol it is referring to */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rel[i].r_info);
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+		//dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
+		dot = (Elf64_Addr)loc & ~0x03;
+		loc64 = (Elf64_Xword *)loc;
+
+		val = sym->st_value;
+		addend = rel[i].r_addend;
+
+#if 0
+#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t :
+		printk("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n",
+			strtab + sym->st_name,
+			loc, val, addend,
+			r(R_PARISC_LTOFF14R)
+			r(R_PARISC_LTOFF21L)
+			r(R_PARISC_PCREL22F)
+			r(R_PARISC_DIR64)
+			r(R_PARISC_SEGREL32)
+			r(R_PARISC_FPTR64)
+			"UNKNOWN");
+#undef r
+#endif
+
+		switch (ELF64_R_TYPE(rel[i].r_info)) {
+		case R_PARISC_LTOFF21L:
+			/* LT-relative; left 21 bits */
+			val = get_got(me, val, addend);
+			DEBUGP("LTOFF21L Symbol %s loc %p val %lx\n",
+			       strtab + sym->st_name,
+			       loc, val);
+			val = lrsel(val, 0);
+			*loc = mask(*loc, 21) | reassemble_21(val);
+			break;
+		case R_PARISC_LTOFF14R:
+			/* L(ltoff(val+addend)) */
+			/* LT-relative; right 14 bits */
+			val = get_got(me, val, addend);
+			val = rrsel(val, 0);
+			DEBUGP("LTOFF14R Symbol %s loc %p val %lx\n",
+			       strtab + sym->st_name,
+			       loc, val);
+			*loc = mask(*loc, 14) | reassemble_14(val);
+			break;
+		case R_PARISC_PCREL22F:
+			/* PC-relative; 22 bits */
+			DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
+			       strtab + sym->st_name,
+			       loc, val);
+			val += addend;
+			/* can we reach it locally? */
+			if (in_local(me, (void *)val)) {
+				/* this is the case where the symbol is local
+				 * to the module, but in a different section,
+				 * so stub the jump in case it's more than 22
+				 * bits away */
+				val = (val - dot - 8)/4;
+				if (!RELOC_REACHABLE(val, 22)) {
+					/* direct distance too far, create
+					 * stub entry instead */
+					val = get_stub(me, sym->st_value,
+						addend, ELF_STUB_DIRECT,
+						loc0, targetsec);
+				} else {
+					/* Ok, we can reach it directly. */
+					val = sym->st_value;
+					val += addend;
+				}
+			} else {
+				val = sym->st_value;
+				if (strncmp(strtab + sym->st_name, "$$", 2)
+				    == 0)
+					val = get_stub(me, val, addend, ELF_STUB_MILLI,
+						       loc0, targetsec);
+				else
+					val = get_stub(me, val, addend, ELF_STUB_GOT,
+						       loc0, targetsec);
+			}
+			DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
+			       strtab + sym->st_name, loc, sym->st_value,
+			       addend, val);
+			val = (val - dot - 8)/4;
+			CHECK_RELOC(val, 22);
+			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
+			break;
+		case R_PARISC_PCREL32:
+			/* 32-bit PC relative address */
+			*loc = val - dot - 8 + addend;
+			break;
+		case R_PARISC_DIR64:
+			/* 64-bit effective address */
+			*loc64 = val + addend;
+			break;
+		case R_PARISC_SEGREL32:
+			/* 32-bit segment relative address */
+			/* See note about special handling of SEGREL32 at
+			 * the beginning of this file.
+			 */
+			*loc = fsel(val, addend); 
+			break;
+		case R_PARISC_SECREL32:
+			/* 32-bit section relative address. */
+			*loc = fsel(val, addend);
+			break;
+		case R_PARISC_FPTR64:
+			/* 64-bit function address */
+			if(in_local(me, (void *)(val + addend))) {
+				*loc64 = get_fdesc(me, val+addend);
+				DEBUGP("FDESC for %s at %p points to %lx\n",
+				       strtab + sym->st_name, *loc64,
+				       ((Elf_Fdesc *)*loc64)->addr);
+			} else {
+				/* if the symbol is not local to this
+				 * module then val+addend is a pointer
+				 * to the function descriptor */
+				DEBUGP("Non local FPTR64 Symbol %s loc %p val %lx\n",
+				       strtab + sym->st_name,
+				       loc, val);
+				*loc64 = val + addend;
+			}
+			break;
+
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
+			       me->name, ELF64_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+#endif
+
+static void
+register_unwind_table(struct module *me,
+		      const Elf_Shdr *sechdrs)
+{
+	unsigned char *table, *end;
+	unsigned long gp;
+
+	if (!me->arch.unwind_section)
+		return;
+
+	table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
+	end = table + sechdrs[me->arch.unwind_section].sh_size;
+	gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
+
+	DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
+	       me->arch.unwind_section, table, end, gp);
+	me->arch.unwind = unwind_table_add(me->name, 0, gp, table, end);
+}
+
+static void
+deregister_unwind_table(struct module *me)
+{
+	if (me->arch.unwind)
+		unwind_table_remove(me->arch.unwind);
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	int i;
+	unsigned long nsyms;
+	const char *strtab = NULL;
+	Elf_Sym *newptr, *oldptr;
+	Elf_Shdr *symhdr = NULL;
+#ifdef DEBUG
+	Elf_Fdesc *entry;
+	u32 *addr;
+
+	entry = (Elf_Fdesc *)me->init;
+	printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry,
+	       entry->gp, entry->addr);
+	addr = (u32 *)entry->addr;
+	printk("INSNS: %x %x %x %x\n",
+	       addr[0], addr[1], addr[2], addr[3]);
+	printk("got entries used %ld, gots max %ld\n"
+	       "fdescs used %ld, fdescs max %ld\n",
+	       me->arch.got_count, me->arch.got_max,
+	       me->arch.fdesc_count, me->arch.fdesc_max);
+#endif
+
+	register_unwind_table(me, sechdrs);
+
+	/* haven't filled in me->symtab yet, so have to find it
+	 * ourselves */
+	for (i = 1; i < hdr->e_shnum; i++) {
+		if(sechdrs[i].sh_type == SHT_SYMTAB
+		   && (sechdrs[i].sh_flags & SHF_ALLOC)) {
+			int strindex = sechdrs[i].sh_link;
+			/* FIXME: AWFUL HACK
+			 * The cast is to drop the const from
+			 * the sechdrs pointer */
+			symhdr = (Elf_Shdr *)&sechdrs[i];
+			strtab = (char *)sechdrs[strindex].sh_addr;
+			break;
+		}
+	}
+
+	DEBUGP("module %s: strtab %p, symhdr %p\n",
+	       me->name, strtab, symhdr);
+
+	if(me->arch.got_count > MAX_GOTS) {
+		printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d)\n",
+				me->name, me->arch.got_count, MAX_GOTS);
+		return -EINVAL;
+	}
+
+	kfree(me->arch.section);
+	me->arch.section = NULL;
+
+	/* no symbol table */
+	if(symhdr == NULL)
+		return 0;
+
+	oldptr = (void *)symhdr->sh_addr;
+	newptr = oldptr + 1;	/* we start counting at 1 */
+	nsyms = symhdr->sh_size / sizeof(Elf_Sym);
+	DEBUGP("OLD num_symtab %lu\n", nsyms);
+
+	for (i = 1; i < nsyms; i++) {
+		oldptr++;	/* note, count starts at 1 so preincrement */
+		if(strncmp(strtab + oldptr->st_name,
+			      ".L", 2) == 0)
+			continue;
+
+		if(newptr != oldptr)
+			*newptr++ = *oldptr;
+		else
+			newptr++;
+
+	}
+	nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
+	DEBUGP("NEW num_symtab %lu\n", nsyms);
+	symhdr->sh_size = nsyms * sizeof(Elf_Sym);
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+	deregister_unwind_table(mod);
+}
+
+#ifdef CONFIG_64BIT
+void *dereference_module_function_descriptor(struct module *mod, void *ptr)
+{
+	unsigned long start_opd = (Elf64_Addr)mod->core_layout.base +
+				   mod->arch.fdesc_offset;
+	unsigned long end_opd = start_opd +
+				mod->arch.fdesc_count * sizeof(Elf64_Fdesc);
+
+	if (ptr < (void *)start_opd || ptr >= (void *)end_opd)
+		return ptr;
+
+	return dereference_function_descriptor(ptr);
+}
+#endif
diff --git a/arch/parisc/kernel/pa7300lc.c b/arch/parisc/kernel/pa7300lc.c
new file mode 100644
index 0000000..0d770ac
--- /dev/null
+++ b/arch/parisc/kernel/pa7300lc.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *   linux/arch/parisc/kernel/pa7300lc.c
+ *	- PA7300LC-specific functions	
+ *
+ *   Copyright (C) 2000 Philipp Rumpf */
+
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/machdep.h>
+
+/* CPU register indices */
+
+#define MIOC_STATUS	0xf040
+#define MIOC_CONTROL	0xf080
+#define MDERRADD	0xf0e0
+#define DMAERR		0xf0e8
+#define DIOERR		0xf0ec
+#define HIDMAMEM	0xf0f4
+
+/* this returns the HPA of the CPU it was called on */
+static u32 cpu_hpa(void)
+{
+	return 0xfffb0000;
+}
+
+static void pa7300lc_lpmc(int code, struct pt_regs *regs)
+{
+	u32 hpa;
+	printk(KERN_WARNING "LPMC on CPU %d\n", smp_processor_id());
+
+	show_regs(regs);
+
+	hpa = cpu_hpa();
+	printk(KERN_WARNING
+		"MIOC_CONTROL %08x\n" "MIOC_STATUS  %08x\n"
+		"MDERRADD     %08x\n" "DMAERR       %08x\n"
+		"DIOERR       %08x\n" "HIDMAMEM     %08x\n",
+		gsc_readl(hpa+MIOC_CONTROL), gsc_readl(hpa+MIOC_STATUS),
+		gsc_readl(hpa+MDERRADD), gsc_readl(hpa+DMAERR),
+		gsc_readl(hpa+DIOERR), gsc_readl(hpa+HIDMAMEM));
+}
+
+void pa7300lc_init(void)
+{
+	cpu_lpmc = pa7300lc_lpmc;
+}
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
new file mode 100644
index 0000000..f33bf2d
--- /dev/null
+++ b/arch/parisc/kernel/pacache.S
@@ -0,0 +1,1191 @@
+/*
+ *  PARISC TLB and cache flushing support
+ *  Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
+ *  Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
+ *  Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
+ *
+ *    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, 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
+ */
+
+/*
+ * NOTE: fdc,fic, and pdc instructions that use base register modification
+ *       should only use index and base registers that are not shadowed,
+ *       so that the fast path emulation in the non access miss handler
+ *       can be used.
+ */
+
+#ifdef CONFIG_64BIT
+	.level	2.0w
+#else
+	.level	2.0
+#endif
+
+#include <asm/psw.h>
+#include <asm/assembly.h>
+#include <asm/pgtable.h>
+#include <asm/cache.h>
+#include <asm/ldcw.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	.section .text.hot
+	.align	16
+
+ENTRY_CFI(flush_tlb_all_local)
+	/*
+	 * The pitlbe and pdtlbe instructions should only be used to
+	 * flush the entire tlb. Also, there needs to be no intervening
+	 * tlb operations, e.g. tlb misses, so the operation needs
+	 * to happen in real mode with all interruptions disabled.
+	 */
+
+	/* pcxt_ssm_bug	- relied upon translation! PA 2.0 Arch. F-4 and F-5 */
+	rsm		PSW_SM_I, %r19		/* save I-bit state */
+	load32		PA(1f), %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+	mtctl		%r0, %cr17		/* Clear IIASQ head */
+	mtctl		%r1, %cr18		/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18		/* IIAOQ tail */
+	load32		REAL_MODE_PSW, %r1
+	mtctl           %r1, %ipsw
+	rfi
+	nop
+
+1:      load32		PA(cache_info), %r1
+
+	/* Flush Instruction Tlb */
+
+	LDREG		ITLB_SID_BASE(%r1), %r20
+	LDREG		ITLB_SID_STRIDE(%r1), %r21
+	LDREG		ITLB_SID_COUNT(%r1), %r22
+	LDREG		ITLB_OFF_BASE(%r1), %arg0
+	LDREG		ITLB_OFF_STRIDE(%r1), %arg1
+	LDREG		ITLB_OFF_COUNT(%r1), %arg2
+	LDREG		ITLB_LOOP(%r1), %arg3
+
+	addib,COND(=)		-1, %arg3, fitoneloop	/* Preadjust and test */
+	movb,<,n	%arg3, %r31, fitdone	/* If loop < 0, skip */
+	copy		%arg0, %r28		/* Init base addr */
+
+fitmanyloop:					/* Loop if LOOP >= 2 */
+	mtsp		%r20, %sr1
+	add		%r21, %r20, %r20	/* increment space */
+	copy		%arg2, %r29		/* Init middle loop count */
+
+fitmanymiddle:					/* Loop if LOOP >= 2 */
+	addib,COND(>)		-1, %r31, fitmanymiddle	/* Adjusted inner loop decr */
+	pitlbe		%r0(%sr1, %r28)
+	pitlbe,m	%arg1(%sr1, %r28)	/* Last pitlbe and addr adjust */
+	addib,COND(>)		-1, %r29, fitmanymiddle	/* Middle loop decr */
+	copy		%arg3, %r31		/* Re-init inner loop count */
+
+	movb,tr		%arg0, %r28, fitmanyloop /* Re-init base addr */
+	addib,COND(<=),n	-1, %r22, fitdone	/* Outer loop count decr */
+
+fitoneloop:					/* Loop if LOOP = 1 */
+	mtsp		%r20, %sr1
+	copy		%arg0, %r28		/* init base addr */
+	copy		%arg2, %r29		/* init middle loop count */
+
+fitonemiddle:					/* Loop if LOOP = 1 */
+	addib,COND(>)		-1, %r29, fitonemiddle	/* Middle loop count decr */
+	pitlbe,m	%arg1(%sr1, %r28)	/* pitlbe for one loop */
+
+	addib,COND(>)		-1, %r22, fitoneloop	/* Outer loop count decr */
+	add		%r21, %r20, %r20		/* increment space */
+
+fitdone:
+
+	/* Flush Data Tlb */
+
+	LDREG		DTLB_SID_BASE(%r1), %r20
+	LDREG		DTLB_SID_STRIDE(%r1), %r21
+	LDREG		DTLB_SID_COUNT(%r1), %r22
+	LDREG		DTLB_OFF_BASE(%r1), %arg0
+	LDREG		DTLB_OFF_STRIDE(%r1), %arg1
+	LDREG		DTLB_OFF_COUNT(%r1), %arg2
+	LDREG		DTLB_LOOP(%r1), %arg3
+
+	addib,COND(=)		-1, %arg3, fdtoneloop	/* Preadjust and test */
+	movb,<,n	%arg3, %r31, fdtdone	/* If loop < 0, skip */
+	copy		%arg0, %r28		/* Init base addr */
+
+fdtmanyloop:					/* Loop if LOOP >= 2 */
+	mtsp		%r20, %sr1
+	add		%r21, %r20, %r20	/* increment space */
+	copy		%arg2, %r29		/* Init middle loop count */
+
+fdtmanymiddle:					/* Loop if LOOP >= 2 */
+	addib,COND(>)		-1, %r31, fdtmanymiddle	/* Adjusted inner loop decr */
+	pdtlbe		%r0(%sr1, %r28)
+	pdtlbe,m	%arg1(%sr1, %r28)	/* Last pdtlbe and addr adjust */
+	addib,COND(>)		-1, %r29, fdtmanymiddle	/* Middle loop decr */
+	copy		%arg3, %r31		/* Re-init inner loop count */
+
+	movb,tr		%arg0, %r28, fdtmanyloop /* Re-init base addr */
+	addib,COND(<=),n	-1, %r22,fdtdone	/* Outer loop count decr */
+
+fdtoneloop:					/* Loop if LOOP = 1 */
+	mtsp		%r20, %sr1
+	copy		%arg0, %r28		/* init base addr */
+	copy		%arg2, %r29		/* init middle loop count */
+
+fdtonemiddle:					/* Loop if LOOP = 1 */
+	addib,COND(>)		-1, %r29, fdtonemiddle	/* Middle loop count decr */
+	pdtlbe,m	%arg1(%sr1, %r28)	/* pdtlbe for one loop */
+
+	addib,COND(>)		-1, %r22, fdtoneloop	/* Outer loop count decr */
+	add		%r21, %r20, %r20	/* increment space */
+
+
+fdtdone:
+	/*
+	 * Switch back to virtual mode
+	 */
+	/* pcxt_ssm_bug */
+	rsm		PSW_SM_I, %r0
+	load32		2f, %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+	mtctl		%r0, %cr17		/* Clear IIASQ head */
+	mtctl		%r1, %cr18		/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18		/* IIAOQ tail */
+	load32		KERNEL_PSW, %r1
+	or		%r1, %r19, %r1	/* I-bit to state on entry */
+	mtctl		%r1, %ipsw	/* restore I-bit (entire PSW) */
+	rfi
+	nop
+
+2:      bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_tlb_all_local)
+
+	.import cache_info,data
+
+ENTRY_CFI(flush_instruction_cache_local)
+	load32		cache_info, %r1
+
+	/* Flush Instruction Cache */
+
+	LDREG		ICACHE_BASE(%r1), %arg0
+	LDREG		ICACHE_STRIDE(%r1), %arg1
+	LDREG		ICACHE_COUNT(%r1), %arg2
+	LDREG		ICACHE_LOOP(%r1), %arg3
+	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
+	mtsp		%r0, %sr1
+	addib,COND(=)		-1, %arg3, fioneloop	/* Preadjust and test */
+	movb,<,n	%arg3, %r31, fisync	/* If loop < 0, do sync */
+
+fimanyloop:					/* Loop if LOOP >= 2 */
+	addib,COND(>)		-1, %r31, fimanyloop	/* Adjusted inner loop decr */
+	fice            %r0(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)	/* Last fice and addr adjust */
+	movb,tr		%arg3, %r31, fimanyloop	/* Re-init inner loop count */
+	addib,COND(<=),n	-1, %arg2, fisync	/* Outer loop decr */
+
+fioneloop:					/* Loop if LOOP = 1 */
+	/* Some implementations may flush with a single fice instruction */
+	cmpib,COND(>>=),n	15, %arg2, fioneloop2
+
+fioneloop1:
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	fice,m		%arg1(%sr1, %arg0)
+	addib,COND(>)	-16, %arg2, fioneloop1
+	fice,m		%arg1(%sr1, %arg0)
+
+	/* Check if done */
+	cmpb,COND(=),n	%arg2, %r0, fisync	/* Predict branch taken */
+
+fioneloop2:
+	addib,COND(>)	-1, %arg2, fioneloop2	/* Outer loop count decr */
+	fice,m		%arg1(%sr1, %arg0)	/* Fice for one loop */
+
+fisync:
+	sync
+	mtsm		%r22			/* restore I-bit */
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_instruction_cache_local)
+
+
+	.import cache_info, data
+ENTRY_CFI(flush_data_cache_local)
+	load32		cache_info, %r1
+
+	/* Flush Data Cache */
+
+	LDREG		DCACHE_BASE(%r1), %arg0
+	LDREG		DCACHE_STRIDE(%r1), %arg1
+	LDREG		DCACHE_COUNT(%r1), %arg2
+	LDREG		DCACHE_LOOP(%r1), %arg3
+	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
+	mtsp		%r0, %sr1
+	addib,COND(=)		-1, %arg3, fdoneloop	/* Preadjust and test */
+	movb,<,n	%arg3, %r31, fdsync	/* If loop < 0, do sync */
+
+fdmanyloop:					/* Loop if LOOP >= 2 */
+	addib,COND(>)		-1, %r31, fdmanyloop	/* Adjusted inner loop decr */
+	fdce		%r0(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)	/* Last fdce and addr adjust */
+	movb,tr		%arg3, %r31, fdmanyloop	/* Re-init inner loop count */
+	addib,COND(<=),n	-1, %arg2, fdsync	/* Outer loop decr */
+
+fdoneloop:					/* Loop if LOOP = 1 */
+	/* Some implementations may flush with a single fdce instruction */
+	cmpib,COND(>>=),n	15, %arg2, fdoneloop2
+
+fdoneloop1:
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	fdce,m		%arg1(%sr1, %arg0)
+	addib,COND(>)	-16, %arg2, fdoneloop1
+	fdce,m		%arg1(%sr1, %arg0)
+
+	/* Check if done */
+	cmpb,COND(=),n	%arg2, %r0, fdsync	/* Predict branch taken */
+
+fdoneloop2:
+	addib,COND(>)	-1, %arg2, fdoneloop2	/* Outer loop count decr */
+	fdce,m		%arg1(%sr1, %arg0)	/* Fdce for one loop */
+
+fdsync:
+	syncdma
+	sync
+	mtsm		%r22			/* restore I-bit */
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_data_cache_local)
+
+/* Macros to serialize TLB purge operations on SMP.  */
+
+	.macro	tlb_lock	la,flags,tmp
+#ifdef CONFIG_SMP
+#if __PA_LDCW_ALIGNMENT > 4
+	load32		pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
+	depi		0,31,__PA_LDCW_ALIGN_ORDER, \la
+#else
+	load32		pa_tlb_lock, \la
+#endif
+	rsm		PSW_SM_I,\flags
+1:	LDCW		0(\la),\tmp
+	cmpib,<>,n	0,\tmp,3f
+2:	ldw		0(\la),\tmp
+	cmpb,<>		%r0,\tmp,1b
+	nop
+	b,n		2b
+3:
+#endif
+	.endm
+
+	.macro	tlb_unlock	la,flags,tmp
+#ifdef CONFIG_SMP
+	ldi		1,\tmp
+	sync
+	stw		\tmp,0(\la)
+	mtsm		\flags
+#endif
+	.endm
+
+/* Clear page using kernel mapping.  */
+
+ENTRY_CFI(clear_page_asm)
+#ifdef CONFIG_64BIT
+
+	/* Unroll the loop.  */
+	ldi		(PAGE_SIZE / 128), %r1
+
+1:
+	std		%r0, 0(%r26)
+	std		%r0, 8(%r26)
+	std		%r0, 16(%r26)
+	std		%r0, 24(%r26)
+	std		%r0, 32(%r26)
+	std		%r0, 40(%r26)
+	std		%r0, 48(%r26)
+	std		%r0, 56(%r26)
+	std		%r0, 64(%r26)
+	std		%r0, 72(%r26)
+	std		%r0, 80(%r26)
+	std		%r0, 88(%r26)
+	std		%r0, 96(%r26)
+	std		%r0, 104(%r26)
+	std		%r0, 112(%r26)
+	std		%r0, 120(%r26)
+
+	/* Note reverse branch hint for addib is taken.  */
+	addib,COND(>),n	-1, %r1, 1b
+	ldo		128(%r26), %r26
+
+#else
+
+	/*
+	 * Note that until (if) we start saving the full 64-bit register
+	 * values on interrupt, we can't use std on a 32 bit kernel.
+	 */
+	ldi		(PAGE_SIZE / 64), %r1
+
+1:
+	stw		%r0, 0(%r26)
+	stw		%r0, 4(%r26)
+	stw		%r0, 8(%r26)
+	stw		%r0, 12(%r26)
+	stw		%r0, 16(%r26)
+	stw		%r0, 20(%r26)
+	stw		%r0, 24(%r26)
+	stw		%r0, 28(%r26)
+	stw		%r0, 32(%r26)
+	stw		%r0, 36(%r26)
+	stw		%r0, 40(%r26)
+	stw		%r0, 44(%r26)
+	stw		%r0, 48(%r26)
+	stw		%r0, 52(%r26)
+	stw		%r0, 56(%r26)
+	stw		%r0, 60(%r26)
+
+	addib,COND(>),n	-1, %r1, 1b
+	ldo		64(%r26), %r26
+#endif
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(clear_page_asm)
+
+/* Copy page using kernel mapping.  */
+
+ENTRY_CFI(copy_page_asm)
+#ifdef CONFIG_64BIT
+	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
+	 * Unroll the loop by hand and arrange insn appropriately.
+	 * Prefetch doesn't improve performance on rp3440.
+	 * GCC probably can do this just as well...
+	 */
+
+	ldi		(PAGE_SIZE / 128), %r1
+
+1:	ldd		0(%r25), %r19
+	ldd		8(%r25), %r20
+
+	ldd		16(%r25), %r21
+	ldd		24(%r25), %r22
+	std		%r19, 0(%r26)
+	std		%r20, 8(%r26)
+
+	ldd		32(%r25), %r19
+	ldd		40(%r25), %r20
+	std		%r21, 16(%r26)
+	std		%r22, 24(%r26)
+
+	ldd		48(%r25), %r21
+	ldd		56(%r25), %r22
+	std		%r19, 32(%r26)
+	std		%r20, 40(%r26)
+
+	ldd		64(%r25), %r19
+	ldd		72(%r25), %r20
+	std		%r21, 48(%r26)
+	std		%r22, 56(%r26)
+
+	ldd		80(%r25), %r21
+	ldd		88(%r25), %r22
+	std		%r19, 64(%r26)
+	std		%r20, 72(%r26)
+
+	ldd		 96(%r25), %r19
+	ldd		104(%r25), %r20
+	std		%r21, 80(%r26)
+	std		%r22, 88(%r26)
+
+	ldd		112(%r25), %r21
+	ldd		120(%r25), %r22
+	ldo		128(%r25), %r25
+	std		%r19, 96(%r26)
+	std		%r20, 104(%r26)
+
+	std		%r21, 112(%r26)
+	std		%r22, 120(%r26)
+
+	/* Note reverse branch hint for addib is taken.  */
+	addib,COND(>),n	-1, %r1, 1b
+	ldo		128(%r26), %r26
+
+#else
+
+	/*
+	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+	 * bundles (very restricted rules for bundling).
+	 * Note that until (if) we start saving
+	 * the full 64 bit register values on interrupt, we can't
+	 * use ldd/std on a 32 bit kernel.
+	 */
+	ldw		0(%r25), %r19
+	ldi		(PAGE_SIZE / 64), %r1
+
+1:
+	ldw		4(%r25), %r20
+	ldw		8(%r25), %r21
+	ldw		12(%r25), %r22
+	stw		%r19, 0(%r26)
+	stw		%r20, 4(%r26)
+	stw		%r21, 8(%r26)
+	stw		%r22, 12(%r26)
+	ldw		16(%r25), %r19
+	ldw		20(%r25), %r20
+	ldw		24(%r25), %r21
+	ldw		28(%r25), %r22
+	stw		%r19, 16(%r26)
+	stw		%r20, 20(%r26)
+	stw		%r21, 24(%r26)
+	stw		%r22, 28(%r26)
+	ldw		32(%r25), %r19
+	ldw		36(%r25), %r20
+	ldw		40(%r25), %r21
+	ldw		44(%r25), %r22
+	stw		%r19, 32(%r26)
+	stw		%r20, 36(%r26)
+	stw		%r21, 40(%r26)
+	stw		%r22, 44(%r26)
+	ldw		48(%r25), %r19
+	ldw		52(%r25), %r20
+	ldw		56(%r25), %r21
+	ldw		60(%r25), %r22
+	stw		%r19, 48(%r26)
+	stw		%r20, 52(%r26)
+	ldo		64(%r25), %r25
+	stw		%r21, 56(%r26)
+	stw		%r22, 60(%r26)
+	ldo		64(%r26), %r26
+	addib,COND(>),n	-1, %r1, 1b
+	ldw		0(%r25), %r19
+#endif
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(copy_page_asm)
+
+/*
+ * NOTE: Code in clear_user_page has a hard coded dependency on the
+ *       maximum alias boundary being 4 Mb. We've been assured by the
+ *       parisc chip designers that there will not ever be a parisc
+ *       chip with a larger alias boundary (Never say never :-) ).
+ *
+ *       Subtle: the dtlb miss handlers support the temp alias region by
+ *       "knowing" that if a dtlb miss happens within the temp alias
+ *       region it must have occurred while in clear_user_page. Since
+ *       this routine makes use of processor local translations, we
+ *       don't want to insert them into the kernel page table. Instead,
+ *       we load up some general registers (they need to be registers
+ *       which aren't shadowed) with the physical page numbers (preshifted
+ *       for tlb insertion) needed to insert the translations. When we
+ *       miss on the translation, the dtlb miss handler inserts the
+ *       translation into the tlb using these values:
+ *
+ *          %r26 physical page (shifted for tlb insert) of "to" translation
+ *          %r23 physical page (shifted for tlb insert) of "from" translation
+ */
+
+        /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+        #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
+        .macro          convert_phys_for_tlb_insert20  phys
+        extrd,u         \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys
+#if _PAGE_SIZE_ENCODING_DEFAULT
+        depdi           _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys
+#endif
+	.endm
+
+	/*
+	 * copy_user_page_asm() performs a page copy using mappings
+	 * equivalent to the user page mappings.  It can be used to
+	 * implement copy_user_page() but unfortunately both the `from'
+	 * and `to' pages need to be flushed through mappings equivalent
+	 * to the user mappings after the copy because the kernel accesses
+	 * the `from' page through the kmap kernel mapping and the `to'
+	 * page needs to be flushed since code can be copied.  As a
+	 * result, this implementation is less efficient than the simpler
+	 * copy using the kernel mapping.  It only needs the `from' page
+	 * to flushed via the user mapping.  The kunmap routines handle
+	 * the flushes needed for the kernel mapping.
+	 *
+	 * I'm still keeping this around because it may be possible to
+	 * use it if more information is passed into copy_user_page().
+	 * Have to do some measurements to see if it is worthwhile to
+	 * lobby for such a change.
+	 *
+	 */
+
+ENTRY_CFI(copy_user_page_asm)
+	/* Convert virtual `to' and `from' addresses to physical addresses.
+	   Move `from' physical address to non shadowed register.  */
+	ldil		L%(__PAGE_OFFSET), %r1
+	sub		%r26, %r1, %r26
+	sub		%r25, %r1, %r23
+
+	ldil		L%(TMPALIAS_MAP_START), %r28
+#ifdef CONFIG_64BIT
+#if (TMPALIAS_MAP_START >= 0x80000000)
+	depdi		0, 31,32, %r28		/* clear any sign extension */
+#endif
+	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
+	convert_phys_for_tlb_insert20 %r23	/* convert phys addr to tlb insert format */
+	depd		%r24,63,22, %r28	/* Form aliased virtual address 'to' */
+	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
+	copy		%r28, %r29
+	depdi		1, 41,1, %r29		/* Form aliased virtual address 'from' */
+#else
+	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
+	extrw,u		%r23, 24,25, %r23	/* convert phys addr to tlb insert format */
+	depw		%r24, 31,22, %r28	/* Form aliased virtual address 'to' */
+	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
+	copy		%r28, %r29
+	depwi		1, 9,1, %r29		/* Form aliased virtual address 'from' */
+#endif
+
+	/* Purge any old translations */
+
+#ifdef CONFIG_PA20
+	pdtlb,l		%r0(%r28)
+	pdtlb,l		%r0(%r29)
+#else
+	tlb_lock	%r20,%r21,%r22
+	pdtlb		%r0(%r28)
+	pdtlb		%r0(%r29)
+	tlb_unlock	%r20,%r21,%r22
+#endif
+
+#ifdef CONFIG_64BIT
+	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
+	 * Unroll the loop by hand and arrange insn appropriately.
+	 * GCC probably can do this just as well.
+	 */
+
+	ldd		0(%r29), %r19
+	ldi		(PAGE_SIZE / 128), %r1
+
+1:	ldd		8(%r29), %r20
+
+	ldd		16(%r29), %r21
+	ldd		24(%r29), %r22
+	std		%r19, 0(%r28)
+	std		%r20, 8(%r28)
+
+	ldd		32(%r29), %r19
+	ldd		40(%r29), %r20
+	std		%r21, 16(%r28)
+	std		%r22, 24(%r28)
+
+	ldd		48(%r29), %r21
+	ldd		56(%r29), %r22
+	std		%r19, 32(%r28)
+	std		%r20, 40(%r28)
+
+	ldd		64(%r29), %r19
+	ldd		72(%r29), %r20
+	std		%r21, 48(%r28)
+	std		%r22, 56(%r28)
+
+	ldd		80(%r29), %r21
+	ldd		88(%r29), %r22
+	std		%r19, 64(%r28)
+	std		%r20, 72(%r28)
+
+	ldd		 96(%r29), %r19
+	ldd		104(%r29), %r20
+	std		%r21, 80(%r28)
+	std		%r22, 88(%r28)
+
+	ldd		112(%r29), %r21
+	ldd		120(%r29), %r22
+	std		%r19, 96(%r28)
+	std		%r20, 104(%r28)
+
+	ldo		128(%r29), %r29
+	std		%r21, 112(%r28)
+	std		%r22, 120(%r28)
+	ldo		128(%r28), %r28
+
+	/* conditional branches nullify on forward taken branch, and on
+	 * non-taken backward branch. Note that .+4 is a backwards branch.
+	 * The ldd should only get executed if the branch is taken.
+	 */
+	addib,COND(>),n	-1, %r1, 1b		/* bundle 10 */
+	ldd		0(%r29), %r19		/* start next loads */
+
+#else
+	ldi		(PAGE_SIZE / 64), %r1
+
+	/*
+	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+	 * bundles (very restricted rules for bundling). It probably
+	 * does OK on PCXU and better, but we could do better with
+	 * ldd/std instructions. Note that until (if) we start saving
+	 * the full 64 bit register values on interrupt, we can't
+	 * use ldd/std on a 32 bit kernel.
+	 */
+
+1:	ldw		0(%r29), %r19
+	ldw		4(%r29), %r20
+	ldw		8(%r29), %r21
+	ldw		12(%r29), %r22
+	stw		%r19, 0(%r28)
+	stw		%r20, 4(%r28)
+	stw		%r21, 8(%r28)
+	stw		%r22, 12(%r28)
+	ldw		16(%r29), %r19
+	ldw		20(%r29), %r20
+	ldw		24(%r29), %r21
+	ldw		28(%r29), %r22
+	stw		%r19, 16(%r28)
+	stw		%r20, 20(%r28)
+	stw		%r21, 24(%r28)
+	stw		%r22, 28(%r28)
+	ldw		32(%r29), %r19
+	ldw		36(%r29), %r20
+	ldw		40(%r29), %r21
+	ldw		44(%r29), %r22
+	stw		%r19, 32(%r28)
+	stw		%r20, 36(%r28)
+	stw		%r21, 40(%r28)
+	stw		%r22, 44(%r28)
+	ldw		48(%r29), %r19
+	ldw		52(%r29), %r20
+	ldw		56(%r29), %r21
+	ldw		60(%r29), %r22
+	stw		%r19, 48(%r28)
+	stw		%r20, 52(%r28)
+	stw		%r21, 56(%r28)
+	stw		%r22, 60(%r28)
+	ldo		64(%r28), %r28
+
+	addib,COND(>)		-1, %r1,1b
+	ldo		64(%r29), %r29
+#endif
+
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(copy_user_page_asm)
+
+ENTRY_CFI(clear_user_page_asm)
+	tophys_r1	%r26
+
+	ldil		L%(TMPALIAS_MAP_START), %r28
+#ifdef CONFIG_64BIT
+#if (TMPALIAS_MAP_START >= 0x80000000)
+	depdi		0, 31,32, %r28		/* clear any sign extension */
+#endif
+	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
+	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
+	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#else
+	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
+	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
+	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#endif
+
+	/* Purge any old translation */
+
+#ifdef CONFIG_PA20
+	pdtlb,l		%r0(%r28)
+#else
+	tlb_lock	%r20,%r21,%r22
+	pdtlb		%r0(%r28)
+	tlb_unlock	%r20,%r21,%r22
+#endif
+
+#ifdef CONFIG_64BIT
+	ldi		(PAGE_SIZE / 128), %r1
+
+	/* PREFETCH (Write) has not (yet) been proven to help here */
+	/* #define	PREFETCHW_OP	ldd		256(%0), %r0 */
+
+1:	std		%r0, 0(%r28)
+	std		%r0, 8(%r28)
+	std		%r0, 16(%r28)
+	std		%r0, 24(%r28)
+	std		%r0, 32(%r28)
+	std		%r0, 40(%r28)
+	std		%r0, 48(%r28)
+	std		%r0, 56(%r28)
+	std		%r0, 64(%r28)
+	std		%r0, 72(%r28)
+	std		%r0, 80(%r28)
+	std		%r0, 88(%r28)
+	std		%r0, 96(%r28)
+	std		%r0, 104(%r28)
+	std		%r0, 112(%r28)
+	std		%r0, 120(%r28)
+	addib,COND(>)		-1, %r1, 1b
+	ldo		128(%r28), %r28
+
+#else	/* ! CONFIG_64BIT */
+	ldi		(PAGE_SIZE / 64), %r1
+
+1:	stw		%r0, 0(%r28)
+	stw		%r0, 4(%r28)
+	stw		%r0, 8(%r28)
+	stw		%r0, 12(%r28)
+	stw		%r0, 16(%r28)
+	stw		%r0, 20(%r28)
+	stw		%r0, 24(%r28)
+	stw		%r0, 28(%r28)
+	stw		%r0, 32(%r28)
+	stw		%r0, 36(%r28)
+	stw		%r0, 40(%r28)
+	stw		%r0, 44(%r28)
+	stw		%r0, 48(%r28)
+	stw		%r0, 52(%r28)
+	stw		%r0, 56(%r28)
+	stw		%r0, 60(%r28)
+	addib,COND(>)		-1, %r1, 1b
+	ldo		64(%r28), %r28
+#endif	/* CONFIG_64BIT */
+
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(clear_user_page_asm)
+
+ENTRY_CFI(flush_dcache_page_asm)
+	ldil		L%(TMPALIAS_MAP_START), %r28
+#ifdef CONFIG_64BIT
+#if (TMPALIAS_MAP_START >= 0x80000000)
+	depdi		0, 31,32, %r28		/* clear any sign extension */
+#endif
+	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
+	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
+	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#else
+	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
+	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
+	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#endif
+
+	/* Purge any old translation */
+
+#ifdef CONFIG_PA20
+	pdtlb,l		%r0(%r28)
+#else
+	tlb_lock	%r20,%r21,%r22
+	pdtlb		%r0(%r28)
+	tlb_unlock	%r20,%r21,%r22
+#endif
+
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), r31
+
+#ifdef CONFIG_64BIT
+	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+#else
+	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+#endif
+	add		%r28, %r25, %r25
+	sub		%r25, r31, %r25
+
+
+1:      fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	fdc,m		r31(%r28)
+	cmpb,COND(<<)	%r28, %r25,1b
+	fdc,m		r31(%r28)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_dcache_page_asm)
+
+ENTRY_CFI(flush_icache_page_asm)
+	ldil		L%(TMPALIAS_MAP_START), %r28
+#ifdef CONFIG_64BIT
+#if (TMPALIAS_MAP_START >= 0x80000000)
+	depdi		0, 31,32, %r28		/* clear any sign extension */
+#endif
+	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
+	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
+	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#else
+	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
+	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
+	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
+#endif
+
+	/* Purge any old translation.  Note that the FIC instruction
+	 * may use either the instruction or data TLB.  Given that we
+	 * have a flat address space, it's not clear which TLB will be
+	 * used.  So, we purge both entries.  */
+
+#ifdef CONFIG_PA20
+	pdtlb,l		%r0(%r28)
+	pitlb,l         %r0(%sr4,%r28)
+#else
+	tlb_lock        %r20,%r21,%r22
+	pdtlb		%r0(%r28)
+	pitlb           %r0(%sr4,%r28)
+	tlb_unlock      %r20,%r21,%r22
+#endif
+
+	ldil		L%icache_stride, %r1
+	ldw		R%icache_stride(%r1), %r31
+
+#ifdef CONFIG_64BIT
+	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+#else
+	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+#endif
+	add		%r28, %r25, %r25
+	sub		%r25, %r31, %r25
+
+
+	/* fic only has the type 26 form on PA1.1, requiring an
+	 * explicit space specification, so use %sr4 */
+1:      fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	fic,m		%r31(%sr4,%r28)
+	cmpb,COND(<<)	%r28, %r25,1b
+	fic,m		%r31(%sr4,%r28)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_icache_page_asm)
+
+ENTRY_CFI(flush_kernel_dcache_page_asm)
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), %r23
+
+#ifdef CONFIG_64BIT
+	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+#else
+	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+#endif
+	add		%r26, %r25, %r25
+	sub		%r25, %r23, %r25
+
+
+1:      fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	fdc,m		%r23(%r26)
+	cmpb,COND(<<)		%r26, %r25,1b
+	fdc,m		%r23(%r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_kernel_dcache_page_asm)
+
+ENTRY_CFI(purge_kernel_dcache_page_asm)
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), %r23
+
+#ifdef CONFIG_64BIT
+	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+#else
+	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+#endif
+	add		%r26, %r25, %r25
+	sub		%r25, %r23, %r25
+
+1:      pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	pdc,m		%r23(%r26)
+	cmpb,COND(<<)		%r26, %r25, 1b
+	pdc,m		%r23(%r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(purge_kernel_dcache_page_asm)
+
+ENTRY_CFI(flush_user_dcache_range_asm)
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), %r23
+	ldo		-1(%r23), %r21
+	ANDCM		%r26, %r21, %r26
+
+1:      cmpb,COND(<<),n	%r26, %r25, 1b
+	fdc,m		%r23(%sr3, %r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_user_dcache_range_asm)
+
+ENTRY_CFI(flush_kernel_dcache_range_asm)
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), %r23
+	ldo		-1(%r23), %r21
+	ANDCM		%r26, %r21, %r26
+
+1:      cmpb,COND(<<),n	%r26, %r25,1b
+	fdc,m		%r23(%r26)
+
+	sync
+	syncdma
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_kernel_dcache_range_asm)
+
+ENTRY_CFI(purge_kernel_dcache_range_asm)
+	ldil		L%dcache_stride, %r1
+	ldw		R%dcache_stride(%r1), %r23
+	ldo		-1(%r23), %r21
+	ANDCM		%r26, %r21, %r26
+
+1:      cmpb,COND(<<),n	%r26, %r25,1b
+	pdc,m		%r23(%r26)
+
+	sync
+	syncdma
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(purge_kernel_dcache_range_asm)
+
+ENTRY_CFI(flush_user_icache_range_asm)
+	ldil		L%icache_stride, %r1
+	ldw		R%icache_stride(%r1), %r23
+	ldo		-1(%r23), %r21
+	ANDCM		%r26, %r21, %r26
+
+1:      cmpb,COND(<<),n	%r26, %r25,1b
+	fic,m		%r23(%sr3, %r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_user_icache_range_asm)
+
+ENTRY_CFI(flush_kernel_icache_page)
+	ldil		L%icache_stride, %r1
+	ldw		R%icache_stride(%r1), %r23
+
+#ifdef CONFIG_64BIT
+	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+#else
+	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+#endif
+	add		%r26, %r25, %r25
+	sub		%r25, %r23, %r25
+
+
+1:      fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	fic,m		%r23(%sr4, %r26)
+	cmpb,COND(<<)		%r26, %r25, 1b
+	fic,m		%r23(%sr4, %r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_kernel_icache_page)
+
+ENTRY_CFI(flush_kernel_icache_range_asm)
+	ldil		L%icache_stride, %r1
+	ldw		R%icache_stride(%r1), %r23
+	ldo		-1(%r23), %r21
+	ANDCM		%r26, %r21, %r26
+
+1:      cmpb,COND(<<),n	%r26, %r25, 1b
+	fic,m		%r23(%sr4, %r26)
+
+	sync
+	bv		%r0(%r2)
+	nop
+ENDPROC_CFI(flush_kernel_icache_range_asm)
+
+	__INIT
+
+	/* align should cover use of rfi in disable_sr_hashing_asm and
+	 * srdis_done.
+	 */
+	.align	256
+ENTRY_CFI(disable_sr_hashing_asm)
+	/*
+	 * Switch to real mode
+	 */
+	/* pcxt_ssm_bug */
+	rsm		PSW_SM_I, %r0
+	load32		PA(1f), %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+	mtctl		%r0, %cr17		/* Clear IIASQ head */
+	mtctl		%r1, %cr18		/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18		/* IIAOQ tail */
+	load32		REAL_MODE_PSW, %r1
+	mtctl		%r1, %ipsw
+	rfi
+	nop
+
+1:      cmpib,=,n	SRHASH_PCXST, %r26,srdis_pcxs
+	cmpib,=,n	SRHASH_PCXL, %r26,srdis_pcxl
+	cmpib,=,n	SRHASH_PA20, %r26,srdis_pa20
+	b,n		srdis_done
+
+srdis_pcxs:
+
+	/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
+
+	.word		0x141c1a00		/* mfdiag %dr0, %r28 */
+	.word		0x141c1a00		/* must issue twice */
+	depwi		0,18,1, %r28		/* Clear DHE (dcache hash enable) */
+	depwi		0,20,1, %r28		/* Clear IHE (icache hash enable) */
+	.word		0x141c1600		/* mtdiag %r28, %dr0 */
+	.word		0x141c1600		/* must issue twice */
+	b,n		srdis_done
+
+srdis_pcxl:
+
+	/* Disable Space Register Hashing for PCXL */
+
+	.word		0x141c0600		/* mfdiag %dr0, %r28 */
+	depwi           0,28,2, %r28		/* Clear DHASH_EN & IHASH_EN */
+	.word		0x141c0240		/* mtdiag %r28, %dr0 */
+	b,n		srdis_done
+
+srdis_pa20:
+
+	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
+
+	.word		0x144008bc		/* mfdiag %dr2, %r28 */
+	depdi		0, 54,1, %r28		/* clear DIAG_SPHASH_ENAB (bit 54) */
+	.word		0x145c1840		/* mtdiag %r28, %dr2 */
+
+
+srdis_done:
+	/* Switch back to virtual mode */
+	rsm		PSW_SM_I, %r0		/* prep to load iia queue */
+	load32 	   	2f, %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+	mtctl		%r0, %cr17		/* Clear IIASQ head */
+	mtctl		%r1, %cr18		/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18		/* IIAOQ tail */
+	load32		KERNEL_PSW, %r1
+	mtctl		%r1, %ipsw
+	rfi
+	nop
+
+2:      bv		%r0(%r2)
+	nop
+ENDPROC_CFI(disable_sr_hashing_asm)
+
+	.end
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
new file mode 100644
index 0000000..7baa226
--- /dev/null
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -0,0 +1,154 @@
+/*
+ *    Architecture-specific kernel symbols
+ *
+ *    Copyright (C) 2000-2001 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2001 Dave Kennedy
+ *    Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001-2003 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2002-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq at parisc-linux.org>
+ *    Copyright (C) 2002-2007 Helge Deller <deller with parisc-linux.org>
+ * 
+ *    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
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+
+#include <linux/string.h>
+EXPORT_SYMBOL(memset);
+
+#include <linux/atomic.h>
+EXPORT_SYMBOL(__xchg8);
+EXPORT_SYMBOL(__xchg32);
+EXPORT_SYMBOL(__cmpxchg_u32);
+EXPORT_SYMBOL(__cmpxchg_u64);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(__atomic_hash);
+#endif
+#ifdef CONFIG_64BIT
+EXPORT_SYMBOL(__xchg64);
+#endif
+
+#include <linux/uaccess.h>
+EXPORT_SYMBOL(lclear_user);
+EXPORT_SYMBOL(lstrnlen_user);
+
+#ifndef CONFIG_64BIT
+/* Needed so insmod can set dp value */
+extern int $global$;
+EXPORT_SYMBOL($global$);
+#endif
+
+#include <asm/io.h>
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memset_io);
+
+extern void $$divI(void);
+extern void $$divU(void);
+extern void $$remI(void);
+extern void $$remU(void);
+extern void $$mulI(void);
+extern void $$divU_3(void);
+extern void $$divU_5(void);
+extern void $$divU_6(void);
+extern void $$divU_9(void);
+extern void $$divU_10(void);
+extern void $$divU_12(void);
+extern void $$divU_7(void);
+extern void $$divU_14(void);
+extern void $$divU_15(void);
+extern void $$divI_3(void);
+extern void $$divI_5(void);
+extern void $$divI_6(void);
+extern void $$divI_7(void);
+extern void $$divI_9(void);
+extern void $$divI_10(void);
+extern void $$divI_12(void);
+extern void $$divI_14(void);
+extern void $$divI_15(void);
+
+EXPORT_SYMBOL($$divI);
+EXPORT_SYMBOL($$divU);
+EXPORT_SYMBOL($$remI);
+EXPORT_SYMBOL($$remU);
+EXPORT_SYMBOL($$mulI);
+EXPORT_SYMBOL($$divU_3);
+EXPORT_SYMBOL($$divU_5);
+EXPORT_SYMBOL($$divU_6);
+EXPORT_SYMBOL($$divU_9);
+EXPORT_SYMBOL($$divU_10);
+EXPORT_SYMBOL($$divU_12);
+EXPORT_SYMBOL($$divU_7);
+EXPORT_SYMBOL($$divU_14);
+EXPORT_SYMBOL($$divU_15);
+EXPORT_SYMBOL($$divI_3);
+EXPORT_SYMBOL($$divI_5);
+EXPORT_SYMBOL($$divI_6);
+EXPORT_SYMBOL($$divI_7);
+EXPORT_SYMBOL($$divI_9);
+EXPORT_SYMBOL($$divI_10);
+EXPORT_SYMBOL($$divI_12);
+EXPORT_SYMBOL($$divI_14);
+EXPORT_SYMBOL($$divI_15);
+
+extern void __ashrdi3(void);
+extern void __ashldi3(void);
+extern void __lshrdi3(void);
+extern void __muldi3(void);
+extern void __ucmpdi2(void);
+
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__ucmpdi2);
+
+asmlinkage void * __canonicalize_funcptr_for_compare(void *);
+EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
+
+#ifdef CONFIG_64BIT
+extern void __divdi3(void);
+extern void __udivdi3(void);
+extern void __umoddi3(void);
+extern void __moddi3(void);
+
+EXPORT_SYMBOL(__divdi3);
+EXPORT_SYMBOL(__udivdi3);
+EXPORT_SYMBOL(__umoddi3);
+EXPORT_SYMBOL(__moddi3);
+#endif
+
+#ifndef CONFIG_64BIT
+extern void $$dyncall(void);
+EXPORT_SYMBOL($$dyncall);
+#endif
+
+#ifdef CONFIG_DISCONTIGMEM
+#include <asm/mmzone.h>
+EXPORT_SYMBOL(node_data);
+EXPORT_SYMBOL(pfnnid_map);
+#endif
+
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
+
+/* from pacache.S -- needed for clear/copy_page */
+EXPORT_SYMBOL(clear_page_asm);
+EXPORT_SYMBOL(copy_page_asm);
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
new file mode 100644
index 0000000..04c48f1
--- /dev/null
+++ b/arch/parisc/kernel/pci-dma.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+** PARISC 1.1 Dynamic DMA mapping support.
+** This implementation is for PA-RISC platforms that do not support
+** I/O TLBs (aka DMA address translation hardware).
+** See Documentation/DMA-API-HOWTO.txt for interface definitions.
+**
+**      (c) Copyright 1999,2000 Hewlett-Packard Company
+**      (c) Copyright 2000 Grant Grundler
+**	(c) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
+**      (c) Copyright 2000 John Marvin
+**
+** "leveraged" from 2.3.47: arch/ia64/kernel/pci-dma.c.
+** (I assume it's from David Mosberger-Tang but there was no Copyright)
+**
+** AFAIK, all PA7100LC and PA7300LC platforms can use this code.
+**
+** - ggg
+*/
+
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/dma-direct.h>
+#include <linux/dma-noncoherent.h>
+
+#include <asm/cacheflush.h>
+#include <asm/dma.h>    /* for DMA_CHUNK_SIZE */
+#include <asm/io.h>
+#include <asm/page.h>	/* get_order */
+#include <asm/pgalloc.h>
+#include <linux/uaccess.h>
+#include <asm/tlbflush.h>	/* for purge_tlb_*() macros */
+
+static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
+static unsigned long pcxl_used_bytes __read_mostly = 0;
+static unsigned long pcxl_used_pages __read_mostly = 0;
+
+extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */
+static DEFINE_SPINLOCK(pcxl_res_lock);
+static char    *pcxl_res_map;
+static int     pcxl_res_hint;
+static int     pcxl_res_size;
+
+#ifdef DEBUG_PCXL_RESOURCE
+#define DBG_RES(x...)	printk(x)
+#else
+#define DBG_RES(x...)
+#endif
+
+
+/*
+** Dump a hex representation of the resource map.
+*/
+
+#ifdef DUMP_RESMAP
+static
+void dump_resmap(void)
+{
+	u_long *res_ptr = (unsigned long *)pcxl_res_map;
+	u_long i = 0;
+
+	printk("res_map: ");
+	for(; i < (pcxl_res_size / sizeof(unsigned long)); ++i, ++res_ptr)
+		printk("%08lx ", *res_ptr);
+
+	printk("\n");
+}
+#else
+static inline void dump_resmap(void) {;}
+#endif
+
+static inline int map_pte_uncached(pte_t * pte,
+		unsigned long vaddr,
+		unsigned long size, unsigned long *paddr_ptr)
+{
+	unsigned long end;
+	unsigned long orig_vaddr = vaddr;
+
+	vaddr &= ~PMD_MASK;
+	end = vaddr + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		unsigned long flags;
+
+		if (!pte_none(*pte))
+			printk(KERN_ERR "map_pte_uncached: page already exists\n");
+		purge_tlb_start(flags);
+		set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
+		pdtlb_kernel(orig_vaddr);
+		purge_tlb_end(flags);
+		vaddr += PAGE_SIZE;
+		orig_vaddr += PAGE_SIZE;
+		(*paddr_ptr) += PAGE_SIZE;
+		pte++;
+	} while (vaddr < end);
+	return 0;
+}
+
+static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
+		unsigned long size, unsigned long *paddr_ptr)
+{
+	unsigned long end;
+	unsigned long orig_vaddr = vaddr;
+
+	vaddr &= ~PGDIR_MASK;
+	end = vaddr + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	do {
+		pte_t * pte = pte_alloc_kernel(pmd, vaddr);
+		if (!pte)
+			return -ENOMEM;
+		if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
+			return -ENOMEM;
+		vaddr = (vaddr + PMD_SIZE) & PMD_MASK;
+		orig_vaddr += PMD_SIZE;
+		pmd++;
+	} while (vaddr < end);
+	return 0;
+}
+
+static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
+		unsigned long paddr)
+{
+	pgd_t * dir;
+	unsigned long end = vaddr + size;
+
+	dir = pgd_offset_k(vaddr);
+	do {
+		pmd_t *pmd;
+		
+		pmd = pmd_alloc(NULL, dir, vaddr);
+		if (!pmd)
+			return -ENOMEM;
+		if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
+			return -ENOMEM;
+		vaddr = vaddr + PGDIR_SIZE;
+		dir++;
+	} while (vaddr && (vaddr < end));
+	return 0;
+}
+
+static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr,
+		unsigned long size)
+{
+	pte_t * pte;
+	unsigned long end;
+	unsigned long orig_vaddr = vaddr;
+
+	if (pmd_none(*pmd))
+		return;
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
+		pmd_clear(pmd);
+		return;
+	}
+	pte = pte_offset_map(pmd, vaddr);
+	vaddr &= ~PMD_MASK;
+	end = vaddr + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		unsigned long flags;
+		pte_t page = *pte;
+
+		pte_clear(&init_mm, vaddr, pte);
+		purge_tlb_start(flags);
+		pdtlb_kernel(orig_vaddr);
+		purge_tlb_end(flags);
+		vaddr += PAGE_SIZE;
+		orig_vaddr += PAGE_SIZE;
+		pte++;
+		if (pte_none(page) || pte_present(page))
+			continue;
+		printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
+	} while (vaddr < end);
+}
+
+static inline void unmap_uncached_pmd(pgd_t * dir, unsigned long vaddr,
+		unsigned long size)
+{
+	pmd_t * pmd;
+	unsigned long end;
+	unsigned long orig_vaddr = vaddr;
+
+	if (pgd_none(*dir))
+		return;
+	if (pgd_bad(*dir)) {
+		pgd_ERROR(*dir);
+		pgd_clear(dir);
+		return;
+	}
+	pmd = pmd_offset(dir, vaddr);
+	vaddr &= ~PGDIR_MASK;
+	end = vaddr + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	do {
+		unmap_uncached_pte(pmd, orig_vaddr, end - vaddr);
+		vaddr = (vaddr + PMD_SIZE) & PMD_MASK;
+		orig_vaddr += PMD_SIZE;
+		pmd++;
+	} while (vaddr < end);
+}
+
+static void unmap_uncached_pages(unsigned long vaddr, unsigned long size)
+{
+	pgd_t * dir;
+	unsigned long end = vaddr + size;
+
+	dir = pgd_offset_k(vaddr);
+	do {
+		unmap_uncached_pmd(dir, vaddr, end - vaddr);
+		vaddr = vaddr + PGDIR_SIZE;
+		dir++;
+	} while (vaddr && (vaddr < end));
+}
+
+#define PCXL_SEARCH_LOOP(idx, mask, size)  \
+       for(; res_ptr < res_end; ++res_ptr) \
+       { \
+               if(0 == ((*res_ptr) & mask)) { \
+                       *res_ptr |= mask; \
+		       idx = (int)((u_long)res_ptr - (u_long)pcxl_res_map); \
+		       pcxl_res_hint = idx + (size >> 3); \
+                       goto resource_found; \
+               } \
+       }
+
+#define PCXL_FIND_FREE_MAPPING(idx, mask, size)  { \
+       u##size *res_ptr = (u##size *)&(pcxl_res_map[pcxl_res_hint & ~((size >> 3) - 1)]); \
+       u##size *res_end = (u##size *)&pcxl_res_map[pcxl_res_size]; \
+       PCXL_SEARCH_LOOP(idx, mask, size); \
+       res_ptr = (u##size *)&pcxl_res_map[0]; \
+       PCXL_SEARCH_LOOP(idx, mask, size); \
+}
+
+unsigned long
+pcxl_alloc_range(size_t size)
+{
+	int res_idx;
+	u_long mask, flags;
+	unsigned int pages_needed = size >> PAGE_SHIFT;
+
+	mask = (u_long) -1L;
+ 	mask >>= BITS_PER_LONG - pages_needed;
+
+	DBG_RES("pcxl_alloc_range() size: %d pages_needed %d pages_mask 0x%08lx\n", 
+		size, pages_needed, mask);
+
+	spin_lock_irqsave(&pcxl_res_lock, flags);
+
+	if(pages_needed <= 8) {
+		PCXL_FIND_FREE_MAPPING(res_idx, mask, 8);
+	} else if(pages_needed <= 16) {
+		PCXL_FIND_FREE_MAPPING(res_idx, mask, 16);
+	} else if(pages_needed <= 32) {
+		PCXL_FIND_FREE_MAPPING(res_idx, mask, 32);
+	} else {
+		panic("%s: pcxl_alloc_range() Too many pages to map.\n",
+		      __FILE__);
+	}
+
+	dump_resmap();
+	panic("%s: pcxl_alloc_range() out of dma mapping resources\n",
+	      __FILE__);
+	
+resource_found:
+	
+	DBG_RES("pcxl_alloc_range() res_idx %d mask 0x%08lx res_hint: %d\n",
+		res_idx, mask, pcxl_res_hint);
+
+	pcxl_used_pages += pages_needed;
+	pcxl_used_bytes += ((pages_needed >> 3) ? (pages_needed >> 3) : 1);
+
+	spin_unlock_irqrestore(&pcxl_res_lock, flags);
+
+	dump_resmap();
+
+	/* 
+	** return the corresponding vaddr in the pcxl dma map
+	*/
+	return (pcxl_dma_start + (res_idx << (PAGE_SHIFT + 3)));
+}
+
+#define PCXL_FREE_MAPPINGS(idx, m, size) \
+		u##size *res_ptr = (u##size *)&(pcxl_res_map[(idx) + (((size >> 3) - 1) & (~((size >> 3) - 1)))]); \
+		/* BUG_ON((*res_ptr & m) != m); */ \
+		*res_ptr &= ~m;
+
+/*
+** clear bits in the pcxl resource map
+*/
+static void
+pcxl_free_range(unsigned long vaddr, size_t size)
+{
+	u_long mask, flags;
+	unsigned int res_idx = (vaddr - pcxl_dma_start) >> (PAGE_SHIFT + 3);
+	unsigned int pages_mapped = size >> PAGE_SHIFT;
+
+	mask = (u_long) -1L;
+ 	mask >>= BITS_PER_LONG - pages_mapped;
+
+	DBG_RES("pcxl_free_range() res_idx: %d size: %d pages_mapped %d mask 0x%08lx\n", 
+		res_idx, size, pages_mapped, mask);
+
+	spin_lock_irqsave(&pcxl_res_lock, flags);
+
+	if(pages_mapped <= 8) {
+		PCXL_FREE_MAPPINGS(res_idx, mask, 8);
+	} else if(pages_mapped <= 16) {
+		PCXL_FREE_MAPPINGS(res_idx, mask, 16);
+	} else if(pages_mapped <= 32) {
+		PCXL_FREE_MAPPINGS(res_idx, mask, 32);
+	} else {
+		panic("%s: pcxl_free_range() Too many pages to unmap.\n",
+		      __FILE__);
+	}
+	
+	pcxl_used_pages -= (pages_mapped ? pages_mapped : 1);
+	pcxl_used_bytes -= ((pages_mapped >> 3) ? (pages_mapped >> 3) : 1);
+
+	spin_unlock_irqrestore(&pcxl_res_lock, flags);
+
+	dump_resmap();
+}
+
+static int proc_pcxl_dma_show(struct seq_file *m, void *v)
+{
+#if 0
+	u_long i = 0;
+	unsigned long *res_ptr = (u_long *)pcxl_res_map;
+#endif
+	unsigned long total_pages = pcxl_res_size << 3;   /* 8 bits per byte */
+
+	seq_printf(m, "\nDMA Mapping Area size    : %d bytes (%ld pages)\n",
+		PCXL_DMA_MAP_SIZE, total_pages);
+
+	seq_printf(m, "Resource bitmap : %d bytes\n", pcxl_res_size);
+
+	seq_puts(m,  "     	  total:    free:    used:   % used:\n");
+	seq_printf(m, "blocks  %8d %8ld %8ld %8ld%%\n", pcxl_res_size,
+		pcxl_res_size - pcxl_used_bytes, pcxl_used_bytes,
+		(pcxl_used_bytes * 100) / pcxl_res_size);
+
+	seq_printf(m, "pages   %8ld %8ld %8ld %8ld%%\n", total_pages,
+		total_pages - pcxl_used_pages, pcxl_used_pages,
+		(pcxl_used_pages * 100 / total_pages));
+
+#if 0
+	seq_puts(m, "\nResource bitmap:");
+
+	for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) {
+		if ((i & 7) == 0)
+		    seq_puts(m,"\n   ");
+		seq_printf(m, "%s %08lx", buf, *res_ptr);
+	}
+#endif
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static int __init
+pcxl_dma_init(void)
+{
+	if (pcxl_dma_start == 0)
+		return 0;
+
+	pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
+	pcxl_res_hint = 0;
+	pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
+					    get_order(pcxl_res_size));
+	memset(pcxl_res_map, 0, pcxl_res_size);
+	proc_gsc_root = proc_mkdir("gsc", NULL);
+	if (!proc_gsc_root)
+    		printk(KERN_WARNING
+			"pcxl_dma_init: Unable to create gsc /proc dir entry\n");
+	else {
+		struct proc_dir_entry* ent;
+		ent = proc_create_single("pcxl_dma", 0, proc_gsc_root,
+				proc_pcxl_dma_show);
+		if (!ent)
+			printk(KERN_WARNING
+				"pci-dma.c: Unable to create pcxl_dma /proc entry.\n");
+	}
+	return 0;
+}
+
+__initcall(pcxl_dma_init);
+
+static void *pcxl_dma_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
+{
+	unsigned long vaddr;
+	unsigned long paddr;
+	int order;
+
+	order = get_order(size);
+	size = 1 << (order + PAGE_SHIFT);
+	vaddr = pcxl_alloc_range(size);
+	paddr = __get_free_pages(flag, order);
+	flush_kernel_dcache_range(paddr, size);
+	paddr = __pa(paddr);
+	map_uncached_pages(vaddr, size, paddr);
+	*dma_handle = (dma_addr_t) paddr;
+
+#if 0
+/* This probably isn't needed to support EISA cards.
+** ISA cards will certainly only support 24-bit DMA addressing.
+** Not clear if we can, want, or need to support ISA.
+*/
+	if (!dev || *dev->coherent_dma_mask < 0xffffffff)
+		gfp |= GFP_DMA;
+#endif
+	return (void *)vaddr;
+}
+
+static void *pcx_dma_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
+{
+	void *addr;
+
+	if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
+		return NULL;
+
+	addr = (void *)__get_free_pages(flag, get_order(size));
+	if (addr)
+		*dma_handle = (dma_addr_t)virt_to_phys(addr);
+
+	return addr;
+}
+
+void *arch_dma_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+{
+
+	if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl)
+		return pcxl_dma_alloc(dev, size, dma_handle, gfp, attrs);
+	else
+		return pcx_dma_alloc(dev, size, dma_handle, gfp, attrs);
+}
+
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
+		dma_addr_t dma_handle, unsigned long attrs)
+{
+	int order = get_order(size);
+
+	if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
+		size = 1 << (order + PAGE_SHIFT);
+		unmap_uncached_pages((unsigned long)vaddr, size);
+		pcxl_free_range((unsigned long)vaddr, size);
+
+		vaddr = __va(dma_handle);
+	}
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+		size_t size, enum dma_data_direction dir)
+{
+	flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
+}
+
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+		size_t size, enum dma_data_direction dir)
+{
+	flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
+}
+
+void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	flush_kernel_dcache_range((unsigned long)vaddr, size);
+}
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
new file mode 100644
index 0000000..ae684ac
--- /dev/null
+++ b/arch/parisc/kernel/pci.c
@@ -0,0 +1,279 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998 Ralf Baechle
+ * Copyright (C) 1999 SuSE GmbH
+ * Copyright (C) 1999-2001 Hewlett-Packard Company
+ * Copyright (C) 1999-2001 Grant Grundler
+ */
+#include <linux/eisa.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/superio.h>
+
+#define DEBUG_RESOURCES 0
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBGC(x...)	printk(KERN_DEBUG x)
+#else
+# define DBGC(x...)
+#endif
+
+
+#if DEBUG_RESOURCES
+#define DBG_RES(x...)	printk(KERN_DEBUG x)
+#else
+#define DBG_RES(x...)
+#endif
+
+/* To be used as: mdelay(pci_post_reset_delay);
+ *
+ * post_reset is the time the kernel should stall to prevent anyone from
+ * accessing the PCI bus once #RESET is de-asserted. 
+ * PCI spec somewhere says 1 second but with multi-PCI bus systems,
+ * this makes the boot time much longer than necessary.
+ * 20ms seems to work for all the HP PCI implementations to date.
+ *
+ * #define pci_post_reset_delay 50
+ */
+
+struct pci_port_ops *pci_port __read_mostly;
+struct pci_bios_ops *pci_bios __read_mostly;
+
+static int pci_hba_count __read_mostly;
+
+/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.  */
+#define PCI_HBA_MAX 32
+static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly;
+
+
+/********************************************************************
+**
+** I/O port space support
+**
+*********************************************************************/
+
+/* EISA port numbers and PCI port numbers share the same interface.  Some
+ * machines have both EISA and PCI adapters installed.  Rather than turn
+ * pci_port into an array, we reserve bus 0 for EISA and call the EISA
+ * routines if the access is to a port on bus 0.  We don't want to fix
+ * EISA and ISA drivers which assume port space is <= 0xffff.
+ */
+
+#ifdef CONFIG_EISA
+#define EISA_IN(size) if (EISA_bus && (b == 0)) return eisa_in##size(addr)
+#define EISA_OUT(size) if (EISA_bus && (b == 0)) return eisa_out##size(d, addr)
+#else
+#define EISA_IN(size)
+#define EISA_OUT(size)
+#endif
+
+#define PCI_PORT_IN(type, size) \
+u##size in##type (int addr) \
+{ \
+	int b = PCI_PORT_HBA(addr); \
+	EISA_IN(size); \
+	if (!parisc_pci_hba[b]) return (u##size) -1; \
+	return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
+} \
+EXPORT_SYMBOL(in##type);
+
+PCI_PORT_IN(b,  8)
+PCI_PORT_IN(w, 16)
+PCI_PORT_IN(l, 32)
+
+
+#define PCI_PORT_OUT(type, size) \
+void out##type (u##size d, int addr) \
+{ \
+	int b = PCI_PORT_HBA(addr); \
+	EISA_OUT(size); \
+	if (!parisc_pci_hba[b]) return; \
+	pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
+} \
+EXPORT_SYMBOL(out##type);
+
+PCI_PORT_OUT(b,  8)
+PCI_PORT_OUT(w, 16)
+PCI_PORT_OUT(l, 32)
+
+
+
+/*
+ * BIOS32 replacement.
+ */
+static int __init pcibios_init(void)
+{
+	if (!pci_bios)
+		return -1;
+
+	if (pci_bios->init) {
+		pci_bios->init();
+	} else {
+		printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
+	}
+
+	/* Set the CLS for PCI as early as possible. */
+	pci_cache_line_size = pci_dfl_cache_line_size;
+
+	return 0;
+}
+
+
+/* Called from pci_do_scan_bus() *after* walking a bus but before walking PPBs. */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+	if (pci_bios->fixup_bus) {
+		pci_bios->fixup_bus(bus);
+	} else {
+		printk(KERN_WARNING "pci_bios != NULL but fixup_bus() is!\n");
+	}
+}
+
+
+/*
+ * Called by pci_set_master() - a driver interface.
+ *
+ * Legacy PDC guarantees to set:
+ *	Map Memory BAR's into PA IO space.
+ *	Map Expansion ROM BAR into one common PA IO space per bus.
+ *	Map IO BAR's into PCI IO space.
+ *	Command (see below)
+ *	Cache Line Size
+ *	Latency Timer
+ *	Interrupt Line
+ *	PPB: secondary latency timer, io/mmio base/limit,
+ *		bus numbers, bridge control
+ *
+ */
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+
+	/* If someone already mucked with this, don't touch it. */
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat >= 16) return;
+
+	/*
+	** HP generally has fewer devices on the bus than other architectures.
+	** upper byte is PCI_LATENCY_TIMER.
+	*/
+	pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
+			      (0x80 << 8) | pci_cache_line_size);
+}
+
+/*
+ * pcibios_init_bridge() initializes cache line and default latency
+ * for pci controllers and pci-pci bridges
+ */
+void __ref pcibios_init_bridge(struct pci_dev *dev)
+{
+	unsigned short bridge_ctl, bridge_ctl_new;
+
+	/* We deal only with pci controllers and pci-pci bridges. */
+	if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	/* PCI-PCI bridge - set the cache line and default latency
+	 * (32) for primary and secondary buses.
+	 */
+	pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
+
+	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
+
+	bridge_ctl_new = bridge_ctl | PCI_BRIDGE_CTL_PARITY |
+		PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_MASTER_ABORT;
+	dev_info(&dev->dev, "Changing bridge control from 0x%08x to 0x%08x\n",
+		bridge_ctl, bridge_ctl_new);
+
+	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl_new);
+}
+
+/*
+ * pcibios align resources() is called every time generic PCI code
+ * wants to generate a new address. The process of looking for
+ * an available address, each candidate is first "aligned" and
+ * then checked if the resource is available until a match is found.
+ *
+ * Since we are just checking candidates, don't use any fields other
+ * than res->start.
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t alignment)
+{
+	resource_size_t mask, align, start = res->start;
+
+	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
+		pci_name(((struct pci_dev *) data)),
+		res->parent, res->start, res->end,
+		(int) res->flags, size, alignment);
+
+	/* If it's not IO, then it's gotta be MEM */
+	align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+
+	/* Align to largest of MIN or input size */
+	mask = max(alignment, align) - 1;
+	start += mask;
+	start &= ~mask;
+
+	return start;
+}
+
+/*
+ * A driver is enabling the device.  We make sure that all the appropriate
+ * bits are set to allow the device to operate as the driver is expecting.
+ * We enable the port IO and memory IO bits if the device has any BARs of
+ * that type, and we enable the PERR and SERR bits unconditionally.
+ * Drivers that do not need parity (eg graphics and possibly networking)
+ * can clear these bits if they want.
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int err;
+	u16 cmd, old_cmd;
+
+	err = pci_enable_resources(dev, mask);
+	if (err < 0)
+		return err;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+
+	cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+
+#if 0
+	/* If bridge/bus controller has FBB enabled, child must too. */
+	if (dev->bus->bridge_ctl & PCI_BRIDGE_CTL_FAST_BACK)
+		cmd |= PCI_COMMAND_FAST_BACK;
+#endif
+
+	if (cmd != old_cmd) {
+		dev_info(&dev->dev, "enabling SERR and PARITY (%04x -> %04x)\n",
+			old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+
+/* PA-RISC specific */
+void pcibios_register_hba(struct pci_hba_data *hba)
+{
+	if (pci_hba_count >= PCI_HBA_MAX) {
+		printk(KERN_ERR "PCI: Too many Host Bus Adapters\n");
+		return;
+	}
+
+	parisc_pci_hba[pci_hba_count] = hba;
+	hba->hba_num = pci_hba_count++;
+}
+
+subsys_initcall(pcibios_init);
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c
new file mode 100644
index 0000000..28e0748
--- /dev/null
+++ b/arch/parisc/kernel/pdc_chassis.c
@@ -0,0 +1,290 @@
+/* 
+ *    interfaces to Chassis Codes via PDC (firmware)
+ *
+ *    Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
+ *    Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License, version 2, as
+ *    published by the Free Software Foundation.
+ *
+ *    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
+ *
+ *    TODO: poll chassis warns, trigger (configurable) machine shutdown when
+ *    		needed.
+ *    	    Find out how to get Chassis warnings out of PAT boxes?
+ */
+
+#undef PDC_CHASSIS_DEBUG
+#ifdef PDC_CHASSIS_DEBUG
+#define DPRINTK(fmt, args...)	printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/cache.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/pdc_chassis.h>
+#include <asm/processor.h>
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
+
+#define PDC_CHASSIS_VER	"0.05"
+
+#ifdef CONFIG_PDC_CHASSIS
+static unsigned int pdc_chassis_enabled __read_mostly = 1;
+
+
+/**
+ * pdc_chassis_setup() - Enable/disable pdc_chassis code at boot time.
+ * @str configuration param: 0 to disable chassis log
+ * @return 1
+ */
+ 
+static int __init pdc_chassis_setup(char *str)
+{
+	/*panic_timeout = simple_strtoul(str, NULL, 0);*/
+	get_option(&str, &pdc_chassis_enabled);
+	return 1;
+}
+__setup("pdcchassis=", pdc_chassis_setup);
+
+
+/** 
+ * pdc_chassis_checkold() - Checks for old PDC_CHASSIS compatibility
+ * @pdc_chassis_old: 1 if old pdc chassis style
+ * 
+ * Currently, only E class and A180 are known to work with this.
+ * Inspired by Christoph Plattner
+ */
+#if 0
+static void __init pdc_chassis_checkold(void)
+{
+	switch(CPU_HVERSION) {
+		case 0x480:		/* E25 */
+		case 0x481:		/* E35 */
+		case 0x482:		/* E45 */
+		case 0x483:		/* E55 */
+		case 0x516:		/* A180 */
+			break;
+
+		default:
+			break;
+	}
+	DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
+}
+#endif
+
+/**
+ * pdc_chassis_panic_event() - Called by the panic handler.
+ *
+ * As soon as a panic occurs, we should inform the PDC.
+ */
+
+static int pdc_chassis_panic_event(struct notifier_block *this,
+		        unsigned long event, void *ptr)
+{
+	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+		return NOTIFY_DONE;
+}   
+
+
+static struct notifier_block pdc_chassis_panic_block = {
+	.notifier_call = pdc_chassis_panic_event,
+	.priority = INT_MAX,
+};
+
+
+/**
+ * parisc_reboot_event() - Called by the reboot handler.
+ *
+ * As soon as a reboot occurs, we should inform the PDC.
+ */
+
+static int pdc_chassis_reboot_event(struct notifier_block *this,
+		        unsigned long event, void *ptr)
+{
+	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
+		return NOTIFY_DONE;
+}   
+
+
+static struct notifier_block pdc_chassis_reboot_block = {
+	.notifier_call = pdc_chassis_reboot_event,
+	.priority = INT_MAX,
+};
+#endif /* CONFIG_PDC_CHASSIS */
+
+
+/**
+ * parisc_pdc_chassis_init() - Called at boot time.
+ */
+
+void __init parisc_pdc_chassis_init(void)
+{
+#ifdef CONFIG_PDC_CHASSIS
+	if (likely(pdc_chassis_enabled)) {
+		DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
+
+		/* Let see if we have something to handle... */
+		printk(KERN_INFO "Enabling %s chassis codes support v%s\n",
+				is_pdc_pat() ? "PDC_PAT" : "regular",
+				PDC_CHASSIS_VER);
+
+		/* initialize panic notifier chain */
+		atomic_notifier_chain_register(&panic_notifier_list,
+				&pdc_chassis_panic_block);
+
+		/* initialize reboot notifier chain */
+		register_reboot_notifier(&pdc_chassis_reboot_block);
+	}
+#endif /* CONFIG_PDC_CHASSIS */
+}
+
+
+/** 
+ * pdc_chassis_send_status() - Sends a predefined message to the chassis,
+ * and changes the front panel LEDs according to the new system state
+ * @retval: PDC call return value.
+ *
+ * Only machines with 64 bits PDC PAT and those reported in
+ * pdc_chassis_checkold() are supported atm.
+ * 
+ * returns 0 if no error, -1 if no supported PDC is present or invalid message,
+ * else returns the appropriate PDC error code.
+ * 
+ * For a list of predefined messages, see asm-parisc/pdc_chassis.h
+ */
+
+int pdc_chassis_send_status(int message)
+{
+	/* Maybe we should do that in an other way ? */
+	int retval = 0;
+#ifdef CONFIG_PDC_CHASSIS
+	if (likely(pdc_chassis_enabled)) {
+
+		DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
+
+#ifdef CONFIG_64BIT
+		if (is_pdc_pat()) {
+			switch(message) {
+				case PDC_CHASSIS_DIRECT_BSTART:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BSTART, PDC_CHASSIS_LSTATE_RUN_NORMAL);
+					break;
+
+				case PDC_CHASSIS_DIRECT_BCOMPLETE:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BCOMPLETE, PDC_CHASSIS_LSTATE_RUN_NORMAL);
+					break;
+
+				case PDC_CHASSIS_DIRECT_SHUTDOWN:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_SHUTDOWN, PDC_CHASSIS_LSTATE_NONOS);
+					break;
+
+				case PDC_CHASSIS_DIRECT_PANIC:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_PANIC, PDC_CHASSIS_LSTATE_RUN_CRASHREC);
+					break;
+
+				case PDC_CHASSIS_DIRECT_LPMC:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_LPMC, PDC_CHASSIS_LSTATE_RUN_SYSINT);
+					break;
+
+				case PDC_CHASSIS_DIRECT_HPMC:
+					retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_HPMC, PDC_CHASSIS_LSTATE_RUN_NCRIT);
+					break;
+
+				default:
+					retval = -1;
+			}
+		} else retval = -1;
+#else
+		if (1) {
+			switch (message) {
+				case PDC_CHASSIS_DIRECT_BSTART:
+					retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT));
+					break;
+
+				case PDC_CHASSIS_DIRECT_BCOMPLETE:
+					retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
+					break;
+
+				case PDC_CHASSIS_DIRECT_SHUTDOWN:
+					retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_SHUT));
+					break;
+
+				case PDC_CHASSIS_DIRECT_HPMC:
+				case PDC_CHASSIS_DIRECT_PANIC:
+					retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_FLT));
+					break;
+
+				case PDC_CHASSIS_DIRECT_LPMC:
+					retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_WARN));
+					break;
+
+				default:
+					retval = -1;
+			}
+		} else retval = -1;
+#endif /* CONFIG_64BIT */
+	}	/* if (pdc_chassis_enabled) */
+#endif /* CONFIG_PDC_CHASSIS */
+	return retval;
+}
+
+#ifdef CONFIG_PDC_CHASSIS_WARN
+#ifdef CONFIG_PROC_FS
+static int pdc_chassis_warn_show(struct seq_file *m, void *v)
+{
+	unsigned long warn;
+	u32 warnreg;
+
+	if (pdc_chassis_warn(&warn) != PDC_OK)
+		return -EIO;
+
+	warnreg = (warn & 0xFFFFFFFF);
+
+	if ((warnreg >> 24) & 0xFF)
+		seq_printf(m, "Chassis component failure! (eg fan or PSU): 0x%.2x\n",
+			   (warnreg >> 24) & 0xFF);
+
+	seq_printf(m, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
+	seq_printf(m, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
+	seq_printf(m, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
+	return 0;
+}
+
+static int __init pdc_chassis_create_procfs(void)
+{
+	unsigned long test;
+	int ret;
+
+	ret = pdc_chassis_warn(&test);
+	if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) {
+		/* seems that some boxes (eg L1000) do not implement this */
+		printk(KERN_INFO "Chassis warnings not supported.\n");
+		return 0;
+	}
+
+	printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n",
+			PDC_CHASSIS_VER);
+	proc_create_single("chassis", 0400, NULL, pdc_chassis_warn_show);
+	return 0;
+}
+
+__initcall(pdc_chassis_create_procfs);
+
+#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_PDC_CHASSIS_WARN */
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
new file mode 100644
index 0000000..c46bf29
--- /dev/null
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -0,0 +1,281 @@
+/* 
+ *    PDC Console support - ie use firmware to dump text via boot console
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2010 Guy Martin <gmsoft at tuxicoman.be>
+ *
+ *
+ *    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
+ */
+
+/*
+ *  The PDC console is a simple console, which can be used for debugging 
+ *  boot related problems on HP PA-RISC machines. It is also useful when no
+ *  other console works.
+ *
+ *  This code uses the ROM (=PDC) based functions to read and write characters
+ *  from and to PDC's boot path.
+ */
+
+/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. 
+ * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
+#define EARLY_BOOTUP_DEBUG
+
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/tty.h>
+#include <asm/page.h>		/* for PAGE0 */
+#include <asm/pdc.h>		/* for iodc_call() proto and friends */
+
+static DEFINE_SPINLOCK(pdc_console_lock);
+static struct console pdc_cons;
+
+static void pdc_console_write(struct console *co, const char *s, unsigned count)
+{
+	int i = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_console_lock, flags);
+	do {
+		i += pdc_iodc_print(s + i, count - i);
+	} while (i < count);
+	spin_unlock_irqrestore(&pdc_console_lock, flags);
+}
+
+int pdc_console_poll_key(struct console *co)
+{
+	int c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_console_lock, flags);
+	c = pdc_iodc_getc();
+	spin_unlock_irqrestore(&pdc_console_lock, flags);
+
+	return c;
+}
+
+static int pdc_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+#if defined(CONFIG_PDC_CONSOLE)
+#include <linux/vt_kern.h>
+#include <linux/tty_flip.h>
+
+#define PDC_CONS_POLL_DELAY (30 * HZ / 1000)
+
+static void pdc_console_poll(struct timer_list *unused);
+static DEFINE_TIMER(pdc_console_timer, pdc_console_poll);
+static struct tty_port tty_port;
+
+static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
+{
+	tty_port_tty_set(&tty_port, tty);
+	mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
+
+	return 0;
+}
+
+static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp)
+{
+	if (tty->count == 1) {
+		del_timer_sync(&pdc_console_timer);
+		tty_port_tty_set(&tty_port, NULL);
+	}
+}
+
+static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	pdc_console_write(NULL, buf, count);
+	return count;
+}
+
+static int pdc_console_tty_write_room(struct tty_struct *tty)
+{
+	return 32768; /* no limit, no buffer used */
+}
+
+static int pdc_console_tty_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0; /* no buffer */
+}
+
+static const struct tty_operations pdc_console_tty_ops = {
+	.open = pdc_console_tty_open,
+	.close = pdc_console_tty_close,
+	.write = pdc_console_tty_write,
+	.write_room = pdc_console_tty_write_room,
+	.chars_in_buffer = pdc_console_tty_chars_in_buffer,
+};
+
+static void pdc_console_poll(struct timer_list *unused)
+{
+	int data, count = 0;
+
+	while (1) {
+		data = pdc_console_poll_key(NULL);
+		if (data == -1)
+			break;
+		tty_insert_flip_char(&tty_port, data & 0xFF, TTY_NORMAL);
+		count ++;
+	}
+
+	if (count)
+		tty_flip_buffer_push(&tty_port);
+
+	if (pdc_cons.flags & CON_ENABLED)
+		mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
+}
+
+static struct tty_driver *pdc_console_tty_driver;
+
+static int __init pdc_console_tty_driver_init(void)
+{
+	int err;
+
+	/* Check if the console driver is still registered.
+	 * It is unregistered if the pdc console was not selected as the
+	 * primary console. */
+
+	struct console *tmp;
+
+	console_lock();
+	for_each_console(tmp)
+		if (tmp == &pdc_cons)
+			break;
+	console_unlock();
+
+	if (!tmp) {
+		printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
+	pdc_cons.flags &= ~CON_BOOT;
+
+	pdc_console_tty_driver = alloc_tty_driver(1);
+
+	if (!pdc_console_tty_driver)
+		return -ENOMEM;
+
+	tty_port_init(&tty_port);
+
+	pdc_console_tty_driver->driver_name = "pdc_cons";
+	pdc_console_tty_driver->name = "ttyB";
+	pdc_console_tty_driver->major = MUX_MAJOR;
+	pdc_console_tty_driver->minor_start = 0;
+	pdc_console_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
+	pdc_console_tty_driver->init_termios = tty_std_termios;
+	pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW |
+		TTY_DRIVER_RESET_TERMIOS;
+	tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops);
+	tty_port_link_device(&tty_port, pdc_console_tty_driver, 0);
+
+	err = tty_register_driver(pdc_console_tty_driver);
+	if (err) {
+		printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
+		tty_port_destroy(&tty_port);
+		return err;
+	}
+
+	return 0;
+}
+device_initcall(pdc_console_tty_driver_init);
+
+static struct tty_driver * pdc_console_device (struct console *c, int *index)
+{
+	*index = c->index;
+	return pdc_console_tty_driver;
+}
+#else
+#define pdc_console_device NULL
+#endif
+
+static struct console pdc_cons = {
+	.name =		"ttyB",
+	.write =	pdc_console_write,
+	.device =	pdc_console_device,
+	.setup =	pdc_console_setup,
+	.flags =	CON_BOOT | CON_PRINTBUFFER,
+	.index =	-1,
+};
+
+static int pdc_console_initialized;
+
+static void pdc_console_init_force(void)
+{
+	if (pdc_console_initialized)
+		return;
+	++pdc_console_initialized;
+	
+	/* If the console is duplex then copy the COUT parameters to CIN. */
+	if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
+		memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
+
+	/* register the pdc console */
+	register_console(&pdc_cons);
+}
+
+void __init pdc_console_init(void)
+{
+#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE)
+	pdc_console_init_force();
+#endif
+#ifdef EARLY_BOOTUP_DEBUG
+	printk(KERN_INFO "Initialized PDC Console for debugging.\n");
+#endif
+}
+
+
+/*
+ * Used for emergencies. Currently only used if an HPMC occurs. If an
+ * HPMC occurs, it is possible that the current console may not be
+ * properly initialised after the PDC IO reset. This routine unregisters
+ * all of the current consoles, reinitializes the pdc console and
+ * registers it.
+ */
+
+void pdc_console_restart(void)
+{
+	struct console *console;
+
+	if (pdc_console_initialized)
+		return;
+
+	/* If we've already seen the output, don't bother to print it again */
+	if (console_drivers != NULL)
+		pdc_cons.flags &= ~CON_PRINTBUFFER;
+
+	while ((console = console_drivers) != NULL)
+		unregister_console(console_drivers);
+
+	/* force registering the pdc console */
+	pdc_console_init_force();
+}
diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c
new file mode 100644
index 0000000..36434d4
--- /dev/null
+++ b/arch/parisc/kernel/pdt.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *    Page Deallocation Table (PDT) support
+ *
+ *    The Page Deallocation Table (PDT) is maintained by firmware and holds a
+ *    list of memory addresses in which memory errors were detected.
+ *    The list contains both single-bit (correctable) and double-bit
+ *    (uncorrectable) errors.
+ *
+ *    Copyright 2017 by Helge Deller <deller@gmx.de>
+ *
+ *    possible future enhancements:
+ *    - add userspace interface via procfs or sysfs to clear PDT
+ */
+
+#include <linux/memblock.h>
+#include <linux/seq_file.h>
+#include <linux/kthread.h>
+#include <linux/initrd.h>
+
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+
+enum pdt_access_type {
+	PDT_NONE,
+	PDT_PDC,
+	PDT_PAT_NEW,
+	PDT_PAT_CELL
+};
+
+static enum pdt_access_type pdt_type;
+
+/* PDT poll interval: 1 minute if errors, 5 minutes if everything OK. */
+#define PDT_POLL_INTERVAL_DEFAULT	(5*60*HZ)
+#define PDT_POLL_INTERVAL_SHORT		(1*60*HZ)
+static unsigned long pdt_poll_interval = PDT_POLL_INTERVAL_DEFAULT;
+
+/* global PDT status information */
+static struct pdc_mem_retinfo pdt_status;
+
+#define MAX_PDT_TABLE_SIZE	PAGE_SIZE
+#define MAX_PDT_ENTRIES		(MAX_PDT_TABLE_SIZE / sizeof(unsigned long))
+static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss;
+
+/*
+ * Constants for the pdt_entry format:
+ * A pdt_entry holds the physical address in bits 0-57, bits 58-61 are
+ * reserved, bit 62 is the perm bit and bit 63 is the error_type bit.
+ * The perm bit indicates whether the error have been verified as a permanent
+ * error (value of 1) or has not been verified, and may be transient (value
+ * of 0). The error_type bit indicates whether the error is a single bit error
+ * (value of 1) or a multiple bit error.
+ * On non-PAT machines phys_addr is encoded in bits 0-59 and error_type in bit
+ * 63. Those machines don't provide the perm bit.
+ */
+
+#define PDT_ADDR_PHYS_MASK	(pdt_type != PDT_PDC ? ~0x3f : ~0x0f)
+#define PDT_ADDR_PERM_ERR	(pdt_type != PDT_PDC ? 2UL : 0UL)
+#define PDT_ADDR_SINGLE_ERR	1UL
+
+/* report PDT entries via /proc/meminfo */
+void arch_report_meminfo(struct seq_file *m)
+{
+	if (pdt_type == PDT_NONE)
+		return;
+
+	seq_printf(m, "PDT_max_entries: %7lu\n",
+			pdt_status.pdt_size);
+	seq_printf(m, "PDT_cur_entries: %7lu\n",
+			pdt_status.pdt_entries);
+}
+
+static int get_info_pat_new(void)
+{
+	struct pdc_pat_mem_retinfo pat_rinfo;
+	int ret;
+
+	/* newer PAT machines like C8000 report info for all cells */
+	if (is_pdc_pat())
+		ret = pdc_pat_mem_pdt_info(&pat_rinfo);
+	else
+		return PDC_BAD_PROC;
+
+	pdt_status.pdt_size = pat_rinfo.max_pdt_entries;
+	pdt_status.pdt_entries = pat_rinfo.current_pdt_entries;
+	pdt_status.pdt_status = 0;
+	pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc;
+	pdt_status.good_mem = pat_rinfo.good_mem;
+
+	return ret;
+}
+
+static int get_info_pat_cell(void)
+{
+	struct pdc_pat_mem_cell_pdt_retinfo cell_rinfo;
+	int ret;
+
+	/* older PAT machines like rp5470 report cell info only */
+	if (is_pdc_pat())
+		ret = pdc_pat_mem_pdt_cell_info(&cell_rinfo, parisc_cell_num);
+	else
+		return PDC_BAD_PROC;
+
+	pdt_status.pdt_size = cell_rinfo.max_pdt_entries;
+	pdt_status.pdt_entries = cell_rinfo.current_pdt_entries;
+	pdt_status.pdt_status = 0;
+	pdt_status.first_dbe_loc = cell_rinfo.first_dbe_loc;
+	pdt_status.good_mem = cell_rinfo.good_mem;
+
+	return ret;
+}
+
+static void report_mem_err(unsigned long pde)
+{
+	struct pdc_pat_mem_phys_mem_location loc;
+	unsigned long addr;
+	char dimm_txt[32];
+
+	addr = pde & PDT_ADDR_PHYS_MASK;
+
+	/* show DIMM slot description on PAT machines */
+	if (is_pdc_pat()) {
+		pdc_pat_mem_get_dimm_phys_location(&loc, addr);
+		sprintf(dimm_txt, "DIMM slot %02x, ", loc.dimm_slot);
+	} else
+		dimm_txt[0] = 0;
+
+	pr_warn("PDT: BAD MEMORY at 0x%08lx, %s%s%s-bit error.\n",
+		addr, dimm_txt,
+		pde & PDT_ADDR_PERM_ERR ? "permanent ":"",
+		pde & PDT_ADDR_SINGLE_ERR ? "single":"multi");
+}
+
+
+/*
+ * pdc_pdt_init()
+ *
+ * Initialize kernel PDT structures, read initial PDT table from firmware,
+ * report all current PDT entries and mark bad memory with memblock_reserve()
+ * to avoid that the kernel will use broken memory areas.
+ *
+ */
+void __init pdc_pdt_init(void)
+{
+	int ret, i;
+	unsigned long entries;
+	struct pdc_mem_read_pdt pdt_read_ret;
+
+	pdt_type = PDT_PAT_NEW;
+	ret = get_info_pat_new();
+
+	if (ret != PDC_OK) {
+		pdt_type = PDT_PAT_CELL;
+		ret = get_info_pat_cell();
+	}
+
+	if (ret != PDC_OK) {
+		pdt_type = PDT_PDC;
+		/* non-PAT machines provide the standard PDC call */
+		ret = pdc_mem_pdt_info(&pdt_status);
+	}
+
+	if (ret != PDC_OK) {
+		pdt_type = PDT_NONE;
+		pr_info("PDT: Firmware does not provide any page deallocation"
+			" information.\n");
+		return;
+	}
+
+	entries = pdt_status.pdt_entries;
+	if (WARN_ON(entries > MAX_PDT_ENTRIES))
+		entries = pdt_status.pdt_entries = MAX_PDT_ENTRIES;
+
+	pr_info("PDT: type %s, size %lu, entries %lu, status %lu, dbe_loc 0x%lx,"
+		" good_mem %lu MB\n",
+			pdt_type == PDT_PDC ? __stringify(PDT_PDC) :
+			pdt_type == PDT_PAT_CELL ? __stringify(PDT_PAT_CELL)
+						 : __stringify(PDT_PAT_NEW),
+			pdt_status.pdt_size, pdt_status.pdt_entries,
+			pdt_status.pdt_status, pdt_status.first_dbe_loc,
+			pdt_status.good_mem / 1024 / 1024);
+
+	if (entries == 0) {
+		pr_info("PDT: Firmware reports all memory OK.\n");
+		return;
+	}
+
+	if (pdt_status.first_dbe_loc &&
+		pdt_status.first_dbe_loc <= __pa((unsigned long)&_end))
+		pr_crit("CRITICAL: Bad memory inside kernel image memory area!\n");
+
+	pr_warn("PDT: Firmware reports %lu entries of faulty memory:\n",
+		entries);
+
+	if (pdt_type == PDT_PDC)
+		ret = pdc_mem_pdt_read_entries(&pdt_read_ret, pdt_entry);
+	else {
+#ifdef CONFIG_64BIT
+		struct pdc_pat_mem_read_pd_retinfo pat_pret;
+
+		if (pdt_type == PDT_PAT_CELL)
+			ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
+				MAX_PDT_ENTRIES);
+		else
+			ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry,
+				MAX_PDT_TABLE_SIZE, 0);
+#else
+		ret = PDC_BAD_PROC;
+#endif
+	}
+
+	if (ret != PDC_OK) {
+		pdt_type = PDT_NONE;
+		pr_warn("PDT: Get PDT entries failed with %d\n", ret);
+		return;
+	}
+
+	for (i = 0; i < pdt_status.pdt_entries; i++) {
+		unsigned long addr;
+
+		report_mem_err(pdt_entry[i]);
+
+		addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK;
+		if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) &&
+			addr >= initrd_start && addr < initrd_end)
+			pr_crit("CRITICAL: initrd possibly broken "
+				"due to bad memory!\n");
+
+		/* mark memory page bad */
+		memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
+	}
+}
+
+
+/*
+ * This is the PDT kernel thread main loop.
+ */
+
+static int pdt_mainloop(void *unused)
+{
+	struct pdc_mem_read_pdt pdt_read_ret;
+	struct pdc_pat_mem_read_pd_retinfo pat_pret __maybe_unused;
+	unsigned long old_num_entries;
+	unsigned long *bad_mem_ptr;
+	int num, ret;
+
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		old_num_entries = pdt_status.pdt_entries;
+
+		schedule_timeout(pdt_poll_interval);
+		if (kthread_should_stop())
+			break;
+
+		/* Do we have new PDT entries? */
+		switch (pdt_type) {
+		case PDT_PAT_NEW:
+			ret = get_info_pat_new();
+			break;
+		case PDT_PAT_CELL:
+			ret = get_info_pat_cell();
+			break;
+		default:
+			ret = pdc_mem_pdt_info(&pdt_status);
+			break;
+		}
+
+		if (ret != PDC_OK) {
+			pr_warn("PDT: unexpected failure %d\n", ret);
+			return -EINVAL;
+		}
+
+		/* if no new PDT entries, just wait again */
+		num = pdt_status.pdt_entries - old_num_entries;
+		if (num <= 0)
+			continue;
+
+		/* decrease poll interval in case we found memory errors */
+		if (pdt_status.pdt_entries &&
+			pdt_poll_interval == PDT_POLL_INTERVAL_DEFAULT)
+			pdt_poll_interval = PDT_POLL_INTERVAL_SHORT;
+
+		/* limit entries to get */
+		if (num > MAX_PDT_ENTRIES) {
+			num = MAX_PDT_ENTRIES;
+			pdt_status.pdt_entries = old_num_entries + num;
+		}
+
+		/* get new entries */
+		switch (pdt_type) {
+#ifdef CONFIG_64BIT
+		case PDT_PAT_CELL:
+			if (pdt_status.pdt_entries > MAX_PDT_ENTRIES) {
+				pr_crit("PDT: too many entries.\n");
+				return -ENOMEM;
+			}
+			ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
+				MAX_PDT_ENTRIES);
+			bad_mem_ptr = &pdt_entry[old_num_entries];
+			break;
+		case PDT_PAT_NEW:
+			ret = pdc_pat_mem_read_pd_pdt(&pat_pret,
+				pdt_entry,
+				num * sizeof(unsigned long),
+				old_num_entries * sizeof(unsigned long));
+			bad_mem_ptr = &pdt_entry[0];
+			break;
+#endif
+		default:
+			ret = pdc_mem_pdt_read_entries(&pdt_read_ret,
+				pdt_entry);
+			bad_mem_ptr = &pdt_entry[old_num_entries];
+			break;
+		}
+
+		/* report and mark memory broken */
+		while (num--) {
+			unsigned long pde = *bad_mem_ptr++;
+
+			report_mem_err(pde);
+
+#ifdef CONFIG_MEMORY_FAILURE
+			if ((pde & PDT_ADDR_PERM_ERR) ||
+			    ((pde & PDT_ADDR_SINGLE_ERR) == 0))
+				memory_failure(pde >> PAGE_SHIFT, 0);
+			else
+				soft_offline_page(
+					pfn_to_page(pde >> PAGE_SHIFT), 0);
+#else
+			pr_crit("PDT: memory error at 0x%lx ignored.\n"
+				"Rebuild kernel with CONFIG_MEMORY_FAILURE=y "
+				"for real handling.\n",
+				pde & PDT_ADDR_PHYS_MASK);
+#endif
+
+		}
+	}
+
+	return 0;
+}
+
+
+static int __init pdt_initcall(void)
+{
+	struct task_struct *kpdtd_task;
+
+	if (pdt_type == PDT_NONE)
+		return -ENODEV;
+
+	kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd");
+	if (IS_ERR(kpdtd_task))
+		return PTR_ERR(kpdtd_task);
+
+	wake_up_process(kpdtd_task);
+
+	return 0;
+}
+
+late_initcall(pdt_initcall);
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
new file mode 100644
index 0000000..0813359
--- /dev/null
+++ b/arch/parisc/kernel/perf.c
@@ -0,0 +1,851 @@
+/*
+ *  Parisc performance counters
+ *  Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ *
+ *  This code is derived, with permission, from HP/UX sources.
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  Edited comment from original sources:
+ *
+ *  This driver programs the PCX-U/PCX-W performance counters
+ *  on the PA-RISC 2.0 chips.  The driver keeps all images now
+ *  internally to the kernel to hopefully eliminate the possibility
+ *  of a bad image halting the CPU.  Also, there are different
+ *  images for the PCX-W and later chips vs the PCX-U chips.
+ *
+ *  Only 1 process is allowed to access the driver at any time,
+ *  so the only protection that is needed is at open and close.
+ *  A variable "perf_enabled" is used to hold the state of the
+ *  driver.  The spinlock "perf_lock" is used to protect the
+ *  modification of the state during open/close operations so
+ *  multiple processes don't get into the driver simultaneously.
+ *
+ *  This driver accesses the processor directly vs going through
+ *  the PDC INTRIGUE calls.  This is done to eliminate bugs introduced
+ *  in various PDC revisions.  The code is much more maintainable
+ *  and reliable this way vs having to debug on every version of PDC
+ *  on every box.
+ */
+
+#include <linux/capability.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+
+#include <linux/uaccess.h>
+#include <asm/perf.h>
+#include <asm/parisc-device.h>
+#include <asm/processor.h>
+#include <asm/runway.h>
+#include <asm/io.h>		/* for __raw_read() */
+
+#include "perf_images.h"
+
+#define MAX_RDR_WORDS	24
+#define PERF_VERSION	2	/* derived from hpux's PI v2 interface */
+
+/* definition of RDR regs */
+struct rdr_tbl_ent {
+	uint16_t	width;
+	uint8_t		num_words;
+	uint8_t		write_control;
+};
+
+static int perf_processor_interface __read_mostly = UNKNOWN_INTF;
+static int perf_enabled __read_mostly;
+static DEFINE_SPINLOCK(perf_lock);
+struct parisc_device *cpu_device __read_mostly;
+
+/* RDRs to write for PCX-W */
+static const int perf_rdrs_W[] =
+	{ 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
+
+/* RDRs to write for PCX-U */
+static const int perf_rdrs_U[] =
+	{ 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
+
+/* RDR register descriptions for PCX-W */
+static const struct rdr_tbl_ent perf_rdr_tbl_W[] = {
+	{ 19,	1,	8 },   /* RDR 0 */
+	{ 16,	1,	16 },  /* RDR 1 */
+	{ 72,	2,	0 },   /* RDR 2 */
+	{ 81,	2,	0 },   /* RDR 3 */
+	{ 328,	6,	0 },   /* RDR 4 */
+	{ 160,	3,	0 },   /* RDR 5 */
+	{ 336,	6,	0 },   /* RDR 6 */
+	{ 164,	3,	0 },   /* RDR 7 */
+	{ 0,	0,	0 },   /* RDR 8 */
+	{ 35,	1,	0 },   /* RDR 9 */
+	{ 6,	1,	0 },   /* RDR 10 */
+	{ 18,	1,	0 },   /* RDR 11 */
+	{ 13,	1,	0 },   /* RDR 12 */
+	{ 8,	1,	0 },   /* RDR 13 */
+	{ 8,	1,	0 },   /* RDR 14 */
+	{ 8,	1,	0 },   /* RDR 15 */
+	{ 1530,	24,	0 },   /* RDR 16 */
+	{ 16,	1,	0 },   /* RDR 17 */
+	{ 4,	1,	0 },   /* RDR 18 */
+	{ 0,	0,	0 },   /* RDR 19 */
+	{ 152,	3,	24 },  /* RDR 20 */
+	{ 152,	3,	24 },  /* RDR 21 */
+	{ 233,	4,	48 },  /* RDR 22 */
+	{ 233,	4,	48 },  /* RDR 23 */
+	{ 71,	2,	0 },   /* RDR 24 */
+	{ 71,	2,	0 },   /* RDR 25 */
+	{ 11,	1,	0 },   /* RDR 26 */
+	{ 18,	1,	0 },   /* RDR 27 */
+	{ 128,	2,	0 },   /* RDR 28 */
+	{ 0,	0,	0 },   /* RDR 29 */
+	{ 16,	1,	0 },   /* RDR 30 */
+	{ 16,	1,	0 },   /* RDR 31 */
+};
+
+/* RDR register descriptions for PCX-U */
+static const struct rdr_tbl_ent perf_rdr_tbl_U[] = {
+	{ 19,	1,	8 },              /* RDR 0 */
+	{ 32,	1,	16 },             /* RDR 1 */
+	{ 20,	1,	0 },              /* RDR 2 */
+	{ 0,	0,	0 },              /* RDR 3 */
+	{ 344,	6,	0 },              /* RDR 4 */
+	{ 176,	3,	0 },              /* RDR 5 */
+	{ 336,	6,	0 },              /* RDR 6 */
+	{ 0,	0,	0 },              /* RDR 7 */
+	{ 0,	0,	0 },              /* RDR 8 */
+	{ 0,	0,	0 },              /* RDR 9 */
+	{ 28,	1,	0 },              /* RDR 10 */
+	{ 33,	1,	0 },              /* RDR 11 */
+	{ 0,	0,	0 },              /* RDR 12 */
+	{ 230,	4,	0 },              /* RDR 13 */
+	{ 32,	1,	0 },              /* RDR 14 */
+	{ 128,	2,	0 },              /* RDR 15 */
+	{ 1494,	24,	0 },              /* RDR 16 */
+	{ 18,	1,	0 },              /* RDR 17 */
+	{ 4,	1,	0 },              /* RDR 18 */
+	{ 0,	0,	0 },              /* RDR 19 */
+	{ 158,	3,	24 },             /* RDR 20 */
+	{ 158,	3,	24 },             /* RDR 21 */
+	{ 194,	4,	48 },             /* RDR 22 */
+	{ 194,	4,	48 },             /* RDR 23 */
+	{ 71,	2,	0 },              /* RDR 24 */
+	{ 71,	2,	0 },              /* RDR 25 */
+	{ 28,	1,	0 },              /* RDR 26 */
+	{ 33,	1,	0 },              /* RDR 27 */
+	{ 88,	2,	0 },              /* RDR 28 */
+	{ 32,	1,	0 },              /* RDR 29 */
+	{ 24,	1,	0 },              /* RDR 30 */
+	{ 16,	1,	0 },              /* RDR 31 */
+};
+
+/*
+ * A non-zero write_control in the above tables is a byte offset into
+ * this array.
+ */
+static const uint64_t perf_bitmasks[] = {
+	0x0000000000000000ul,     /* first dbl word must be zero */
+	0xfdffe00000000000ul,     /* RDR0 bitmask */
+	0x003f000000000000ul,     /* RDR1 bitmask */
+	0x00fffffffffffffful,     /* RDR20-RDR21 bitmask (152 bits) */
+	0xfffffffffffffffful,
+	0xfffffffc00000000ul,
+	0xfffffffffffffffful,     /* RDR22-RDR23 bitmask (233 bits) */
+	0xfffffffffffffffful,
+	0xfffffffffffffffcul,
+	0xff00000000000000ul
+};
+
+/*
+ * Write control bitmasks for Pa-8700 processor given
+ * some things have changed slightly.
+ */
+static const uint64_t perf_bitmasks_piranha[] = {
+	0x0000000000000000ul,     /* first dbl word must be zero */
+	0xfdffe00000000000ul,     /* RDR0 bitmask */
+	0x003f000000000000ul,     /* RDR1 bitmask */
+	0x00fffffffffffffful,     /* RDR20-RDR21 bitmask (158 bits) */
+	0xfffffffffffffffful,
+	0xfffffffc00000000ul,
+	0xfffffffffffffffful,     /* RDR22-RDR23 bitmask (210 bits) */
+	0xfffffffffffffffful,
+	0xfffffffffffffffful,
+	0xfffc000000000000ul
+};
+
+static const uint64_t *bitmask_array;   /* array of bitmasks to use */
+
+/******************************************************************************
+ * Function Prototypes
+ *****************************************************************************/
+static int perf_config(uint32_t *image_ptr);
+static int perf_release(struct inode *inode, struct file *file);
+static int perf_open(struct inode *inode, struct file *file);
+static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
+static ssize_t perf_write(struct file *file, const char __user *buf,
+	size_t count, loff_t *ppos);
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+static void perf_start_counters(void);
+static int perf_stop_counters(uint32_t *raddr);
+static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
+static int perf_rdr_read_ubuf(uint32_t	rdr_num, uint64_t *buffer);
+static int perf_rdr_clear(uint32_t rdr_num);
+static int perf_write_image(uint64_t *memaddr);
+static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer);
+
+/* External Assembly Routines */
+extern uint64_t perf_rdr_shift_in_W (uint32_t rdr_num, uint16_t width);
+extern uint64_t perf_rdr_shift_in_U (uint32_t rdr_num, uint16_t width);
+extern void perf_rdr_shift_out_W (uint32_t rdr_num, uint64_t buffer);
+extern void perf_rdr_shift_out_U (uint32_t rdr_num, uint64_t buffer);
+extern void perf_intrigue_enable_perf_counters (void);
+extern void perf_intrigue_disable_perf_counters (void);
+
+/******************************************************************************
+ * Function Definitions
+ *****************************************************************************/
+
+
+/*
+ * configure:
+ *
+ * Configure the cpu with a given data image.  First turn off the counters,
+ * then download the image, then turn the counters back on.
+ */
+static int perf_config(uint32_t *image_ptr)
+{
+	long error;
+	uint32_t raddr[4];
+
+	/* Stop the counters*/
+	error = perf_stop_counters(raddr);
+	if (error != 0) {
+		printk("perf_config: perf_stop_counters = %ld\n", error);
+		return -EINVAL;
+	}
+
+printk("Preparing to write image\n");
+	/* Write the image to the chip */
+	error = perf_write_image((uint64_t *)image_ptr);
+	if (error != 0) {
+		printk("perf_config: DOWNLOAD = %ld\n", error);
+		return -EINVAL;
+	}
+
+printk("Preparing to start counters\n");
+
+	/* Start the counters */
+	perf_start_counters();
+
+	return sizeof(uint32_t);
+}
+
+/*
+ * Open the device and initialize all of its memory.  The device is only
+ * opened once, but can be "queried" by multiple processes that know its
+ * file descriptor.
+ */
+static int perf_open(struct inode *inode, struct file *file)
+{
+	spin_lock(&perf_lock);
+	if (perf_enabled) {
+		spin_unlock(&perf_lock);
+		return -EBUSY;
+	}
+	perf_enabled = 1;
+ 	spin_unlock(&perf_lock);
+
+	return 0;
+}
+
+/*
+ * Close the device.
+ */
+static int perf_release(struct inode *inode, struct file *file)
+{
+	spin_lock(&perf_lock);
+	perf_enabled = 0;
+	spin_unlock(&perf_lock);
+
+	return 0;
+}
+
+/*
+ * Read does nothing for this driver
+ */
+static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
+{
+	return 0;
+}
+
+/*
+ * write:
+ *
+ * This routine downloads the image to the chip.  It must be
+ * called on the processor that the download should happen
+ * on.
+ */
+static ssize_t perf_write(struct file *file, const char __user *buf,
+	size_t count, loff_t *ppos)
+{
+	size_t image_size;
+	uint32_t image_type;
+	uint32_t interface_type;
+	uint32_t test;
+
+	if (perf_processor_interface == ONYX_INTF)
+		image_size = PCXU_IMAGE_SIZE;
+	else if (perf_processor_interface == CUDA_INTF)
+		image_size = PCXW_IMAGE_SIZE;
+	else
+		return -EFAULT;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (count != sizeof(uint32_t))
+		return -EIO;
+
+	if (copy_from_user(&image_type, buf, sizeof(uint32_t)))
+		return -EFAULT;
+
+	/* Get the interface type and test type */
+   	interface_type = (image_type >> 16) & 0xffff;
+	test           = (image_type & 0xffff);
+
+	/* Make sure everything makes sense */
+
+	/* First check the machine type is correct for
+	   the requested image */
+	if (((perf_processor_interface == CUDA_INTF) &&
+			(interface_type != CUDA_INTF)) ||
+		((perf_processor_interface == ONYX_INTF) &&
+			(interface_type != ONYX_INTF)))
+		return -EINVAL;
+
+	/* Next check to make sure the requested image
+	   is valid */
+	if (((interface_type == CUDA_INTF) &&
+		       (test >= MAX_CUDA_IMAGES)) ||
+	    ((interface_type == ONYX_INTF) &&
+		       (test >= MAX_ONYX_IMAGES)))
+		return -EINVAL;
+
+	/* Copy the image into the processor */
+	if (interface_type == CUDA_INTF)
+		return perf_config(cuda_images[test]);
+	else
+		return perf_config(onyx_images[test]);
+
+	return count;
+}
+
+/*
+ * Patch the images that need to know the IVA addresses.
+ */
+static void perf_patch_images(void)
+{
+#if 0 /* FIXME!! */
+/*
+ * NOTE:  this routine is VERY specific to the current TLB image.
+ * If the image is changed, this routine might also need to be changed.
+ */
+	extern void $i_itlb_miss_2_0();
+	extern void $i_dtlb_miss_2_0();
+	extern void PA2_0_iva();
+
+	/*
+	 * We can only use the lower 32-bits, the upper 32-bits should be 0
+	 * anyway given this is in the kernel
+	 */
+	uint32_t itlb_addr  = (uint32_t)&($i_itlb_miss_2_0);
+	uint32_t dtlb_addr  = (uint32_t)&($i_dtlb_miss_2_0);
+	uint32_t IVAaddress = (uint32_t)&PA2_0_iva;
+
+	if (perf_processor_interface == ONYX_INTF) {
+		/* clear last 2 bytes */
+		onyx_images[TLBMISS][15] &= 0xffffff00;
+		/* set 2 bytes */
+		onyx_images[TLBMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[TLBMISS][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[TLBMISS][17] = itlb_addr;
+
+		/* clear last 2 bytes */
+		onyx_images[TLBHANDMISS][15] &= 0xffffff00;
+		/* set 2 bytes */
+		onyx_images[TLBHANDMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[TLBHANDMISS][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[TLBHANDMISS][17] = itlb_addr;
+
+		/* clear last 2 bytes */
+		onyx_images[BIG_CPI][15] &= 0xffffff00;
+		/* set 2 bytes */
+		onyx_images[BIG_CPI][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[BIG_CPI][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[BIG_CPI][17] = itlb_addr;
+
+	    onyx_images[PANIC][15] &= 0xffffff00;  /* clear last 2 bytes */
+	 	onyx_images[PANIC][15] |= (0x000000ff&((IVAaddress) >> 24)); /* set 2 bytes */
+		onyx_images[PANIC][16] = (IVAaddress << 8)&0xffffff00;
+
+
+	} else if (perf_processor_interface == CUDA_INTF) {
+		/* Cuda interface */
+		cuda_images[TLBMISS][16] =
+			(cuda_images[TLBMISS][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[TLBMISS][17] =
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[TLBMISS][18] = (itlb_addr << 16)&0xffff0000;
+
+		cuda_images[TLBHANDMISS][16] =
+			(cuda_images[TLBHANDMISS][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[TLBHANDMISS][17] =
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[TLBHANDMISS][18] = (itlb_addr << 16)&0xffff0000;
+
+		cuda_images[BIG_CPI][16] =
+			(cuda_images[BIG_CPI][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[BIG_CPI][17] =
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[BIG_CPI][18] = (itlb_addr << 16)&0xffff0000;
+	} else {
+		/* Unknown type */
+	}
+#endif
+}
+
+
+/*
+ * ioctl routine
+ * All routines effect the processor that they are executed on.  Thus you
+ * must be running on the processor that you wish to change.
+ */
+
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long error_start;
+	uint32_t raddr[4];
+	int error = 0;
+
+	switch (cmd) {
+
+	    case PA_PERF_ON:
+			/* Start the counters */
+			perf_start_counters();
+			break;
+
+	    case PA_PERF_OFF:
+			error_start = perf_stop_counters(raddr);
+			if (error_start != 0) {
+				printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
+				error = -EFAULT;
+				break;
+			}
+
+			/* copy out the Counters */
+			if (copy_to_user((void __user *)arg, raddr,
+					sizeof (raddr)) != 0) {
+				error =  -EFAULT;
+				break;
+			}
+			break;
+
+	    case PA_PERF_VERSION:
+  	  		/* Return the version # */
+			error = put_user(PERF_VERSION, (int *)arg);
+			break;
+
+	    default:
+  	 		error = -ENOTTY;
+	}
+
+	return error;
+}
+
+static const struct file_operations perf_fops = {
+	.llseek = no_llseek,
+	.read = perf_read,
+	.write = perf_write,
+	.unlocked_ioctl = perf_ioctl,
+	.compat_ioctl = perf_ioctl,
+	.open = perf_open,
+	.release = perf_release
+};
+
+static struct miscdevice perf_dev = {
+	MISC_DYNAMIC_MINOR,
+	PA_PERF_DEV,
+	&perf_fops
+};
+
+/*
+ * Initialize the module
+ */
+static int __init perf_init(void)
+{
+	int ret;
+
+	/* Determine correct processor interface to use */
+	bitmask_array = perf_bitmasks;
+
+	if (boot_cpu_data.cpu_type == pcxu ||
+	    boot_cpu_data.cpu_type == pcxu_) {
+		perf_processor_interface = ONYX_INTF;
+	} else if (boot_cpu_data.cpu_type == pcxw ||
+		 boot_cpu_data.cpu_type == pcxw_ ||
+		 boot_cpu_data.cpu_type == pcxw2 ||
+		 boot_cpu_data.cpu_type == mako ||
+		 boot_cpu_data.cpu_type == mako2) {
+		perf_processor_interface = CUDA_INTF;
+		if (boot_cpu_data.cpu_type == pcxw2 ||
+		    boot_cpu_data.cpu_type == mako ||
+		    boot_cpu_data.cpu_type == mako2)
+			bitmask_array = perf_bitmasks_piranha;
+	} else {
+		perf_processor_interface = UNKNOWN_INTF;
+		printk("Performance monitoring counters not supported on this processor\n");
+		return -ENODEV;
+	}
+
+	ret = misc_register(&perf_dev);
+	if (ret) {
+		printk(KERN_ERR "Performance monitoring counters: "
+			"cannot register misc device.\n");
+		return ret;
+	}
+
+	/* Patch the images to match the system */
+    	perf_patch_images();
+
+	/* TODO: this only lets us access the first cpu.. what to do for SMP? */
+	cpu_device = per_cpu(cpu_data, 0).dev;
+	printk("Performance monitoring counters enabled for %s\n",
+		per_cpu(cpu_data, 0).dev->name);
+
+	return 0;
+}
+device_initcall(perf_init);
+
+/*
+ * perf_start_counters(void)
+ *
+ * Start the counters.
+ */
+static void perf_start_counters(void)
+{
+	/* Enable performance monitor counters */
+	perf_intrigue_enable_perf_counters();
+}
+
+/*
+ * perf_stop_counters
+ *
+ * Stop the performance counters and save counts
+ * in a per_processor array.
+ */
+static int perf_stop_counters(uint32_t *raddr)
+{
+	uint64_t userbuf[MAX_RDR_WORDS];
+
+	/* Disable performance counters */
+	perf_intrigue_disable_perf_counters();
+
+	if (perf_processor_interface == ONYX_INTF) {
+		uint64_t tmp64;
+		/*
+		 * Read the counters
+		 */
+		if (!perf_rdr_read_ubuf(16, userbuf))
+			return -13;
+
+		/* Counter0 is bits 1398 to 1429 */
+		tmp64 =  (userbuf[21] << 22) & 0x00000000ffc00000;
+		tmp64 |= (userbuf[22] >> 42) & 0x00000000003fffff;
+		/* OR sticky0 (bit 1430) to counter0 bit 32 */
+		tmp64 |= (userbuf[22] >> 10) & 0x0000000080000000;
+		raddr[0] = (uint32_t)tmp64;
+
+		/* Counter1 is bits 1431 to 1462 */
+		tmp64 =  (userbuf[22] >> 9) & 0x00000000ffffffff;
+		/* OR sticky1 (bit 1463) to counter1 bit 32 */
+		tmp64 |= (userbuf[22] << 23) & 0x0000000080000000;
+		raddr[1] = (uint32_t)tmp64;
+
+		/* Counter2 is bits 1464 to 1495 */
+		tmp64 =  (userbuf[22] << 24) & 0x00000000ff000000;
+		tmp64 |= (userbuf[23] >> 40) & 0x0000000000ffffff;
+		/* OR sticky2 (bit 1496) to counter2 bit 32 */
+		tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000;
+		raddr[2] = (uint32_t)tmp64;
+
+		/* Counter3 is bits 1497 to 1528 */
+		tmp64 =  (userbuf[23] >> 7) & 0x00000000ffffffff;
+		/* OR sticky3 (bit 1529) to counter3 bit 32 */
+		tmp64 |= (userbuf[23] << 25) & 0x0000000080000000;
+		raddr[3] = (uint32_t)tmp64;
+
+		/*
+		 * Zero out the counters
+		 */
+
+		/*
+		 * The counters and sticky-bits comprise the last 132 bits
+		 * (1398 - 1529) of RDR16 on a U chip.  We'll zero these
+		 * out the easy way: zero out last 10 bits of dword 21,
+		 * all of dword 22 and 58 bits (plus 6 don't care bits) of
+		 * dword 23.
+		 */
+		userbuf[21] &= 0xfffffffffffffc00ul;	/* 0 to last 10 bits */
+		userbuf[22] = 0;
+		userbuf[23] = 0;
+
+		/*
+		 * Write back the zeroed bytes + the image given
+		 * the read was destructive.
+		 */
+		perf_rdr_write(16, userbuf);
+	} else {
+
+		/*
+		 * Read RDR-15 which contains the counters and sticky bits
+		 */
+		if (!perf_rdr_read_ubuf(15, userbuf)) {
+			return -13;
+		}
+
+		/*
+		 * Clear out the counters
+		 */
+		perf_rdr_clear(15);
+
+		/*
+		 * Copy the counters 
+		 */
+		raddr[0] = (uint32_t)((userbuf[0] >> 32) & 0x00000000ffffffffUL);
+		raddr[1] = (uint32_t)(userbuf[0] & 0x00000000ffffffffUL);
+		raddr[2] = (uint32_t)((userbuf[1] >> 32) & 0x00000000ffffffffUL);
+		raddr[3] = (uint32_t)(userbuf[1] & 0x00000000ffffffffUL);
+	}
+
+	return 0;
+}
+
+/*
+ * perf_rdr_get_entry
+ *
+ * Retrieve a pointer to the description of what this
+ * RDR contains.
+ */
+static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
+{
+	if (perf_processor_interface == ONYX_INTF) {
+		return &perf_rdr_tbl_U[rdr_num];
+	} else {
+		return &perf_rdr_tbl_W[rdr_num];
+	}
+}
+
+/*
+ * perf_rdr_read_ubuf
+ *
+ * Read the RDR value into the buffer specified.
+ */
+static int perf_rdr_read_ubuf(uint32_t	rdr_num, uint64_t *buffer)
+{
+	uint64_t	data, data_mask = 0;
+	uint32_t	width, xbits, i;
+	const struct rdr_tbl_ent *tentry;
+
+	tentry = perf_rdr_get_entry(rdr_num);
+	if ((width = tentry->width) == 0)
+		return 0;
+
+	/* Clear out buffer */
+	i = tentry->num_words;
+	while (i--) {
+		buffer[i] = 0;
+	}
+
+	/* Check for bits an even number of 64 */
+	if ((xbits = width & 0x03f) != 0) {
+		data_mask = 1;
+		data_mask <<= (64 - xbits);
+		data_mask--;
+	}
+
+	/* Grab all of the data */
+	i = tentry->num_words;
+	while (i--) {
+
+		if (perf_processor_interface == ONYX_INTF) {
+			data = perf_rdr_shift_in_U(rdr_num, width);
+		} else {
+			data = perf_rdr_shift_in_W(rdr_num, width);
+		}
+		if (xbits) {
+			buffer[i] |= (data << (64 - xbits));
+			if (i) {
+				buffer[i-1] |= ((data >> xbits) & data_mask);
+			}
+		} else {
+			buffer[i] = data;
+		}
+	}
+
+	return 1;
+}
+
+/*
+ * perf_rdr_clear
+ *
+ * Zero out the given RDR register
+ */
+static int perf_rdr_clear(uint32_t	rdr_num)
+{
+	const struct rdr_tbl_ent *tentry;
+	int32_t		i;
+
+	tentry = perf_rdr_get_entry(rdr_num);
+
+	if (tentry->width == 0) {
+		return -1;
+	}
+
+	i = tentry->num_words;
+	while (i--) {
+		if (perf_processor_interface == ONYX_INTF) {
+			perf_rdr_shift_out_U(rdr_num, 0UL);
+		} else {
+			perf_rdr_shift_out_W(rdr_num, 0UL);
+		}
+	}
+
+	return 0;
+}
+
+
+/*
+ * perf_write_image
+ *
+ * Write the given image out to the processor
+ */
+static int perf_write_image(uint64_t *memaddr)
+{
+	uint64_t buffer[MAX_RDR_WORDS];
+	uint64_t *bptr;
+	uint32_t dwords;
+	const uint32_t *intrigue_rdr;
+	const uint64_t *intrigue_bitmask;
+	uint64_t tmp64;
+	void __iomem *runway;
+	const struct rdr_tbl_ent *tentry;
+	int i;
+
+	/* Clear out counters */
+	if (perf_processor_interface == ONYX_INTF) {
+
+		perf_rdr_clear(16);
+
+		/* Toggle performance monitor */
+		perf_intrigue_enable_perf_counters();
+		perf_intrigue_disable_perf_counters();
+
+		intrigue_rdr = perf_rdrs_U;
+	} else {
+		perf_rdr_clear(15);
+		intrigue_rdr = perf_rdrs_W;
+	}
+
+	/* Write all RDRs */
+	while (*intrigue_rdr != -1) {
+		tentry = perf_rdr_get_entry(*intrigue_rdr);
+		perf_rdr_read_ubuf(*intrigue_rdr, buffer);
+		bptr   = &buffer[0];
+		dwords = tentry->num_words;
+		if (tentry->write_control) {
+			intrigue_bitmask = &bitmask_array[tentry->write_control >> 3];
+			while (dwords--) {
+				tmp64 = *intrigue_bitmask & *memaddr++;
+				tmp64 |= (~(*intrigue_bitmask++)) & *bptr;
+				*bptr++ = tmp64;
+			}
+		} else {
+			while (dwords--) {
+				*bptr++ = *memaddr++;
+			}
+		}
+
+		perf_rdr_write(*intrigue_rdr, buffer);
+		intrigue_rdr++;
+	}
+
+	/*
+	 * Now copy out the Runway stuff which is not in RDRs
+	 */
+
+	if (cpu_device == NULL)
+	{
+		printk(KERN_ERR "write_image: cpu_device not yet initialized!\n");
+		return -1;
+	}
+
+	runway = ioremap_nocache(cpu_device->hpa.start, 4096);
+	if (!runway) {
+		pr_err("perf_write_image: ioremap failed!\n");
+		return -ENOMEM;
+	}
+
+	/* Merge intrigue bits into Runway STATUS 0 */
+	tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
+	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul),
+		     runway + RUNWAY_STATUS);
+
+	/* Write RUNWAY DEBUG registers */
+	for (i = 0; i < 8; i++) {
+		__raw_writeq(*memaddr++, runway + RUNWAY_DEBUG);
+	}
+
+	return 0;
+}
+
+/*
+ * perf_rdr_write
+ *
+ * Write the given RDR register with the contents
+ * of the given buffer.
+ */
+static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer)
+{
+	const struct rdr_tbl_ent *tentry;
+	int32_t		i;
+
+printk("perf_rdr_write\n");
+	tentry = perf_rdr_get_entry(rdr_num);
+	if (tentry->width == 0) { return; }
+
+	i = tentry->num_words;
+	while (i--) {
+		if (perf_processor_interface == ONYX_INTF) {
+			perf_rdr_shift_out_U(rdr_num, buffer[i]);
+		} else {
+			perf_rdr_shift_out_W(rdr_num, buffer[i]);
+		}
+	}
+printk("perf_rdr_write done\n");
+}
diff --git a/arch/parisc/kernel/perf_asm.S b/arch/parisc/kernel/perf_asm.S
new file mode 100644
index 0000000..fa6ea99
--- /dev/null
+++ b/arch/parisc/kernel/perf_asm.S
@@ -0,0 +1,1692 @@
+
+/*    low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
+ * 
+ *    Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
+ *    Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
+ * 
+ *    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
+ */
+
+#include <asm/assembly.h>
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#ifdef CONFIG_64BIT
+	.level		2.0w
+#endif /* CONFIG_64BIT */
+
+#define MTDIAG_1(gr)    .word 0x14201840 + gr*0x10000
+#define MTDIAG_2(gr)    .word 0x14401840 + gr*0x10000
+#define MFDIAG_1(gr)    .word 0x142008A0 + gr
+#define MFDIAG_2(gr)    .word 0x144008A0 + gr
+#define STDIAG(dr)      .word 0x14000AA0 + dr*0x200000
+#define SFDIAG(dr)      .word 0x14000BA0 + dr*0x200000
+#define DR2_SLOW_RET    53
+
+
+;
+; Enable the performance counters
+;
+; The coprocessor only needs to be enabled when
+; starting/stopping the coprocessor with the pmenb/pmdis.
+;
+	.text
+
+ENTRY(perf_intrigue_enable_perf_counters)
+	.proc
+	.callinfo  frame=0,NO_CALLS
+	.entry
+
+	ldi     0x20,%r25                ; load up perfmon bit
+	mfctl   ccr,%r26                 ; get coprocessor register
+	or      %r25,%r26,%r26             ; set bit
+	mtctl   %r26,ccr                 ; turn on performance coprocessor
+	pmenb                           ; enable performance monitor
+	ssm     0,0                     ; dummy op to ensure completion
+	sync                            ; follow ERS
+	andcm   %r26,%r25,%r26             ; clear bit now 
+	mtctl   %r26,ccr                 ; turn off performance coprocessor
+	nop                             ; NOPs as specified in ERS
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	bve    (%r2)
+	nop
+	.exit
+	.procend
+ENDPROC(perf_intrigue_enable_perf_counters)
+
+ENTRY(perf_intrigue_disable_perf_counters)
+	.proc
+	.callinfo  frame=0,NO_CALLS
+	.entry
+	ldi     0x20,%r25                ; load up perfmon bit
+	mfctl   ccr,%r26                 ; get coprocessor register
+	or      %r25,%r26,%r26             ; set bit
+	mtctl   %r26,ccr                 ; turn on performance coprocessor
+	pmdis                           ; disable performance monitor
+	ssm     0,0                     ; dummy op to ensure completion
+	andcm   %r26,%r25,%r26             ; clear bit now 
+	bve    (%r2)
+	mtctl   %r26,ccr                 ; turn off performance coprocessor
+	.exit
+	.procend
+ENDPROC(perf_intrigue_disable_perf_counters)
+
+;***********************************************************************
+;*
+;* Name: perf_rdr_shift_in_W
+;*
+;* Description:
+;*	This routine shifts data in from the RDR in arg0 and returns
+;*	the result in ret0.  If the RDR is <= 64 bits in length, it
+;*	is shifted shifted backup immediately.  This is to compensate
+;*	for RDR10 which has bits that preclude PDC stack operations
+;*	when they are in the wrong state.
+;*
+;* Arguments:
+;*	arg0 : rdr to be read
+;*	arg1 : bit length of rdr
+;*
+;* Returns:
+;*	ret0 = next 64 bits of rdr data from staging register
+;*
+;* Register usage:
+;*	arg0 : rdr to be read
+;*	arg1 : bit length of rdr
+;*	%r24  - original DR2 value
+;*	%r1   - scratch
+;*  %r29  - scratch
+;*
+;* Returns:
+;*	ret0 = RDR data (right justified)
+;*
+;***********************************************************************
+
+ENTRY(perf_rdr_shift_in_W)
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+;
+; read(shift in) the RDR.
+;
+
+; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r29
+	MFDIAG_2	(24)
+	or		    %r24,%r29,%r29
+	MTDIAG_2	(29)			; set DR2_SLOW_RET
+
+	nop
+	nop
+	nop
+	nop
+
+;
+; Cacheline start (32-byte cacheline)
+;
+	nop
+	nop
+	nop
+	extrd,u		arg1,63,6,%r1	; setup shift amount by bits to move 
+
+	mtsar		%r1
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr  		%r1,%r0		; branch to 8-instruction sequence
+	nop
+
+;
+; Cacheline start (32-byte cacheline)
+;
+
+	;
+	; RDR 0 sequence
+	;
+	SFDIAG		(0)
+	ssm		    0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)			; mtdiag %dr1, %r1 
+	STDIAG		(0)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 1 sequence
+	;
+	sync
+	ssm		    0,0
+	SFDIAG		(1)
+	ssm		    0,0
+	MFDIAG_1	(28)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+
+	;
+	; RDR 2 read sequence
+	;
+	SFDIAG		(2)
+	ssm		    0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(2)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 3 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 4 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(4)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	; 
+	; RDR 5 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(5)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 6 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(6)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 7 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 8 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 9 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 10 read sequence
+	;
+	SFDIAG		(10)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(10)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 11 read sequence
+	;
+	SFDIAG		(11)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(11)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 12 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 13 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(13)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 14 read sequence
+	;
+	SFDIAG		(14)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(14)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 15 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(15)
+	ssm		0,0
+	MFDIAG_1	(28)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+
+	;
+	; RDR 16 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(16)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 17 read sequence
+	;
+	SFDIAG		(17)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(17)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 18 read sequence
+	;
+	SFDIAG		(18)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(18)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 19 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 20 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(20)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 21 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(21)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 22 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(22)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 23 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(23)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 24 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(24)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 25 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(25)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 26 read sequence
+	;
+	SFDIAG		(26)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 27 read sequence
+	;
+	SFDIAG		(27)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 28 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(28)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 29 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(29)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 30 read sequence
+	;
+	SFDIAG		(30)
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(30)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_W_leave
+
+	;
+	; RDR 31 read sequence
+	;
+	sync
+	ssm		0,0
+	SFDIAG		(31)
+	ssm		0,0
+	MFDIAG_1	(28)
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; Fallthrough
+	;
+
+perf_rdr_shift_in_W_leave:
+	bve		    (%r2)
+	.exit
+	MTDIAG_2	(24)			; restore DR2
+	.procend
+ENDPROC(perf_rdr_shift_in_W)
+
+
+;***********************************************************************
+;*
+;* Name: perf_rdr_shift_out_W
+;*
+;* Description:
+;*	This routine moves data to the RDR's.  The double-word that
+;*	arg1 points to is loaded and moved into the staging register.
+;*	Then the STDIAG instruction for the RDR # in arg0 is called
+;*	to move the data to the RDR.
+;*
+;* Arguments:
+;*	arg0 = rdr number
+;*	arg1 = 64-bit value to write
+;*	%r24 - DR2 | DR2_SLOW_RET
+;*	%r23 - original DR2 value
+;*
+;* Returns:
+;*	None
+;*
+;* Register usage:
+;*
+;***********************************************************************
+
+ENTRY(perf_rdr_shift_out_W)
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+;
+; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, the remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r24
+	MFDIAG_2	(23)
+	or		%r24,%r23,%r24
+	MTDIAG_2	(24)		; set DR2_SLOW_RET
+	MTDIAG_1	(25)		; data to the staging register
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr		    %r1,%r0	; branch to 8-instruction sequence
+	nop
+
+	;
+	; RDR 0 write sequence
+	;
+	sync				; RDR 0 write sequence
+	ssm		0,0
+	STDIAG		(0)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 1 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(1)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 2 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(2)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 3 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(3)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 4 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(4)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 5 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(5)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 6 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(6)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 7 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(7)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 8 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(8)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 9 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(9)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 10 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(10)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 11 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(11)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 12 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(12)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 13 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(13)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 14 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(14)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 15 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(15)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 16 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(16)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 17 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(17)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 18 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(18)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 19 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(19)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 20 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(20)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 21 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(21)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 22 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(22)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 23 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(23)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 24 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(24)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 25 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(25)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 26 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(10)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 27 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(11)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 28 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(28)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 29 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(29)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 30 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(30)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 31 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(31)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+perf_rdr_shift_out_W_leave:
+	bve		(%r2)
+	.exit
+	MTDIAG_2	(23)			; restore DR2
+	.procend
+ENDPROC(perf_rdr_shift_out_W)
+
+
+;***********************************************************************
+;*
+;* Name: rdr_shift_in_U
+;*
+;* Description:
+;*	This routine shifts data in from the RDR in arg0 and returns
+;*	the result in ret0.  If the RDR is <= 64 bits in length, it
+;*	is shifted shifted backup immediately.  This is to compensate
+;*	for RDR10 which has bits that preclude PDC stack operations
+;*	when they are in the wrong state.
+;*
+;* Arguments:
+;*	arg0 : rdr to be read
+;*	arg1 : bit length of rdr
+;*
+;* Returns:
+;*	ret0 = next 64 bits of rdr data from staging register
+;*
+;* Register usage:
+;*	arg0 : rdr to be read						                        
+;*	arg1 : bit length of rdr					                        
+;*	%r24 - original DR2 value
+;*	%r23 - DR2 | DR2_SLOW_RET
+;*	%r1  - scratch
+;*
+;***********************************************************************
+
+ENTRY(perf_rdr_shift_in_U)
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+
+; read(shift in) the RDR.
+;
+; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, remote diagnose registers.
+
+	depdi,z		1,DR2_SLOW_RET,1,%r29
+	MFDIAG_2	(24)
+	or			%r24,%r29,%r29
+	MTDIAG_2	(29)			; set DR2_SLOW_RET
+
+	nop
+	nop
+	nop
+	nop
+
+;
+; Start of next 32-byte cacheline
+;
+	nop
+	nop
+	nop
+	extrd,u		arg1,63,6,%r1
+
+	mtsar		%r1
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr 		%r1,%r0		; branch to 8-instruction sequence
+	nop
+
+;
+; Start of next 32-byte cacheline
+;
+	SFDIAG		(0)		; RDR 0 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(0)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(1)		; RDR 1 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(1)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	sync				; RDR 2 read sequence
+	ssm		0,0
+	SFDIAG		(4)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 3 read sequence
+	ssm		0,0
+	SFDIAG		(3)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 4 read sequence
+	ssm		0,0
+	SFDIAG		(4)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 5 read sequence
+	ssm		0,0
+	SFDIAG		(5)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 6 read sequence
+	ssm		0,0
+	SFDIAG		(6)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 7 read sequence
+	ssm		0,0
+	SFDIAG		(7)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	SFDIAG		(9)		; RDR 9 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(9)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(10)		; RDR 10 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(10)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(11)		; RDR 11 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(11)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(12)		; RDR 12 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(12)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(13)		; RDR 13 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(13)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(14)		; RDR 14 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(14)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(15)		; RDR 15 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(15)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	sync				; RDR 16 read sequence
+	ssm		0,0
+	SFDIAG		(16)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	SFDIAG		(17)		; RDR 17 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(17)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(18)		; RDR 18 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(18)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	sync				; RDR 20 read sequence
+	ssm		0,0
+	SFDIAG		(20)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 21 read sequence
+	ssm		0,0
+	SFDIAG		(21)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 22 read sequence
+	ssm		0,0
+	SFDIAG		(22)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 23 read sequence
+	ssm		0,0
+	SFDIAG		(23)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 24 read sequence
+	ssm		0,0
+	SFDIAG		(24)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	sync				; RDR 25 read sequence
+	ssm		0,0
+	SFDIAG		(25)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	SFDIAG		(26)		; RDR 26 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(27)		; RDR 27 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	sync				; RDR 28 read sequence
+	ssm		0,0
+	SFDIAG		(28)
+	ssm		0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm		0,0
+	nop
+
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	SFDIAG		(30)		; RDR 30 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(30)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(31)		; RDR 31 read sequence
+	ssm		0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(31)
+	ssm		0,0
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+
+perf_rdr_shift_in_U_leave:
+	bve		    (%r2)
+	.exit
+	MTDIAG_2	(24)			; restore DR2
+	.procend
+ENDPROC(perf_rdr_shift_in_U)
+
+;***********************************************************************
+;*
+;* Name: rdr_shift_out_U
+;*
+;* Description:
+;*	This routine moves data to the RDR's.  The double-word that
+;*	arg1 points to is loaded and moved into the staging register.
+;*	Then the STDIAG instruction for the RDR # in arg0 is called
+;*	to move the data to the RDR.
+;*
+;* Arguments:
+;*	arg0 = rdr target
+;*	arg1 = buffer pointer
+;*
+;* Returns:
+;*	None
+;*
+;* Register usage:
+;*	arg0 = rdr target
+;*	arg1 = buffer pointer
+;*	%r24 - DR2 | DR2_SLOW_RET
+;*	%r23 - original DR2 value
+;*
+;***********************************************************************
+
+ENTRY(perf_rdr_shift_out_U)
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+
+;
+; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, the remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r24
+	MFDIAG_2	(23)
+	or		%r24,%r23,%r24
+	MTDIAG_2	(24)		; set DR2_SLOW_RET
+
+	MTDIAG_1	(25)		; data to the staging register
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr		%r1,%r0		; branch to 8-instruction sequence
+	nop
+
+;
+; 32-byte cachline aligned
+;
+
+	sync				; RDR 0 write sequence
+	ssm		0,0
+	STDIAG		(0)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 1 write sequence
+	ssm		0,0
+	STDIAG		(1)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 2 write sequence
+	ssm		0,0
+	STDIAG		(2)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 3 write sequence
+	ssm		0,0
+	STDIAG		(3)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 4 write sequence
+	ssm		0,0
+	STDIAG		(4)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 5 write sequence
+	ssm		0,0
+	STDIAG		(5)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 6 write sequence
+	ssm		0,0
+	STDIAG		(6)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 7 write sequence
+	ssm		0,0
+	STDIAG		(7)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 8 write sequence
+	ssm		0,0
+	STDIAG		(8)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 9 write sequence
+	ssm		0,0
+	STDIAG		(9)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 10 write sequence
+	ssm		0,0
+	STDIAG		(10)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 11 write sequence
+	ssm		0,0
+	STDIAG		(11)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 12 write sequence
+	ssm		0,0
+	STDIAG		(12)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 13 write sequence
+	ssm		0,0
+	STDIAG		(13)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 14 write sequence
+	ssm		0,0
+	STDIAG		(14)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 15 write sequence
+	ssm		0,0
+	STDIAG		(15)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 16 write sequence
+	ssm		0,0
+	STDIAG		(16)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 17 write sequence
+	ssm		0,0
+	STDIAG		(17)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 18 write sequence
+	ssm		0,0
+	STDIAG		(18)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 19 write sequence
+	ssm		0,0
+	STDIAG		(19)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 20 write sequence
+	ssm		0,0
+	STDIAG		(20)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 21 write sequence
+	ssm		0,0
+	STDIAG		(21)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 22 write sequence
+	ssm		0,0
+	STDIAG		(22)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 23 write sequence
+	ssm		0,0
+	STDIAG		(23)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 24 write sequence
+	ssm		0,0
+	STDIAG		(24)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 25 write sequence
+	ssm		0,0
+	STDIAG		(25)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 26 write sequence
+	ssm		0,0
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 27 write sequence
+	ssm		0,0
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 28 write sequence
+	ssm		0,0
+	STDIAG		(28)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 29 write sequence
+	ssm		0,0
+	STDIAG		(29)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 30 write sequence
+	ssm		0,0
+	STDIAG		(30)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+	sync				; RDR 31 write sequence
+	ssm		0,0
+	STDIAG		(31)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm		0,0
+	nop
+
+perf_rdr_shift_out_U_leave:
+	bve		(%r2)
+	.exit
+	MTDIAG_2	(23)			; restore DR2
+	.procend
+ENDPROC(perf_rdr_shift_out_U)
+
diff --git a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h
new file mode 100644
index 0000000..7fef964
--- /dev/null
+++ b/arch/parisc/kernel/perf_images.h
@@ -0,0 +1,3138 @@
+/* 
+ *    Imagine for use with the Onyx (PCX-U) CPU interface 
+ *
+ *    Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
+ *    Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
+ *
+ *    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
+ */
+#ifndef PERF_IMAGES_H
+#define PERF_IMAGES_H
+
+/* Magic numbers taken without modification from HPUX stuff */
+
+#define PCXU_IMAGE_SIZE 584
+
+static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
+/*
+ * CPI:
+ *
+ * Counts the following:
+ *
+ * ctr0 : total cycles
+ * ctr1 : total cycles where nothing retired
+ * ctr2 : total instructions retired, including nullified
+ * ctr3 : total instructions retired, less nullified instructions
+ */
+         {
+         0x4c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe0e0e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
+         0x0101ffff, 0xfffff104, 0xe000c07f, 0xfffffffc,
+         0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
+         0x00000fff, 0xff00000f, 0xffff0000, 0x0fffff00,
+         0x000fffff, 0x00000000, 0x00000000, 0x00ffffff,
+         0xfffff000, 0x0000000f, 0xffffffff, 0xff000000,
+         0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000030, 0x00003c00, 0x067f080c, 0x02019fc0,
+         0x02804067, 0xf0009030, 0x19fc002c, 0x40067f08,
+         0x0c12019f, 0xc0028440, 0x67f00091, 0x3019fc00,
+         0x2fc007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
+         0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
+         0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
+         0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
+         0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
+         0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
+         0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
+         0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff},
+
+/* Bus utilization image (bus_util)
+ *
+ * ctr0 : counts address valid cycles
+ * ctr1 : counts data valid cycles
+ * ctr2 : counts overflow from counter 0
+ * ctr3 : counts overflow from counter 1
+ */
+         {
+         0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
+         0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0x0000000c, 0x00003c00, 0x07930000, 0x0041e4c0,
+         0x01002079, 0x3000800c, 0x1e4c0030, 0x00279300,
+         0x010049e4, 0xc0014022, 0x79300090, 0x0c9e4c00,
+         0x34004793, 0x00020051, 0xe4c00180, 0x24793000,
+         0xa00d1e4c, 0x00380067, 0x93000300, 0x59e4c001,
+         0xc0267930, 0x00b00d9e, 0x4c003fff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00100000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/*
+ * TLB counts (same as tlbStats image):
+ *
+ * Counts the following:
+ *
+ * ctr0: DTLB misses
+ * ctr1: ITLB misses
+ * ctr2: total cycles in the miss handlers
+ * ctr3: total cycles
+ */
+
+         {
+         0x0c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe7e7e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
+         0x0101ffff, 0xfffff104, 0xe000c06a, 0xafffc85c,
+         0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
+         0x01b9e000, 0x0001b8c0, 0x00000000, 0x0fffff00,
+         0x000fffff, 0x00000000, 0x00000000, 0x00400000,
+         0x00001000, 0x00000004, 0x00000000, 0x01000000,
+         0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55ff5, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c00, 0x01ff0001, 0x08007fc2,
+         0x02c1001f, 0xf0807100, 0x1bfc200c, 0x4806ff00,
+         0x03f001ff, 0xfe003c00, 0x7fff800f, 0x001fffe0,
+         0x03c007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
+         0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
+         0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
+         0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
+         0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
+         0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
+         0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
+         0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/* tlbHandMiss
+ *
+ * ctr0: counts TLB misses 
+ * ctr1: counts dmisses inside tlb miss handlers 
+ * ctr2: counts cycles in the tlb miss handlers 
+ * ctr3: counts overflows of ctr2 
+ */
+{
+0x1c00c000,00000000,0x00060000,00000000,
+0xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
+0x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
+0x01380010,0x1fffffff,0xff000000,00000000,
+0x01b9e000,0x0001b8c0,00000000,0x0fffff00,
+0x000fffff,00000000,00000000,0x00400000,
+0x00001000,0x00000004,00000000,0x01000000,
+0x0000ffff,0xfffffff0,00000000,0x0fffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
+0xf0000000,0x00003c00,0x01fd0000,0x08007f42,
+0x0281001f,0xd080a100,0x19f42008,0x44067d08,
+0x0612019f,0x400084c0,0x67d00060,0x0047f400,
+0x042011fd,0x080b0404,0x7f4202c4,0x0167d080,
+0x311059f4,0x201c4816,0x7d000313,0x059f4001,
+0xfc007fff,0x800f001f,0xffe003c0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* branch_taken image (ptkn image)
+ *
+ * ctr0: overflow for ctr1
+ * ctr1: predicted taken branches, actually taken
+ * ctr2: all predicted taken branches (nullfied or not)
+ * ctr3: overflow for ctr2
+ */
+
+        {
+        0xcc01e000, 0x00000000, 0x00060000, 0x00000000,
+        0xa08080a0, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+        0xf0000000, 0x00003c00, 0x04f90000, 0x02013e40,
+        0x0081004f, 0x90004060, 0x13e40018, 0x0024f900,
+        0x0802093e, 0x40028102, 0x4f9000c0, 0x6093e400,
+        0x380014f9, 0x00010205, 0x3e4000c1, 0x014f9000,
+        0x506053e4, 0x001c0034, 0xf9000902, 0x0d3e4002,
+        0xc1034f90, 0x00d060d3, 0xe4003fff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
+        0x00000000, 0x00000000, 0x00000000, 0x00000000,
+        0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+        0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+        0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+        0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+        0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff },
+
+/* branch_nottaken (pntkn image)
+ *
+ * ctr0: overflow for ctr1
+ * ctr1: counts branches predicted not-taken, but actually taken
+ * ctr2: counts all predictable branches predicted not-taken
+ * ctr3: overflow for ctr2
+ */
+{
+0xcc01e000,00000000,0x00060000,00000000,
+0xc0c0c0e0,0xffb1fffb,0xfff7ffff,0xffffffff,
+0xffffffff,0xfffffffb,0x1fffbfff,0x7fffffff,
+0xfcc7ffff,0xffdffffa,0x5f000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+
+/* imiss image
+ *
+ * ctr0 : counts imiss aligned on 0
+ * ctr1 : counts imiss aligned on 4
+ * ctr2 : counts imiss aligned on 8
+ * ctr3 : counts imiss aligned on C
+ */
+         {
+         0x0c00c000, 0x00000000, 0x00010000, 0x00000000,
+         0xe7ebedee, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c00, 0x007f0000, 0x01001fc0,
+         0x00408007, 0xf0002030, 0x01fc000c, 0x10007f00,
+         0x0405001f, 0xc0014180, 0x07f00060, 0x7001fc00,
+         0x1c20007f, 0x00080900, 0x1fc00242, 0x8007f000,
+         0xa0b001fc, 0x002c3000, 0x7f000c0d, 0x001fc003,
+         0x438007f0, 0x00e0f001, 0xfc003fff, 0xfffff800,
+         0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
+         0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
+         0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
+         0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
+         0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff},
+
+/* dmiss image
+ * 
+ * ctr0 : counts cycles
+ * ctr1 : counts cycles where something retired
+ * ctr2 : counts dmisses
+ * ctr3 : (same as ctr2)
+ */
+         {
+         0x3c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe0e0e0e0, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c04, 0x007f0009, 0x02001fc0,
+         0x0280c007, 0xf000b040, 0x01fc0030, 0x14007f00,
+         0x0d06001f, 0xc00381c0, 0x07f000f0, 0x8001fc00,
+         0x2024007f, 0x00090a00, 0x1fc00282, 0xc007f000,
+         0xb0c001fc, 0x00303400, 0x7f000d0e, 0x001fc003,
+         0x83c007f0, 0x00f00001, 0xfc0023ff, 0xfffff800,
+         0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
+         0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
+         0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
+         0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
+         0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/* dcmiss 
+ *
+ * ctr0: counts store instructions retired 
+ * ctr1: counts load instructions retired
+ * ctr2: counts dmisses 
+ * ctr3: counts READ_SHARED_OR_PRIV and READ_PRIVATE transactions on Runway 
+ */
+{
+0x2c90c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf00000e8,0x00003c02,0x00bf0001,0x02002fc0,
+0x0080a00b,0xf0003040,0x02fc0010,0x1200bf00,
+0x0506002f,0xc00181a0,0x0bf00070,0x8002fc00,
+0x202200bf,0x00090a00,0x2fc00282,0xa00bf000,
+0xb0c002fc,0x00303200,0xbf000d0e,0x002fc003,
+0x83a00bf0,0x00ffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0x55555555,0xd5555555,
+0x55555555,0x75555555,0x5e1ffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf8000000,00000000,
+00000000,00000000,0xf4000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* big_cpi
+ *
+ * ctr0: counts total cycles 
+ * ctr1: counts overflows of ctr0 (for greater than 32-bit values) 
+ * ctr2: counts overflows of ctr3 (for greater than 32-bit values) 
+ * ctr3: counts unnullified instructions retired 
+ */
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
+0x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
+0x01380010,0x1fffffff,0xff000000,00000000,
+0x01b9e000,0x0001b8c0,00000000,0x0fffff00,
+0x000fffff,00000000,00000000,0x00400000,
+0x00001000,0x00000004,00000000,0x01000000,
+0x0000ffff,0xfffffff0,00000000,0x0fffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
+0xf0000010,0x00003c00,0x01760008,0x00025d80,
+0x02800417,0x6000c001,0x25d80038,0x04017600,
+0x0901025d,0x8002c044,0x176000d0,0x1125d800,
+0x3c2001f6,0x08080400,0x7d820203,0x001f6080,
+0x804027d8,0x20282009,0xf6080a0c,0x027d8202,
+0x81041f60,0x80c08107,0xd8203030,0x41f6080c,
+0x04127d82,0x0382049f,0x6080e0c1,0x27d82038,
+0x4006f608,0x081011bd,0x82030400,0xef6080a1,
+0x013bd820,0x384806f6,0x00081211,0xbd800304,
+0x80ef6000,0xa1213bd8,0x003bc007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* big_ls
+ *
+ * ctr0:counts the total number of cycles for which local_stall_A1 is asserted. 
+ * ctr1: is the overflow for counter 0. 
+ * ctr2: counts IFLUSH_AV 
+ * ctr3: is the overflow for counter 2. 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00029408,0x02f50002,0x0800bd40,
+0x0202802f,0x5000a000,0x4bd40004,0x0812f500,
+0x030804bd,0x40024281,0x2f5000b0,0x010bd400,
+0x100842f5,0x00060810,0xbd400302,0x842f5000,
+0xe0014bd4,0x00140852,0xf5000708,0x14bd4003,
+0x42852f50,0x00ff001f,0xffe003c0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x0df70000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* br_abort
+ *
+ * ctr0: counts BRAD_STALLH 
+ * ctr1: counts ONE_QUAD 
+ * ctr2: counts BR0_ABRT 
+ * ctr3: counts BR1_ABRT
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x1a250000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* isnt
+ *
+ * ctr0: counts the total number of cycles for which iside_notrans is asserted 
+ * ctr1: counts the number of times iside_notrans is asserted for 1-4 cycles 
+ * ctr2: counts the number of times iside_notrans is asserted for 5-7 cycles 
+ * ctr3: counts the number of times iside_notrans is asserted for > 7 cycles 
+ */
+{
+0x0c018000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xcfffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c20,0x03ff0808,0x1800ffc4,
+0x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
+0x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
+0x210003ff,0x00045800,0xffcc0214,0x003ff000,
+0x26800ffc,0xe0218003,0xff000278,0x00ffd002,
+0x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xcdff0000,00000000,0xc0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* quadrant
+ *
+ * ctr0: Total number of instructions in quadrant 0 
+ * ctr1: Total number of instructions in quadrant 1 
+ * ctr2: Total number of instructions in quadrant 2 
+ * ctr3: Total number of instructions in quadrant 3 
+ * Works only with 32-bit
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x004e0004,   0x07ffffff,   0xffc01380,
+   0x0101ffff,   0xfffff004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0x00000fff,   0xff00000f,   0xffff0000,   0x0fffff00,
+   0x000fffff,   0x00000000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000040f,   0xfffffffc,   0xff000000,
+   0x0080ffff,   0xffffcff0,   0x0000000c,   0x0fffffff,
+   0xfcff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xfff55ff5,   0x5fffffff,   0xffffffff,   0xf0000000,
+   0xf00000f0,   0x00003c00,   0x007f0000,   0x01001fc0,
+   0x00408007,   0xf0002030,   0x01fc000c,   0x10007f00,
+   0x0405001f,   0xc0014180,   0x07f00060,   0x7001fc00,
+   0x1c20007f,   0x00080900,   0x1fc00242,   0x8007f000,
+   0xa0b001fc,   0x002c3000,   0x7f000c0d,   0x001fc003,
+   0x438007f0,   0x00e0f001,   0xfc003fff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffffc00,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff},
+
+/* rw_pdfet (READ_PRIV transactions)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf8000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff},
+
+/* rw_wdfet (WRITEBACKS)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0x98000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff},
+
+/* shlib_cpi
+ *
+ * ctr0: Total number of instructions in quad 0 
+ * ctr1: Total number of CPU clock cycles in quad 0 
+ * ctr2: total instructions without nullified   
+ * ctr3: total number of CPU clock cycles 
+ */
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x004e0004,   0x07ffffff,   0xffc01380,
+   0x0101ffff,   0xfffff004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0x00000fff,   0xff00000f,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000000f,   0xfffffffc,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xfff77ff5,   0x7fffffff,   0xffffffff,   0xf0000000,
+   0xf00000a0,   0x00003c00,   0x01ff0005,   0x08007fc0,
+   0x03c1001f,   0xf08030c0,   0x07fc203c,   0x4001ff08,
+   0x0118007f,   0xc003c500,   0x1ff08031,   0xc007fc00,
+   0x3fffffff,   0xf800ffff,   0xfffe003f,   0xffffff80,
+   0x0fffffff,   0xe003ffff,   0xfff800ff,   0xfffffe00,
+   0x3fffffff,   0x800fffff,   0xffe003ff,   0xfffff800,
+   0xfffffffe,   0x003fffff,   0xff800fff,   0xffffe003,
+   0xfffffff8,   0x00ffffff,   0xfe003fff,   0xffff800f,
+   0xffffffe0,   0x03ffffff,   0xf800ffff,   0xfffe003f,
+   0xffffff80,   0x0fffffff,   0xe003ffff,   0xfff800ff,
+   0xfffffe00,   0x3fffffff,   0x800fffff,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff},
+
+
+/* addr_inv_abort_alu
+ *
+ * ctr0: counts ABORT_ALU0L 
+ * ctr1: counts ABORT_ALU1L 
+ * ctr2: counts ADDR0_INVALID 
+ * ctr3: counts ADDR1_INVALID 
+ */
+
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000d,0x01001fc0,
+0x03008007,0xf000f030,0x01fc0038,0x10007f00,
+0x0905001f,0xc0020180,0x07f000b0,0x7001fc00,
+0x2820007f,0x00050900,0x1fc00102,0x8007f000,
+0x70b001fc,0x00183000,0x7f00010d,0x001fc000,
+0x038007f0,0x0030f001,0xfc000bff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x65380000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+
+/* brad_stall
+ *
+ * ctr0: counts the total number of cycles for which brad_stall is asserted 
+ * ctr1: counts the number of times brad_stall is asserted for 1-4 cycles 
+ * ctr2: counts the number of times brad_stall is asserted for 5-7 cycles 
+ * ctr3: counts the number of times brad_stall is asserted for > 7 cycles 
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c20,0x03ff0808,0x1800ffc4,
+0x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
+0x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
+0x210003ff,0x00045800,0xffcc0214,0x003ff000,
+0x26800ffc,0xe0218003,0xff000278,0x00ffd002,
+0x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x1bff0000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* cntl_in_pipel
+ *
+ * ctr0: counts the total number of cycles for which cntl_in_pipel is asserted 
+ * ctr1: counts the number of times cntl_in_pipel is asserted for 1-4 cycles 
+ * ctr2: counts the number of times cntl_in_pipel is asserted for 5-7 cycles 
+ * ctr3: counts the number of times cntl_in_pipel is asserted for > 7 cycles 
+ */
+{
+0x0c006000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x3fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c00,0x03ff0808,0x1000ffc4,
+0x0206003f,0xf0004200,0x0ffc6020,0xa003ff00,
+0x043000ff,0xc8020e00,0x3ff00044,0x000ffca0,
+0x212003ff,0x00045000,0xffcc0216,0x003ff000,
+0x26000ffc,0xe021a003,0xff000270,0x00ffd002,
+0x1e003ff0,0x0028000f,0xfd002220,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x3fff0000,00000000,0x30000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+/* dsnt_xfh
+ *
+ * ctr0: counts dside_notrans 
+ * ctr1: counts xfhang 
+ * ctr2: is the overflow for ctr0 
+ * ctr3: is the overflow for ctr1 
+ */
+{
+0x0c018000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xcfffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00030000,0x01f30000,0x00087cc0,
+0x0040041f,0x30002001,0x87cc000c,0x1001f300,
+0x0404087c,0xc0014104,0x1f300060,0x4187cc00,
+0x1c2001f3,0x00080808,0x7cc00242,0x041f3000,
+0xa08187cc,0x002c3001,0xf3000c0c,0x087cc003,
+0x43041f30,0x00e0c187,0xcc003fc0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xcb3f0000,00000000,0xc0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff }, 
+
+/* fet_sig1
+ *
+ * ctr0: counts ICORE_AV 
+ * ctr1: counts ITRANS_STALL 
+ * ctr2: counts SEL_PCQH 
+ * ctr3: counts OUT_OF_CONTEXT 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x07c10000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* fet_sig2
+ *
+ * ctr0: counts ICORE_AV  
+ * ctr1: counts IRTN_AV 
+ * ctr2: counts ADDRESS_INC 
+ * ctr3: counts ADDRESS_DEC 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x06930000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_1
+ *
+ * ctr0: counts HIT_RETRY0 
+ * ctr1: counts HIT_RETRY1 
+ * ctr2: counts GO_TAG_E 
+ * ctr3: counts GO_TAG_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x71c10000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_2
+ *
+ * ctr0: counts HIT_DM0 
+ * ctr1: counts HIT_DM1 
+ * ctr2: counts GO_STORE_E 
+ * ctr3: counts GO_STORE_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x72930000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_3
+ *
+ * ctr0: counts HIT_DV0 
+ * ctr1: counts HIT_DV1 
+ * ctr2: counts STBYPT_E (load bypasses from store queue) 
+ * ctr3: counts STBYPT_O
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f0002,0x01001fc0,
+0x00c08007,0xf0000030,0x01fc0004,0x10007f00,
+0x0605001f,0xc001c180,0x07f00040,0x7001fc00,
+0x1420007f,0x000a0900,0x1fc002c2,0x8007f000,
+0x80b001fc,0x00243000,0x7f000e0d,0x001fc003,
+0xc38007f0,0x00c0f001,0xfc0037ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x77250000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_4
+ *
+ * ctr0: counts HIT_DIRTY0 
+ * ctr1: counts HIT_DIRTY1 
+ * ctr2: counts CA_BYP_E (quick launch) 
+ * ctr3: counts CA_BYP_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x7bb70000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+/* mpb_labort
+ *
+ * ctr0: counts L_ABORT_ALU0L
+ * ctr1: counts L_ABORT_ALU1L 
+ * ctr2: counts MPB0H 
+ * ctr3: counts MPB1H 
+ */
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x605c0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* panic
+ *
+ * ctr0: is the overflow for counter 1 
+ * ctr1: counts traps and RFI's 
+ * ctr2: counts panic traps 
+ * ctr3: is the overflow for counter 2
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xe7efe0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffffc,
+0x41380030,0x1aabfff2,0x17000000,00000000,
+0x01b80000,0x3effffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,00000000,0x00400000,
+0x00001fff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+0xb0000000,0x00012c04,0x05790804,0x14013e44,
+0x0008004f,0x90000040,0x15e46000,0xc0047920,
+0x004a003e,0x40011080,0x0f900024,0x4003e460,
+0x00c80479,0x00023301,0x1e400100,0x4157d080,
+0x514053f4,0x40048014,0xfd000104,0x055f4600,
+0x4c0147d2,0x0014a043,0xf4001508,0x10fd0003,
+0x44043f46,0x004c8147,0xd0003330,0x51f40014,
+0x04257908,0x0c14093e,0x44020802,0x4f900080,
+0x4095e460,0x20c02479,0x20084a08,0x3e400310,
+0x820f9000,0xa44083e4,0x6020c824,0x79000a33,
+0x091e4003,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x10400000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rare_inst
+ *
+ * ctr0: counts sync and syncdma instructions 
+ * ctr1: counts pxtlbx,x instructions 
+ * ctr2: counts ixtlbt instructions 
+ * ctr3: counts cycles 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0x004e000c,0x000843fc,0x85c09380,
+0x0121ebfd,0xff217124,0xe0004000,0x943fc85f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xe00000e0,0x00003c00,0x007f0001,0x01001fc0,
+0x00408007,0xf0003030,0x01fc000c,0x10007f00,
+0x0505001f,0xc0014180,0x07f00070,0x7001fc00,
+0x1c20007f,0x00090900,0x1fc00242,0x8007f000,
+0xb0b001fc,0x002c3000,0x7f000d0d,0x001fc003,
+0x438007f0,0x00f0f001,0xfc003fff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rw_dfet (for D-cache misses and writebacks)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf0000000,00000000,
+00000000,00000000,0x98000000,00000000,
+0xffffffff,0xffffffff,0x0fffffff,0xffffffff,
+00000000,00000000,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rw_ifet (I-cache misses -- actually dumb READ transactions)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xd0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff,00000000,00000000,
+0xffffffff,0xffffffff },
+
+
+/* rw_sdfet (READ_SHARED_OR_PRIVATE transactions)
+ *
+ * ctr0: counts address valid cycles
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf4000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff },
+
+
+/* spec_ifet
+ *
+ * ICORE_AV fires for every request which the Instruction Fetch Unit sends
+ * to the Runway Interface Block.  Hence, this counts all I-misses, speculative
+ * or not, but does *not* include I-cache prefetches, which are generated by
+ * RIB.
+ * IRTN_AV fires twice for every I-cache miss returning from RIB to the IFU.
+ * It will not fire if a second I-cache miss is issued from the IFU to RIB
+ * before the first returns.  Therefore, if the IRTN_AV count is much less
+ * than 2x the ICORE_AV count, many speculative I-cache misses are occurring
+ * which are "discovered" to be incorrect fairly quickly.
+ * The ratio of I-cache miss transactions on Runway to the ICORE_AV count is
+ * a measure of the effectiveness of instruction prefetching.  This ratio
+ * should be between 1 and 2.  If it is close to 1, most prefetches are
+ * eventually called for by the IFU; if it is close to 2, almost no prefetches
+ * are useful and they are wasted bus traffic.
+ *
+ * ctr0: counts ICORE_AV 
+ * ctr1: counts IRTN_AV 
+ * ctr2: counts all non-coherent READ transactions on Runway. (TTYPE D0) 
+ *	This should be just I-cache miss and I-prefetch transactions.
+ * ctr3: counts total processor cycles 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x00000008,0x00030c00,0x01bf0001,0x00806fc0,
+0x00c1001b,0xf0005048,0x06fc001c,0x2001bf00,
+0x0908806f,0xc002c300,0x1bf000d0,0xc806fc00,
+0x3fffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0x06bf0000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00110000,00000000,0xd0ffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff,00000000,00000000,
+0xffffffff,0xffffffff },
+
+/* st_cond0
+ *
+ * ctr0: is the overflow for ctr1
+ * ctr1: counts major ops 0C and 0E (fp ops, not fmac or fmpyadd) 
+ * ctr2: counts B,L (including long and push) and GATE (including nullified),
+ *	 predicted not-taken
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc13380,
+0x0101ffff,0xffa1f057,0xe000407f,0xdfffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond1
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major ops 1x (most of the load/stores) 
+ * ctr2: counts CMPB (dw) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc01b80,
+0x0101ffff,0xffb7f03d,0xe000407f,0xffffc8ff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond2
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major op 03 
+ * ctr2: counts CMPIB (dw) predicted not taken. 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc09780,
+0x0101ffff,0xff21f077,0xe000407f,0xffffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond3
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major ops 06 & 26 
+ * ctr2: counts BB, BVB, MOVB, MOVIB (incl. nullified) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc03780,
+0x0101ffff,0xff29f016,0xe000407f,0xffffe97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond4
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major op 2E 
+ * ctr2: counts CMPB, CMPIB, ADDB, ADDIB (incl. nullified) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc17780,
+0x0101ffff,0xff21f014,0xe000407f,0xffffe9ff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_unpred0
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts BE and BE,L 
+ * ctr2: counts BE and BE,L including nullified 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0c0c0e0,0xffffffff,0xffffffff,0xffdf5bbf,
+0xffffffff,0xff25f7d6,0xefffffff,0xffffc97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_unpred1
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts BLR, BV, BVE, BVE,L 
+ * ctr2: counts BLR, BV, BVE, BVE,L including nullified 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0c0c0e0,0xffffffff,0xffffffff,0xffc15f80,
+0x0501ff7f,0xff21f057,0xe001407f,0xdfffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* unpred
+ *
+ * ctr0: counts non-nullified unpredictable branches 
+ * ctr1: is the overflow for ctr0 
+ * ctr2: counts all unpredictable branches (nullified or not) 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0xcc01e000,00000000,0x00060000,00000000,
+0x20202020,0xff31ffff,0xfff7fffe,0x97ffcc7f,
+0xfffffdff,0xffa5fff3,0x1fffffff,0x7fffe97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf00000a0,0x00003c00,0x02f50000,0x0004bd40,
+0x0040802f,0x50002020,0x4bd4000c,0x0042f500,
+0x040014bd,0x40014084,0x2f500060,0x214bd400,
+0x1c2002f5,0x00080804,0xbd400242,0x802f5000,
+0xa0a04bd4,0x002c2042,0xf5000c08,0x14bd4003,
+0x42842f50,0x00e0a14b,0xd4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+   
+
+/* go_store
+ *
+ * ctr0: Overflow for counter 2 
+ * ctr1: Overflow for counter 3 
+ * ctr2: count of GO_STORE_E signal 
+ * ctr3: count of GO_STORE_O signal 
+ */
+
+   {
+   0x0c00e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffa5ffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xff000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x7fffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xf0000000,
+   0x00000000,   0x0000c000,   0x067c0000,   0x01019f00,
+   0x00408067,   0xc0002030,   0x19f0000c,   0x000e7c00,
+   0x0401039f,   0x00014080,   0xe7c00060,   0x3039f000,
+   0x1c00167c,   0x00080105,   0x9f000240,   0x8167c000,
+   0xa03059f0,   0x002c001e,   0x7c000c01,   0x079f0003,
+   0x4081e7c0,   0x00e03079,   0xf0003fc0,   0x07fff800,
+   0xf001fffe,   0x003c007f,   0xff800f00,   0x1fffe003,
+   0xc007fff8,   0x00f001ff,   0xfe003c00,   0x7fff800f,
+   0x001fffe0,   0x03c007ff,   0xf800f001,   0xfffe003c,
+   0x007fff80,   0x0f001fff,   0xe003c007,   0xfff800f0,
+   0x01fffe00,   0x3c007fff,   0x800f001f,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0x70130000,   0x00000000,   0x70000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffaaaa,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffaaaa,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff
+   },
+
+
+/* shlib_call
+ *
+ * ctr0: SharedLib call Depth1 
+ * ctr1: SharedLib call Depth2 
+ * ctr2: SharedLib call Depth3 
+ * ctr3: SharedLib call Depth>3 
+ */
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xc76fa005,   0x07dd7e9c,   0x87115b80,
+   0x01100200,   0x07200004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xf0000000,
+   0xf0000000,   0x00003c20,   0x01ff0808,   0x04007fc0,
+   0x0003001f,   0xf0000180,   0x07fc4010,   0x5001ff00,
+   0x001c007f,   0xc2000a00,   0x1ff18022,   0x4007fc20,
+   0x00b001ff,   0x10003800,   0x7fc8004d,   0x001ff100,
+   0x03c007fc,   0x60012001,   0xff280144,   0x007fc600,
+   0x13001ff2,   0x00058007,   0xfcc00550,   0x01ff2000,
+   0x5c007fca,   0x001a001f,   0xf3801640,   0x07fca001,
+   0xb001ff30,   0x0078007f,   0xd0005d00,   0x1ff30007,
+   0xc007fce0,   0x022001ff,   0x48018400,   0x7fce0023,
+   0x001ff400,   0x098007fd,   0x20065001,   0xff40009c,
+   0x007fd200,   0x3fffffff,   0x800fffff,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff
+   }
+};
+#define PCXW_IMAGE_SIZE 576
+
+static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
+/*
+ * CPI:     FROM CPI.IDF (Image 0)
+ *
+ * Counts the following:
+ *
+ * ctr0 : total cycles
+ * ctr1 : total cycles where nothing retired
+ * ctr2 : total instructions retired, including nullified
+ * ctr3 : total instructions retired, less nullified instructions
+ */
+   {
+   0x4c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x60f00000,   0x0fffff00,   0x000fffff,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00ffffff, 
+   0xfffff000,   0x0000000f,   0xffffffff,   0xff000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x00270000,   0x00000055, 
+   0x0200000e,   0x4d300000,   0x00000000,   0x0ff00002, 
+   0x70000000,   0x00000020,   0x0000e400,   0x00000ff0, 
+   0x00000000,   0x00000000,   0x00000055,   0xffffff00, 
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00000,   0x00000030,   0x00000000, 
+   0x00157fff,   0xffc00000,   0x034c0000,   0x00000000, 
+   0x03fc0000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* Bus utilization image   FROM BUS_UTIL.IDF (Image 1)
+ *
+ * ctr0 : counts address valid cycles
+ * ctr1 : counts data valid cycles
+ * ctr2 : counts overflow from counter 0
+ * ctr3 : counts overflow from counter 1
+ */
+         {
+	 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
+	 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
+	 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+	 0x00000000, 0x00000000, 0x00001b00, 0xaa000000,
+	 0x00000001, 0x30700000, 0x00055aaf, 0xf0000000,
+	 0x01b00000, 0x00000000, 0x00001037, 0x00000000,
+	 0x55aaff00, 0x00c00000, 0x1b55aa00, 0x00000000,
+	 0x0001fff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
+	 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
+	 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
+	 0x0ffff0cf, 0xffff0000, 0x00000000, 0x00ffffff,
+	 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
+	 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
+	 0xfff70000, 0x000055aa, 0xff000000, 0x000006d5,
+	 0x40000000, 0x00000000, 0x731c0000, 0x000156ab,
+	 0xfc000000, 0x00000000, 0xffff0000, 0x00000000,
+	 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
+	 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
+	 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
+	 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
+	 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
+	 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
+	 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
+	 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
+	 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
+	 0xfe000000, 0x00000000, 0x00100000, 0x00000000,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+   },
+
+/*
+ * TLB counts:    FROM TLBSTATS.IDF (Image 2)
+ *
+ * Counts the following:
+ *
+ * ctr0: DTLB misses
+ * ctr1: ITLB misses
+ * ctr2: total cycles in the miss handlers
+ * ctr3: total cycles
+ */
+
+   {
+   0x0c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000, 
+   0x00001000,   0x00000004,   0x00000000,   0x01000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x00800000,   0x00153f7f, 
+   0x55000000,   0xaf800000,   0xc0000000,   0x0403f240, 
+   0x00000000,   0x00001010,   0x00004700,   0x00000ff0, 
+   0x00000000,   0x00000000,   0x00000055,   0xffffff00, 
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00000,   0x00000000,   0x00000000, 
+   0x00157fff,   0xffc00000,   0x00000000,   0x3fc00000, 
+   0x00040000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* tlbhandler  FROM tlbHandMiss.idf (Image 3)
+ *
+ * ctr0: TLB misses
+ * ctr1: dmisses inside the TLB miss handler
+ * ctr2: cycles in the TLB miss handler
+ * ctr3: overflow of ctr2
+ */
+   {
+   0x1c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000, 
+   0x00001000,   0x00000004,   0x00000000,   0x01000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x006c0000,   0x01000054, 
+   0x02000002,   0xc3200000,   0xc00aa000,   0x0c03f240, 
+   0x00000000,   0x00001010,   0x000044f4,   0x00000c00, 
+   0xaa0000f0,   0x0f0000b0,   0x00005005,   0x0f5f0000, 
+   0x0001f000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00a00,   0x000f0000,   0x24004000, 
+   0x15400001,   0x40c00003,   0x3da00000,   0x0002a800, 
+   0x00ff0000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch_taken image  FROM PTKN.IDF (Image 4)
+ *
+ * ctr0: mispredicted branches
+ * ctr1: predicted taken branches, actually taken
+ * ctr2: predicted taken branches (includes nullfied)
+ * ctr3: all branches
+ */
+
+   {
+   0xcc01e000,   0x00000000,   0x00000000,   0x00000000, 
+   0xa08080a0,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfffffeff,   0xfffeffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x0f0fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch_nottaken  FROM PNTKN.IDF (Image 5)
+ *
+ * ctr0: mispredicted branches
+ * ctr1: branches predicted not-taken, but actually taken
+ * ctr2: branches predicted not-taken (includes nullified)
+ * ctr3: all branches
+ */
+   {
+   0xcc01e000,   0x00000000,   0x00000000,   0x00000000, 
+   0xe0c0c0e0,   0xffffffff,   0xffffffff,   0xffefffff, 
+   0xffffbfff,   0xfffffeff,   0xfffeffff,   0xfffffeff, 
+   0xfffffffe,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x0f0fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+   
+/* IMISS image (Image 6)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* DMISS image (Image 7)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* dmiss_access image    FROM DMISS_RATIO.IDF  (Image 8)
+ * 
+ * ctr0 : all loads and stores that retire (even lines)
+ * ctr1 : all loads and stores that retire (odd lines)
+ * ctr2 : dcache misses of retired loads/stores
+ * ctr3 : all READ_PRIV and READ_SHAR_OR_PRIV on Runway
+ *        (Speculative and Non-Speculative)
+ */
+   {
+   0x2d81e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x10101010,   0x00ffffff,   0xa003ffff,   0xfe800fff, 
+   0xfffa003f,   0xffffe8ff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd2280a00,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000005,   0x555ff900, 
+   0x80200000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x00005555,   0xff80bf8b,   0xab030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x15153fe0,   0x27628880, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000001, 
+   0x5557fc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00110000,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xf8ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+
+/* big_cpi image  (Image 9)
+ * 
+ * ctr0 : Total number of CPU clock cycles. 
+ * ctr1 : Unused 
+ * ctr2 : Unused
+ * ctr3 : Total number of Non-Nullified instructions retired. 
+ */
+   {
+   0x0c00c000,   0x00000000,   0x00060000,   0x00000000,
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff,
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff,
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000,
+   0x00001000,   0x00000004,   0x00000000,   0x01000000,
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00550005,   0x00220000,
+   0x0000000c,   0x71f00000,   0x00f00aa0,   0x0aaff000,
+   0x00005002,   0x20000000,   0x0000c413,   0x00000c0f,
+   0x00aa0000,   0xff00b600,   0x000500a0,   0x00000300,
+   0x000cc3f0,   0x0000c0f0,   0x0aa0000f,   0xff000000,
+   0x011000a0,   0x05503000,   0x00d03700,   0x00000f00,
+   0xaa005500,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0xf000aa00,
+   0x11000a00,   0x55000000,   0x0d037000,   0x00c0f00a,
+   0xa0055000,   0x0db00005,   0x5002a000,   0x00300000,
+   0xf40f0000,   0x0c0f00aa,   0x0000ff10,   0x27400000,
+   0x00008000,   0x00c00003,   0x037c0000,   0x003c02a8,
+   0x02abfc00,   0x00000000,   0x6fff0000,   0x00000000,
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* big_ls image  (Image 10)
+ * 
+ * ctr0 : Total number of CPU clock cycles during which local_stall_A1 is asserted 
+ * ctr1 : Overflow of Counter 0 
+ * ctr2 : Total number of IFLUSH_AV 
+ * ctr3 : Overflow of Counter 2 
+ */
+   {
+   0x0c000000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x28880001,   0x54000000,
+   0x00000004,   0xb6200000,   0x000aaaa0,   0x05555288,
+   0x80000010,   0x00000000,   0x0000486e,   0x00000000,
+   0xaaaa0055,   0x55002888,   0x00545401,   0x03030000,
+   0x0007b000,   0x0000ff00,   0x00000000,   0x05000000,
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00000000,
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0xa0000000,   0x00055fff,   0xfff00000,
+   0x00aa0000,   0x05502a2a,   0x00151500,   0x0a220015,
+   0x40400000,   0x00000001,   0xe2980000,   0x0002aaa8,
+   0x01555400,   0x00000000,   0x0df70000,   0x00000000,
+   0x00000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* br_abort image  (Image 12)
+ * 
+ * ctr0 : Total number of BRAD_STALLH
+ * ctr1 : Total number of ONE_QUAD
+ * ctr2 : Total number of BR0_ABRT
+ * ctr3 : Total number of BR1_ABRT
+ */
+
+   {
+   0x0c002000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xffffffff,   0xffffffff,   0xff0fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x1077ffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x551b0000,   0x00000000,
+   0x0000000c,   0xd4f00000,   0x00000000,   0x0ffff001,
+   0xb0000000,   0x00000000,   0x0000fd4c,   0x00000000,
+   0x000000ff,   0xff00ff1b,   0x00000000,   0x00000000,
+   0x0000d000,   0x0000ff00,   0x00000000,   0x0e0fffff,
+   0xffffffff,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0xffffffff,   0xffffffff,   0xfff00000,
+   0x00400000,   0x00000000,   0x00ffff00,   0x2a86c000,
+   0x00000000,   0x00000000,   0xf50c0000,   0x00000000,
+   0x03fffc00,   0x00000000,   0x1a250000,   0x00000000,
+   0x10000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+
+/* isnt image  (Image 13)
+ * 
+ * ctr0 : Total number of cycles for which iside_notrans is asserted. 
+ * ctr1 : Total number of times iside_notrans is asserted for 1-4 cycles. 
+ * ctr2 : Total number of times iside_notrans is asserted for 5-7 cycles. 
+ * ctr3 : Total number of times iside_notrans is asserted for > 7 cycles. 
+ */
+
+   {
+   0x0c018000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xc0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x22000000,   0x000001bc,
+   0x10000006,   0x00900000,   0x50000000,   0x00055a20,
+   0x00000000,   0x00016060,   0x0000c021,   0x00000540,
+   0x00000000,   0x55002200,   0x00000000,   0x56bc4000,
+   0x00048000,   0x0000ff00,   0x00000000,   0x17000000,
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00000000,
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0x80000000,   0x00015bf3,   0xf5500000,
+   0x02210000,   0x00100000,   0x00005500,   0x08800000,
+   0x00001545,   0x85000001,   0x80240000,   0x11000000,
+   0x00015400,   0x00000000,   0xcdff0000,   0x00000000,
+   0xc0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* quadrant image  (image 14)
+ * 
+ * ctr0 : Total number of instructions in quadrant 0. 
+ * ctr1 : Total number of instructions in quadrant 1. 
+ * ctr2 : Total number of instructions in quadrant 2. 
+ * ctr3 : Total number of instructions in quadrant 3. 
+ *
+ * Only works for 32-bit applications.
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x0007ffff,
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0xf0000000,   0x0fffff00,   0x000fffff,   0x00000fff,
+   0xff00000f,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000040f,   0xfffffffc,   0xff000000,
+   0x0080ffff,   0xffffcff0,   0x0000000c,   0x0fffffff,
+   0xfcff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x551b0000,   0x00000000,
+   0x00000003,   0x17000000,   0x00000000,   0x0ffff001,
+   0xb0000000,   0x00000000,   0x00000173,   0x00000000,
+   0x000000ff,   0xff00ff1b,   0x00000000,   0x00000000,
+   0x000f1ff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xff7f0000,   0x00000000,   0x00fffff0,   0x2a86c000,
+   0x00000000,   0x00000003,   0x05f00000,   0x00000000,
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* rw_pdfet image (Image 15)
+ * 
+ * ctr0 : Total of all READ_PRIV address valid cycles. 
+ * ctr1 : Total of all READ_PRIV data valid cycles. 
+ * ctr2 : Overflow of Counter 0. 
+ * ctr3 : Overflow of Counter 1. 
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00001b00,   0xaa000000,
+   0x00000001,   0x30700000,   0x00055aaf,   0xf0000000,
+   0x01b00000,   0x00000000,   0x00001037,   0x00000000,
+   0x55aaff00,   0x00c00000,   0x1b55aa00,   0x00000000,
+   0x0001fff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xfff70000,   0x000055aa,   0xff000000,   0x000006d5,
+   0x40000000,   0x00000000,   0x731c0000,   0x000156ab,
+   0xfc000000,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00100000,   0x00000000,
+   0xf8000000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   },
+
+
+/* rw_wdfet image  (Image 16)
+ * 
+ * ctr0 : Counts total number of writeback transactions. 
+ * ctr1 : Total number of data valid Runway cycles. 
+ * ctr2 : Overflow of Counter 0. 
+ * ctr3 : Overflow of Counter 1. 
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00001b00,   0xaa000000,
+   0x00000001,   0x30700000,   0x00055aaf,   0xf0000000,
+   0x01b00000,   0x00000000,   0x00001037,   0x00000000,
+   0x55aaff00,   0x00c00000,   0x1b55aa00,   0x00000000,
+   0x0001fff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xfff70000,   0x000055aa,   0xff000000,   0x000006d5,
+   0x40000000,   0x00000000,   0x731c0000,   0x000156ab,
+   0xfc000000,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00100000,   0x00000000,
+   0x98000000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   },
+
+/* shlib_cpi image  (Image 17)
+ * 
+ * ctr0 : Total number of instructions in quadrant 0. 
+ * ctr1 : Total number of CPU clock cycles in quadrant 0. 
+ * ctr2 : Total number of Non-Nullified instructions retired. 
+ * ctr3 : Total number of CPU clock cycles. 
+ *
+ * Only works for 32-bit shared libraries.
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x0007ffff,
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0xf0150000,   0x0fffff00,   0x000fffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000000f,   0xfffffffc,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x27000000,   0x00000055,
+   0x02000005,   0x7f500000,   0xc0000000,   0x000ff270,
+   0x00000000,   0x00000000,   0x00007700,   0x00000ff0,
+   0x00000000,   0x0000ffff,   0xffffffff,   0xffffff00,
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xfff00000,
+   0x00000000,   0x0ff00000,   0x000000a0,   0x3fffffff,
+   0xffffffff,   0xffc00000,   0x03d40000,   0x20000000,
+   0x0003fc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* flop image  (Image 18)
+ * 
+ * ctr0 : Total number of floating point instructions (opcode = 0xc). 
+ * ctr1 : Total number of floating point instructions (opcode = 0xe, 0x6, 0x2e, 0x26). 
+ * ctr2 : Unused
+ * ctr3 : Unused 
+ */
+
+   {
+   0x0001e000,   0x00000000,   0x00000000,   0x00000000,
+   0x00001010,   0x33ffffff,   0x006fffff,   0xfc5fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000,
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900,
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000,
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000,
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff,
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000,
+   0x00000000,   0x00000002,   0x67840000,   0x00000000,
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* cachemiss image    FROM I_D_MISSES.IDF  (Image 19)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch   FROM br_report3.idf 
+ *
+ * ctr0 : Total number of mispredicted branches. 
+ * ctr1 : Some Non-Nullified unpredictable branches. 
+ * ctr2 : Total number of branches (Nullified + Non-Nullified)
+ *        (Unpredicted+ Predicted Taken +Predicted Not Taken). 
+ *	  Total of All Branches.
+ * ctr3 : Remaining Non-Nullified unpredictable branches.
+ */
+   {
+   0x4001e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0xffffffff,   0xff9fffff,   0xfe0fffff, 
+   0xffffbaff,   0xfdffc0ff,   0xfffdffff,   0xfffffeff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* crstack  FROM crs_report.idf
+ *
+ * ctr0: correctly predicted branches by the pop_latch
+ * ctr1: some procedure returns
+ * ctr2: all branches, (includes nullified)
+ * ctr3: remaining procedure returns
+ */
+   {
+   0x4001e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0xffffffff,   0xffa10300,   0x000fffff, 
+   0xffffbaf8,   0x3000007f,   0xffffffff,   0xfffffeff, 
+   0xff7fffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf2ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* icache_report image 
+ * 
+ * ctr0 : Icache misses actually used by the core. 
+ * ctr1 : ICORE_AV (Icache misses the core THINKS it needs, including fetching down speculative paths). 
+ * ctr2 : READs on Runway (Icache misses that made it out to Runway, including
+ *	  prefetches).
+ * ctr3 : Prefetch returns (1x and 2x). 
+ */
+   {
+   0x00000000,   0x00000000,   0x00010000,   0x00000000,
+   0x00000000,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xd2002d00,   0x00000000,
+   0x0000000b,   0x46000000,   0x0000000f,   0xf00ff900,
+   0x00900000,   0x00000000,   0x0000907e,   0x00000000,
+   0x0000ff00,   0xff83bf03,   0xdf030303,   0x03030000,
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x80ffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x4fffffff,   0xffffffff,   0xffffffff,
+   0xffff5555,   0x55500000,   0x3f003f80,   0x274026c0,
+   0x00000000,   0x00000002,   0x67840000,   0x00000003,
+   0xfc03fc00,   0x00000000,   0x0eff0000,   0x00000000,
+   0x00000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000,
+   0xd0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   
+   }
+
+};
+
+#endif
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
new file mode 100644
index 0000000..eb39e7e
--- /dev/null
+++ b/arch/parisc/kernel/process.c
@@ -0,0 +1,342 @@
+/*
+ *    PARISC Architecture-dependent parts of process handling
+ *    based on the work for i386
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com>
+ *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001-2014 Helge Deller <deller@gmx.de>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *
+ *
+ *    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
+ */
+
+#include <stdarg.h>
+
+#include <linux/elf.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/sched/task.h>
+#include <linux/sched/task_stack.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <linux/rcupdate.h>
+#include <linux/random.h>
+#include <linux/nmi.h>
+
+#include <asm/io.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembly.h>
+#include <asm/pdc.h>
+#include <asm/pdc_chassis.h>
+#include <asm/pgalloc.h>
+#include <asm/unwind.h>
+#include <asm/sections.h>
+
+#define COMMAND_GLOBAL  F_EXTEND(0xfffe0030)
+#define CMD_RESET       5       /* reset any module */
+
+/*
+** The Wright Brothers and Gecko systems have a H/W problem
+** (Lasi...'nuf said) may cause a broadcast reset to lockup
+** the system. An HVERSION dependent PDC call was developed
+** to perform a "safe", platform specific broadcast reset instead
+** of kludging up all the code.
+**
+** Older machines which do not implement PDC_BROADCAST_RESET will
+** return (with an error) and the regular broadcast reset can be
+** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
+** the PDC call will not return (the system will be reset).
+*/
+void machine_restart(char *cmd)
+{
+#ifdef FASTBOOT_SELFTEST_SUPPORT
+	/*
+	 ** If user has modified the Firmware Selftest Bitmap,
+	 ** run the tests specified in the bitmap after the
+	 ** system is rebooted w/PDC_DO_RESET.
+	 **
+	 ** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
+	 **
+	 ** Using "directed resets" at each processor with the MEM_TOC
+	 ** vector cleared will also avoid running destructive
+	 ** memory self tests. (Not implemented yet)
+	 */
+	if (ftc_bitmap) {
+		pdc_do_firm_test_reset(ftc_bitmap);
+	}
+#endif
+	/* set up a new led state on systems shipped with a LED State panel */
+	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
+	
+	/* "Normal" system reset */
+	pdc_do_reset();
+
+	/* Nope...box should reset with just CMD_RESET now */
+	gsc_writel(CMD_RESET, COMMAND_GLOBAL);
+
+	/* Wait for RESET to lay us to rest. */
+	while (1) ;
+
+}
+
+void (*chassis_power_off)(void);
+
+/*
+ * This routine is called from sys_reboot to actually turn off the
+ * machine 
+ */
+void machine_power_off(void)
+{
+	/* If there is a registered power off handler, call it. */
+	if (chassis_power_off)
+		chassis_power_off();
+
+	/* Put the soft power button back under hardware control.
+	 * If the user had already pressed the power button, the
+	 * following call will immediately power off. */
+	pdc_soft_power_button(0);
+	
+	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
+
+	/* ipmi_poweroff may have been installed. */
+	if (pm_power_off)
+		pm_power_off();
+		
+	/* It seems we have no way to power the system off via
+	 * software. The user has to press the button himself. */
+
+	printk(KERN_EMERG "System shut down completed.\n"
+	       "Please power this system off now.");
+
+	/* prevent soft lockup/stalled CPU messages for endless loop. */
+	rcu_sysrq_start();
+	lockup_detector_soft_poweroff();
+	for (;;);
+}
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+void machine_halt(void)
+{
+	machine_power_off();
+}
+
+void flush_thread(void)
+{
+	/* Only needs to handle fpu stuff or perf monitors.
+	** REVISIT: several arches implement a "lazy fpu state".
+	*/
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+}
+
+/*
+ * Fill in the FPU structure for a core dump.
+ */
+
+int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
+{
+	if (regs == NULL)
+		return 0;
+
+	memcpy(r, regs->fr, sizeof *r);
+	return 1;
+}
+
+int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
+{
+	memcpy(r, tsk->thread.regs.fr, sizeof(*r));
+	return 1;
+}
+
+/*
+ * Idle thread support
+ *
+ * Detect when running on QEMU with SeaBIOS PDC Firmware and let
+ * QEMU idle the host too.
+ */
+
+int running_on_qemu __read_mostly;
+
+void __cpuidle arch_cpu_idle_dead(void)
+{
+	/* nop on real hardware, qemu will offline CPU. */
+	asm volatile("or %%r31,%%r31,%%r31\n":::);
+}
+
+void __cpuidle arch_cpu_idle(void)
+{
+	local_irq_enable();
+
+	/* nop on real hardware, qemu will idle sleep. */
+	asm volatile("or %%r10,%%r10,%%r10\n":::);
+}
+
+static int __init parisc_idle_init(void)
+{
+	const char *marker;
+
+	/* check QEMU/SeaBIOS marker in PAGE0 */
+	marker = (char *) &PAGE0->pad0;
+	running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0);
+
+	if (!running_on_qemu)
+		cpu_idle_poll_ctrl(1);
+
+	return 0;
+}
+arch_initcall(parisc_idle_init);
+
+/*
+ * Copy architecture-specific thread state
+ */
+int
+copy_thread(unsigned long clone_flags, unsigned long usp,
+	    unsigned long kthread_arg, struct task_struct *p)
+{
+	struct pt_regs *cregs = &(p->thread.regs);
+	void *stack = task_stack_page(p);
+	
+	/* We have to use void * instead of a function pointer, because
+	 * function pointers aren't a pointer to the function on 64-bit.
+	 * Make them const so the compiler knows they live in .text */
+	extern void * const ret_from_kernel_thread;
+	extern void * const child_return;
+
+	if (unlikely(p->flags & PF_KTHREAD)) {
+		/* kernel thread */
+		memset(cregs, 0, sizeof(struct pt_regs));
+		if (!usp) /* idle thread */
+			return 0;
+		/* Must exit via ret_from_kernel_thread in order
+		 * to call schedule_tail()
+		 */
+		cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
+		cregs->kpc = (unsigned long) &ret_from_kernel_thread;
+		/*
+		 * Copy function and argument to be called from
+		 * ret_from_kernel_thread.
+		 */
+#ifdef CONFIG_64BIT
+		cregs->gr[27] = ((unsigned long *)usp)[3];
+		cregs->gr[26] = ((unsigned long *)usp)[2];
+#else
+		cregs->gr[26] = usp;
+#endif
+		cregs->gr[25] = kthread_arg;
+	} else {
+		/* user thread */
+		/* usp must be word aligned.  This also prevents users from
+		 * passing in the value 1 (which is the signal for a special
+		 * return for a kernel thread) */
+		if (usp) {
+			usp = ALIGN(usp, 4);
+			if (likely(usp))
+				cregs->gr[30] = usp;
+		}
+		cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
+		cregs->kpc = (unsigned long) &child_return;
+
+		/* Setup thread TLS area from the 4th parameter in clone */
+		if (clone_flags & CLONE_SETTLS)
+			cregs->cr27 = cregs->gr[23];
+	}
+
+	return 0;
+}
+
+unsigned long
+get_wchan(struct task_struct *p)
+{
+	struct unwind_frame_info info;
+	unsigned long ip;
+	int count = 0;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	/*
+	 * These bracket the sleeping functions..
+	 */
+
+	unwind_frame_init_from_blocked_task(&info, p);
+	do {
+		if (unwind_once(&info) < 0)
+			return 0;
+		ip = info.ip;
+		if (!in_sched_functions(ip))
+			return ip;
+	} while (count++ < MAX_UNWIND_ENTRIES);
+	return 0;
+}
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+	Elf64_Fdesc *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->addr, p))
+		ptr = p;
+	return ptr;
+}
+
+void *dereference_kernel_function_descriptor(void *ptr)
+{
+	if (ptr < (void *)__start_opd ||
+			ptr >= (void *)__end_opd)
+		return ptr;
+
+	return dereference_function_descriptor(ptr);
+}
+#endif
+
+static inline unsigned long brk_rnd(void)
+{
+	return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+
+	if (ret < mm->brk)
+		return mm->brk;
+	return ret;
+}
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
new file mode 100644
index 0000000..82bd0d0
--- /dev/null
+++ b/arch/parisc/kernel/processor.c
@@ -0,0 +1,469 @@
+/*
+ *    Initial setup-routines for HP 9000 based hardware.
+ *
+ *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *    Modifications for PA-RISC (C) 1999-2008 Helge Deller <deller@gmx.de>
+ *    Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
+ *    Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
+ *    Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *    Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
+ *
+ *    Initial PA-RISC Version: 04-23-1999 by Helge Deller
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <asm/param.h>
+#include <asm/cache.h>
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
+#include <asm/irq.h>		/* for struct irq_region */
+#include <asm/parisc-device.h>
+
+struct system_cpuinfo_parisc boot_cpu_data __read_mostly;
+EXPORT_SYMBOL(boot_cpu_data);
+#ifdef CONFIG_PA8X00
+int _parisc_requires_coherency __read_mostly;
+EXPORT_SYMBOL(_parisc_requires_coherency);
+#endif
+
+DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data);
+
+/*
+**  	PARISC CPU driver - claim "device" and initialize CPU data structures.
+**
+** Consolidate per CPU initialization into (mostly) one module.
+** Monarch CPU will initialize boot_cpu_data which shouldn't
+** change once the system has booted.
+**
+** The callback *should* do per-instance initialization of
+** everything including the monarch. "Per CPU" init code in
+** setup.c:start_parisc() has migrated here and start_parisc()
+** will call register_parisc_driver(&cpu_driver) before calling do_inventory().
+**
+** The goal of consolidating CPU initialization into one place is
+** to make sure all CPUs get initialized the same way.
+** The code path not shared is how PDC hands control of the CPU to the OS.
+** The initialization of OS data structures is the same (done below).
+*/
+
+/**
+ * init_cpu_profiler - enable/setup per cpu profiling hooks.
+ * @cpunum: The processor instance.
+ *
+ * FIXME: doesn't do much yet...
+ */
+static void
+init_percpu_prof(unsigned long cpunum)
+{
+}
+
+
+/**
+ * processor_probe - Determine if processor driver should claim this device.
+ * @dev: The device which has been found.
+ *
+ * Determine if processor driver should claim this chip (return 0) or not 
+ * (return 1).  If so, initialize the chip and tell other partners in crime 
+ * they have work to do.
+ */
+static int __init processor_probe(struct parisc_device *dev)
+{
+	unsigned long txn_addr;
+	unsigned long cpuid;
+	struct cpuinfo_parisc *p;
+	struct pdc_pat_cpu_num cpu_info = { };
+
+#ifdef CONFIG_SMP
+	if (num_online_cpus() >= nr_cpu_ids) {
+		printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n");
+		return 1;
+	}
+#else
+	if (boot_cpu_data.cpu_count > 0) {
+		printk(KERN_INFO "CONFIG_SMP=n  ignoring additional CPUs\n");
+		return 1;
+	}
+#endif
+
+	/* logical CPU ID and update global counter
+	 * May get overwritten by PAT code.
+	 */
+	cpuid = boot_cpu_data.cpu_count;
+	txn_addr = dev->hpa.start;	/* for legacy PDC */
+	cpu_info.cpu_num = cpu_info.cpu_loc = cpuid;
+
+#ifdef CONFIG_64BIT
+	if (is_pdc_pat()) {
+		ulong status;
+		unsigned long bytecnt;
+	        pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell;
+
+		pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL);
+		if (!pa_pdc_cell)
+			panic("couldn't allocate memory for PDC_PAT_CELL!");
+
+		status = pdc_pat_cell_module(&bytecnt, dev->pcell_loc,
+			dev->mod_index, PA_VIEW, pa_pdc_cell);
+
+		BUG_ON(PDC_OK != status);
+
+		/* verify it's the same as what do_pat_inventory() found */
+		BUG_ON(dev->mod_info != pa_pdc_cell->mod_info);
+		BUG_ON(dev->pmod_loc != pa_pdc_cell->mod_location);
+
+		txn_addr = pa_pdc_cell->mod[0];   /* id_eid for IO sapic */
+
+		kfree(pa_pdc_cell);
+
+		/* get the cpu number */
+		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
+		BUG_ON(PDC_OK != status);
+
+		pr_info("Logical CPU #%lu is physical cpu #%lu at location "
+			"0x%lx with hpa %pa\n",
+			cpuid, cpu_info.cpu_num, cpu_info.cpu_loc,
+			&dev->hpa.start);
+
+#undef USE_PAT_CPUID
+#ifdef USE_PAT_CPUID
+/* We need contiguous numbers for cpuid. Firmware's notion
+ * of cpuid is for physical CPUs and we just don't care yet.
+ * We'll care when we need to query PAT PDC about a CPU *after*
+ * boot time (ie shutdown a CPU from an OS perspective).
+ */
+		if (cpu_info.cpu_num >= NR_CPUS) {
+			printk(KERN_WARNING "IGNORING CPU at %pa,"
+				" cpu_slot_id > NR_CPUS"
+				" (%ld > %d)\n",
+				&dev->hpa.start, cpu_info.cpu_num, NR_CPUS);
+			/* Ignore CPU since it will only crash */
+			boot_cpu_data.cpu_count--;
+			return 1;
+		} else {
+			cpuid = cpu_info.cpu_num;
+		}
+#endif
+	}
+#endif
+
+	p = &per_cpu(cpu_data, cpuid);
+	boot_cpu_data.cpu_count++;
+
+	/* initialize counters - CPU 0 gets it_value set in time_init() */
+	if (cpuid)
+		memset(p, 0, sizeof(struct cpuinfo_parisc));
+
+	p->loops_per_jiffy = loops_per_jiffy;
+	p->dev = dev;		/* Save IODC data in case we need it */
+	p->hpa = dev->hpa.start;	/* save CPU hpa */
+	p->cpuid = cpuid;	/* save CPU id */
+	p->txn_addr = txn_addr;	/* save CPU IRQ address */
+	p->cpu_num = cpu_info.cpu_num;
+	p->cpu_loc = cpu_info.cpu_loc;
+
+	store_cpu_topology(cpuid);
+
+#ifdef CONFIG_SMP
+	/*
+	** FIXME: review if any other initialization is clobbered
+	**	  for boot_cpu by the above memset().
+	*/
+	init_percpu_prof(cpuid);
+#endif
+
+	/*
+	** CONFIG_SMP: init_smp_config() will attempt to get CPUs into
+	** OS control. RENDEZVOUS is the default state - see mem_set above.
+	**	p->state = STATE_RENDEZVOUS;
+	*/
+
+#if 0
+	/* CPU 0 IRQ table is statically allocated/initialized */
+	if (cpuid) {
+		struct irqaction actions[];
+
+		/*
+		** itimer and ipi IRQ handlers are statically initialized in
+		** arch/parisc/kernel/irq.c. ie Don't need to register them.
+		*/
+		actions = kmalloc(sizeof(struct irqaction)*MAX_CPU_IRQ, GFP_ATOMIC);
+		if (!actions) {
+			/* not getting it's own table, share with monarch */
+			actions = cpu_irq_actions[0];
+		}
+
+		cpu_irq_actions[cpuid] = actions;
+	}
+#endif
+
+	/* 
+	 * Bring this CPU up now! (ignore bootstrap cpuid == 0)
+	 */
+#ifdef CONFIG_SMP
+	if (cpuid) {
+		set_cpu_present(cpuid, true);
+		cpu_up(cpuid);
+	}
+#endif
+
+	return 0;
+}
+
+/**
+ * collect_boot_cpu_data - Fill the boot_cpu_data structure.
+ *
+ * This function collects and stores the generic processor information
+ * in the boot_cpu_data structure.
+ */
+void __init collect_boot_cpu_data(void)
+{
+	unsigned long cr16_seed;
+
+	memset(&boot_cpu_data, 0, sizeof(boot_cpu_data));
+
+	cr16_seed = get_cycles();
+	add_device_randomness(&cr16_seed, sizeof(cr16_seed));
+
+	boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
+
+	/* get CPU-Model Information... */
+#define p ((unsigned long *)&boot_cpu_data.pdc.model)
+	if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) {
+		printk(KERN_INFO 
+			"model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
+
+		add_device_randomness(&boot_cpu_data.pdc.model,
+			sizeof(boot_cpu_data.pdc.model));
+	}
+#undef p
+
+	if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) {
+		printk(KERN_INFO "vers  %08lx\n", 
+			boot_cpu_data.pdc.versions);
+
+		add_device_randomness(&boot_cpu_data.pdc.versions,
+			sizeof(boot_cpu_data.pdc.versions));
+	}
+
+	if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) {
+		printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n",
+			(boot_cpu_data.pdc.cpuid >> 5) & 127,
+			boot_cpu_data.pdc.cpuid & 31,
+			boot_cpu_data.pdc.cpuid);
+
+		add_device_randomness(&boot_cpu_data.pdc.cpuid,
+			sizeof(boot_cpu_data.pdc.cpuid));
+	}
+
+	if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK)
+		printk(KERN_INFO "capabilities 0x%lx\n",
+			boot_cpu_data.pdc.capabilities);
+
+	if (pdc_model_sysmodel(boot_cpu_data.pdc.sys_model_name) == PDC_OK)
+		printk(KERN_INFO "model %s\n",
+			boot_cpu_data.pdc.sys_model_name);
+
+	dump_stack_set_arch_desc("%s", boot_cpu_data.pdc.sys_model_name);
+
+	boot_cpu_data.hversion =  boot_cpu_data.pdc.model.hversion;
+	boot_cpu_data.sversion =  boot_cpu_data.pdc.model.sversion;
+
+	boot_cpu_data.cpu_type = parisc_get_cpu_type(boot_cpu_data.hversion);
+	boot_cpu_data.cpu_name = cpu_name_version[boot_cpu_data.cpu_type][0];
+	boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
+
+#ifdef CONFIG_PA8X00
+	_parisc_requires_coherency = (boot_cpu_data.cpu_type == mako) ||
+				(boot_cpu_data.cpu_type == mako2);
+#endif
+}
+
+
+/**
+ * init_per_cpu - Handle individual processor initializations.
+ * @cpunum: logical processor number.
+ *
+ * This function handles initialization for *every* CPU
+ * in the system:
+ *
+ * o Set "default" CPU width for trap handlers
+ *
+ * o Enable FP coprocessor
+ *   REVISIT: this could be done in the "code 22" trap handler.
+ *	(frowands idea - that way we know which processes need FP
+ *	registers saved on the interrupt stack.)
+ *   NEWS FLASH: wide kernels need FP coprocessor enabled to handle
+ *	formatted printing of %lx for example (double divides I think)
+ *
+ * o Enable CPU profiling hooks.
+ */
+int __init init_per_cpu(int cpunum)
+{
+	int ret;
+	struct pdc_coproc_cfg coproc_cfg;
+
+	set_firmware_width();
+	ret = pdc_coproc_cfg(&coproc_cfg);
+
+	store_cpu_topology(cpunum);
+
+	if(ret >= 0 && coproc_cfg.ccr_functional) {
+		mtctl(coproc_cfg.ccr_functional, 10);  /* 10 == Coprocessor Control Reg */
+
+		/* FWIW, FP rev/model is a more accurate way to determine
+		** CPU type. CPU rev/model has some ambiguous cases.
+		*/
+		per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
+		per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
+
+		if (cpunum == 0)
+			printk(KERN_INFO  "FP[%d] enabled: Rev %ld Model %ld\n",
+				cpunum, coproc_cfg.revision, coproc_cfg.model);
+
+		/*
+		** store status register to stack (hopefully aligned)
+		** and clear the T-bit.
+		*/
+		asm volatile ("fstd    %fr0,8(%sp)");
+
+	} else {
+		printk(KERN_WARNING  "WARNING: No FP CoProcessor?!"
+			" (coproc_cfg.ccr_functional == 0x%lx, expected 0xc0)\n"
+#ifdef CONFIG_64BIT
+			"Halting Machine - FP required\n"
+#endif
+			, coproc_cfg.ccr_functional);
+#ifdef CONFIG_64BIT
+		mdelay(100);	/* previous chars get pushed to console */
+		panic("FP CoProc not reported");
+#endif
+	}
+
+	/* FUTURE: Enable Performance Monitor : ccr bit 0x20 */
+	init_percpu_prof(cpunum);
+
+	return ret;
+}
+
+/*
+ * Display CPU info for all CPUs.
+ */
+int
+show_cpuinfo (struct seq_file *m, void *v)
+{
+	unsigned long cpu;
+
+	for_each_online_cpu(cpu) {
+		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+#ifdef CONFIG_SMP
+		if (0 == cpuinfo->hpa)
+			continue;
+#endif
+		seq_printf(m, "processor\t: %lu\n"
+				"cpu family\t: PA-RISC %s\n",
+				 cpu, boot_cpu_data.family_name);
+
+		seq_printf(m, "cpu\t\t: %s\n",  boot_cpu_data.cpu_name );
+
+		/* cpu MHz */
+		seq_printf(m, "cpu MHz\t\t: %d.%06d\n",
+				 boot_cpu_data.cpu_hz / 1000000,
+				 boot_cpu_data.cpu_hz % 1000000  );
+
+#ifdef CONFIG_PARISC_CPU_TOPOLOGY
+		seq_printf(m, "physical id\t: %d\n",
+				topology_physical_package_id(cpu));
+		seq_printf(m, "siblings\t: %d\n",
+				cpumask_weight(topology_core_cpumask(cpu)));
+		seq_printf(m, "core id\t\t: %d\n", topology_core_id(cpu));
+#endif
+
+		seq_printf(m, "capabilities\t:");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
+			seq_puts(m, " os32");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
+			seq_puts(m, " os64");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC)
+			seq_puts(m, " iopdir_fdc");
+		switch (boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) {
+		case PDC_MODEL_NVA_SUPPORTED:
+			seq_puts(m, " nva_supported");
+			break;
+		case PDC_MODEL_NVA_SLOW:
+			seq_puts(m, " nva_slow");
+			break;
+		case PDC_MODEL_NVA_UNSUPPORTED:
+			seq_puts(m, " needs_equivalent_aliasing");
+			break;
+		}
+		seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities);
+
+		seq_printf(m, "model\t\t: %s\n"
+				"model name\t: %s\n",
+				 boot_cpu_data.pdc.sys_model_name,
+				 cpuinfo->dev ?
+				 cpuinfo->dev->name : "Unknown");
+
+		seq_printf(m, "hversion\t: 0x%08x\n"
+			        "sversion\t: 0x%08x\n",
+				 boot_cpu_data.hversion,
+				 boot_cpu_data.sversion );
+
+		/* print cachesize info */
+		show_cache_info(m);
+
+		seq_printf(m, "bogomips\t: %lu.%02lu\n",
+			     cpuinfo->loops_per_jiffy / (500000 / HZ),
+			     (cpuinfo->loops_per_jiffy / (5000 / HZ)) % 100);
+
+		seq_printf(m, "software id\t: %ld\n\n",
+				boot_cpu_data.pdc.model.sw_id);
+	}
+	return 0;
+}
+
+static const struct parisc_device_id processor_tbl[] __initconst = {
+	{ HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID },
+	{ 0, }
+};
+
+static struct parisc_driver cpu_driver __refdata = {
+	.name		= "CPU",
+	.id_table	= processor_tbl,
+	.probe		= processor_probe
+};
+
+/**
+ * processor_init - Processor initialization procedure.
+ *
+ * Register this driver.
+ */
+void __init processor_init(void)
+{
+	register_parisc_driver(&cpu_driver);
+}
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
new file mode 100644
index 0000000..2582df1
--- /dev/null
+++ b/arch/parisc/kernel/ptrace.c
@@ -0,0 +1,778 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kernel support for the ptrace() and syscall tracing interfaces.
+ *
+ * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
+ * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
+ * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
+ * Copyright (C) 2008-2016 Helge Deller <deller@gmx.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/elf.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/tracehook.h>
+#include <linux/user.h>
+#include <linux/personality.h>
+#include <linux/regset.h>
+#include <linux/security.h>
+#include <linux/seccomp.h>
+#include <linux/compat.h>
+#include <linux/signal.h>
+#include <linux/audit.h>
+
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+
+/* PSW bits we allow the debugger to modify */
+#define USER_PSW_BITS	(PSW_N | PSW_B | PSW_V | PSW_CB)
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
+/*
+ * These are our native regset flavors.
+ */
+enum parisc_regset {
+	REGSET_GENERAL,
+	REGSET_FP
+};
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *task)
+{
+	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+	clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
+
+	/* make sure the trap bits are not set */
+	pa_psw(task)->r = 0;
+	pa_psw(task)->t = 0;
+	pa_psw(task)->h = 0;
+	pa_psw(task)->l = 0;
+}
+
+/*
+ * The following functions are called by ptrace_resume() when
+ * enabling or disabling single/block tracing.
+ */
+void user_disable_single_step(struct task_struct *task)
+{
+	ptrace_disable(task);
+}
+
+void user_enable_single_step(struct task_struct *task)
+{
+	clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
+	set_tsk_thread_flag(task, TIF_SINGLESTEP);
+
+	if (pa_psw(task)->n) {
+		/* Nullified, just crank over the queue. */
+		task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
+		task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
+		task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
+		pa_psw(task)->n = 0;
+		pa_psw(task)->x = 0;
+		pa_psw(task)->y = 0;
+		pa_psw(task)->z = 0;
+		pa_psw(task)->b = 0;
+		ptrace_disable(task);
+		/* Don't wake up the task, but let the
+		   parent know something happened. */
+		force_sig_fault(SIGTRAP, TRAP_TRACE,
+				(void __user *) (task_regs(task)->iaoq[0] & ~3),
+				task);
+		/* notify_parent(task, SIGCHLD); */
+		return;
+	}
+
+	/* Enable recovery counter traps.  The recovery counter
+	 * itself will be set to zero on a task switch.  If the
+	 * task is suspended on a syscall then the syscall return
+	 * path will overwrite the recovery counter with a suitable
+	 * value such that it traps once back in user space.  We
+	 * disable interrupts in the tasks PSW here also, to avoid
+	 * interrupts while the recovery counter is decrementing.
+	 */
+	pa_psw(task)->r = 1;
+	pa_psw(task)->t = 0;
+	pa_psw(task)->h = 0;
+	pa_psw(task)->l = 0;
+}
+
+void user_enable_block_step(struct task_struct *task)
+{
+	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+	set_tsk_thread_flag(task, TIF_BLOCKSTEP);
+
+	/* Enable taken branch trap. */
+	pa_psw(task)->r = 0;
+	pa_psw(task)->t = 1;
+	pa_psw(task)->h = 0;
+	pa_psw(task)->l = 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+		 unsigned long addr, unsigned long data)
+{
+	unsigned long __user *datap = (unsigned long __user *)data;
+	unsigned long tmp;
+	long ret = -EIO;
+
+	switch (request) {
+
+	/* Read the word at location addr in the USER area.  For ptraced
+	   processes, the kernel saves all regs on a syscall. */
+	case PTRACE_PEEKUSR:
+		if ((addr & (sizeof(unsigned long)-1)) ||
+		     addr >= sizeof(struct pt_regs))
+			break;
+		tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
+		ret = put_user(tmp, datap);
+		break;
+
+	/* Write the word at location addr in the USER area.  This will need
+	   to change when the kernel no longer saves all regs on a syscall.
+	   FIXME.  There is a problem at the moment in that r3-r18 are only
+	   saved if the process is ptraced on syscall entry, and even then
+	   those values are overwritten by actual register values on syscall
+	   exit. */
+	case PTRACE_POKEUSR:
+		/* Some register values written here may be ignored in
+		 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
+		 * r31/r31+4, and not with the values in pt_regs.
+		 */
+		if (addr == PT_PSW) {
+			/* Allow writing to Nullify, Divide-step-correction,
+			 * and carry/borrow bits.
+			 * BEWARE, if you set N, and then single step, it won't
+			 * stop on the nullified instruction.
+			 */
+			data &= USER_PSW_BITS;
+			task_regs(child)->gr[0] &= ~USER_PSW_BITS;
+			task_regs(child)->gr[0] |= data;
+			ret = 0;
+			break;
+		}
+
+		if ((addr & (sizeof(unsigned long)-1)) ||
+		     addr >= sizeof(struct pt_regs))
+			break;
+		if ((addr >= PT_GR1 && addr <= PT_GR31) ||
+				addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
+				(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
+				addr == PT_SAR) {
+			*(unsigned long *) ((char *) task_regs(child) + addr) = data;
+			ret = 0;
+		}
+		break;
+
+	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
+		return copy_regset_to_user(child,
+					   task_user_regset_view(current),
+					   REGSET_GENERAL,
+					   0, sizeof(struct user_regs_struct),
+					   datap);
+
+	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
+		return copy_regset_from_user(child,
+					     task_user_regset_view(current),
+					     REGSET_GENERAL,
+					     0, sizeof(struct user_regs_struct),
+					     datap);
+
+	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
+		return copy_regset_to_user(child,
+					   task_user_regset_view(current),
+					   REGSET_FP,
+					   0, sizeof(struct user_fp_struct),
+					   datap);
+
+	case PTRACE_SETFPREGS:	/* Set the child FPU state. */
+		return copy_regset_from_user(child,
+					     task_user_regset_view(current),
+					     REGSET_FP,
+					     0, sizeof(struct user_fp_struct),
+					     datap);
+
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		break;
+	}
+
+	return ret;
+}
+
+
+#ifdef CONFIG_COMPAT
+
+/* This function is needed to translate 32 bit pt_regs offsets in to
+ * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
+ * will request offset 12 if it wants gr3, but the lower 32 bits of
+ * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
+ * This code relies on a 32 bit pt_regs being comprised of 32 bit values
+ * except for the fp registers which (a) are 64 bits, and (b) follow
+ * the gr registers at the start of pt_regs.  The 32 bit pt_regs should
+ * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
+ * being 64 bit in both cases.
+ */
+
+static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
+{
+	if (offset < 0)
+		return sizeof(struct pt_regs);
+	else if (offset <= 32*4)	/* gr[0..31] */
+		return offset * 2 + 4;
+	else if (offset <= 32*4+32*8)	/* gr[0..31] + fr[0..31] */
+		return offset + 32*4;
+	else if (offset < sizeof(struct pt_regs)/2 + 32*4)
+		return offset * 2 + 4 - 32*8;
+	else
+		return sizeof(struct pt_regs);
+}
+
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t addr, compat_ulong_t data)
+{
+	compat_uint_t tmp;
+	long ret = -EIO;
+
+	switch (request) {
+
+	case PTRACE_PEEKUSR:
+		if (addr & (sizeof(compat_uint_t)-1))
+			break;
+		addr = translate_usr_offset(addr);
+		if (addr >= sizeof(struct pt_regs))
+			break;
+
+		tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
+		ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
+		break;
+
+	/* Write the word at location addr in the USER area.  This will need
+	   to change when the kernel no longer saves all regs on a syscall.
+	   FIXME.  There is a problem at the moment in that r3-r18 are only
+	   saved if the process is ptraced on syscall entry, and even then
+	   those values are overwritten by actual register values on syscall
+	   exit. */
+	case PTRACE_POKEUSR:
+		/* Some register values written here may be ignored in
+		 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
+		 * r31/r31+4, and not with the values in pt_regs.
+		 */
+		if (addr == PT_PSW) {
+			/* Since PT_PSW==0, it is valid for 32 bit processes
+			 * under 64 bit kernels as well.
+			 */
+			ret = arch_ptrace(child, request, addr, data);
+		} else {
+			if (addr & (sizeof(compat_uint_t)-1))
+				break;
+			addr = translate_usr_offset(addr);
+			if (addr >= sizeof(struct pt_regs))
+				break;
+			if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
+				/* Special case, fp regs are 64 bits anyway */
+				*(__u64 *) ((char *) task_regs(child) + addr) = data;
+				ret = 0;
+			}
+			else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
+					addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
+					addr == PT_SAR+4) {
+				/* Zero the top 32 bits */
+				*(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
+				*(__u32 *) ((char *) task_regs(child) + addr) = data;
+				ret = 0;
+			}
+		}
+		break;
+
+	default:
+		ret = compat_ptrace_request(child, request, addr, data);
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+long do_syscall_trace_enter(struct pt_regs *regs)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+	    tracehook_report_syscall_entry(regs)) {
+		/*
+		 * Tracing decided this syscall should not happen or the
+		 * debugger stored an invalid system call number. Skip
+		 * the system call and the system call restart handling.
+		 */
+		regs->gr[20] = -1UL;
+		goto out;
+	}
+
+	/* Do the secure computing check after ptrace. */
+	if (secure_computing(NULL) == -1)
+		return -1;
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_enter(regs, regs->gr[20]);
+#endif
+
+#ifdef CONFIG_64BIT
+	if (!is_compat_task())
+		audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25],
+				    regs->gr[24], regs->gr[23]);
+	else
+#endif
+		audit_syscall_entry(regs->gr[20] & 0xffffffff,
+			regs->gr[26] & 0xffffffff,
+			regs->gr[25] & 0xffffffff,
+			regs->gr[24] & 0xffffffff,
+			regs->gr[23] & 0xffffffff);
+
+out:
+	/*
+	 * Sign extend the syscall number to 64bit since it may have been
+	 * modified by a compat ptrace call
+	 */
+	return (int) ((u32) regs->gr[20]);
+}
+
+void do_syscall_trace_exit(struct pt_regs *regs)
+{
+	int stepping = test_thread_flag(TIF_SINGLESTEP) ||
+		test_thread_flag(TIF_BLOCKSTEP);
+
+	audit_syscall_exit(regs);
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_exit(regs, regs->gr[20]);
+#endif
+
+	if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(regs, stepping);
+}
+
+
+/*
+ * regset functions.
+ */
+
+static int fpr_get(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	__u64 *k = kbuf;
+	__u64 __user *u = ubuf;
+	__u64 reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NFPREG; --count)
+			*k++ = regs->fr[pos++];
+	else
+		for (; count > 0 && pos < ELF_NFPREG; --count)
+			if (__put_user(regs->fr[pos++], u++))
+				return -EFAULT;
+
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					ELF_NFPREG * sizeof(reg), -1);
+}
+
+static int fpr_set(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	const __u64 *k = kbuf;
+	const __u64 __user *u = ubuf;
+	__u64 reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NFPREG; --count)
+			regs->fr[pos++] = *k++;
+	else
+		for (; count > 0 && pos < ELF_NFPREG; --count) {
+			if (__get_user(reg, u++))
+				return -EFAULT;
+			regs->fr[pos++] = reg;
+		}
+
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+					 ELF_NFPREG * sizeof(reg), -1);
+}
+
+#define RI(reg) (offsetof(struct user_regs_struct,reg) / sizeof(long))
+
+static unsigned long get_reg(struct pt_regs *regs, int num)
+{
+	switch (num) {
+	case RI(gr[0]) ... RI(gr[31]):	return regs->gr[num - RI(gr[0])];
+	case RI(sr[0]) ... RI(sr[7]):	return regs->sr[num - RI(sr[0])];
+	case RI(iasq[0]):		return regs->iasq[0];
+	case RI(iasq[1]):		return regs->iasq[1];
+	case RI(iaoq[0]):		return regs->iaoq[0];
+	case RI(iaoq[1]):		return regs->iaoq[1];
+	case RI(sar):			return regs->sar;
+	case RI(iir):			return regs->iir;
+	case RI(isr):			return regs->isr;
+	case RI(ior):			return regs->ior;
+	case RI(ipsw):			return regs->ipsw;
+	case RI(cr27):			return regs->cr27;
+	case RI(cr0):			return mfctl(0);
+	case RI(cr24):			return mfctl(24);
+	case RI(cr25):			return mfctl(25);
+	case RI(cr26):			return mfctl(26);
+	case RI(cr28):			return mfctl(28);
+	case RI(cr29):			return mfctl(29);
+	case RI(cr30):			return mfctl(30);
+	case RI(cr31):			return mfctl(31);
+	case RI(cr8):			return mfctl(8);
+	case RI(cr9):			return mfctl(9);
+	case RI(cr12):			return mfctl(12);
+	case RI(cr13):			return mfctl(13);
+	case RI(cr10):			return mfctl(10);
+	case RI(cr15):			return mfctl(15);
+	default:			return 0;
+	}
+}
+
+static void set_reg(struct pt_regs *regs, int num, unsigned long val)
+{
+	switch (num) {
+	case RI(gr[0]): /*
+			 * PSW is in gr[0].
+			 * Allow writing to Nullify, Divide-step-correction,
+			 * and carry/borrow bits.
+			 * BEWARE, if you set N, and then single step, it won't
+			 * stop on the nullified instruction.
+			 */
+			val &= USER_PSW_BITS;
+			regs->gr[0] &= ~USER_PSW_BITS;
+			regs->gr[0] |= val;
+			return;
+	case RI(gr[1]) ... RI(gr[31]):
+			regs->gr[num - RI(gr[0])] = val;
+			return;
+	case RI(iaoq[0]):
+	case RI(iaoq[1]):
+			regs->iaoq[num - RI(iaoq[0])] = val;
+			return;
+	case RI(sar):	regs->sar = val;
+			return;
+	default:	return;
+#if 0
+	/* do not allow to change any of the following registers (yet) */
+	case RI(sr[0]) ... RI(sr[7]):	return regs->sr[num - RI(sr[0])];
+	case RI(iasq[0]):		return regs->iasq[0];
+	case RI(iasq[1]):		return regs->iasq[1];
+	case RI(iir):			return regs->iir;
+	case RI(isr):			return regs->isr;
+	case RI(ior):			return regs->ior;
+	case RI(ipsw):			return regs->ipsw;
+	case RI(cr27):			return regs->cr27;
+        case cr0, cr24, cr25, cr26, cr27, cr28, cr29, cr30, cr31;
+        case cr8, cr9, cr12, cr13, cr10, cr15;
+#endif
+	}
+}
+
+static int gpr_get(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	unsigned long *k = kbuf;
+	unsigned long __user *u = ubuf;
+	unsigned long reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			*k++ = get_reg(regs, pos++);
+	else
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			if (__put_user(get_reg(regs, pos++), u++))
+				return -EFAULT;
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					ELF_NGREG * sizeof(reg), -1);
+}
+
+static int gpr_set(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	const unsigned long *k = kbuf;
+	const unsigned long __user *u = ubuf;
+	unsigned long reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			set_reg(regs, pos++, *k++);
+	else
+		for (; count > 0 && pos < ELF_NGREG; --count) {
+			if (__get_user(reg, u++))
+				return -EFAULT;
+			set_reg(regs, pos++, reg);
+		}
+
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+					 ELF_NGREG * sizeof(reg), -1);
+}
+
+static const struct user_regset native_regsets[] = {
+	[REGSET_GENERAL] = {
+		.core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
+		.size = sizeof(long), .align = sizeof(long),
+		.get = gpr_get, .set = gpr_set
+	},
+	[REGSET_FP] = {
+		.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
+		.size = sizeof(__u64), .align = sizeof(__u64),
+		.get = fpr_get, .set = fpr_set
+	}
+};
+
+static const struct user_regset_view user_parisc_native_view = {
+	.name = "parisc", .e_machine = ELF_ARCH, .ei_osabi = ELFOSABI_LINUX,
+	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+
+#ifdef CONFIG_64BIT
+#include <linux/compat.h>
+
+static int gpr32_get(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	compat_ulong_t *k = kbuf;
+	compat_ulong_t __user *u = ubuf;
+	compat_ulong_t reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			*k++ = get_reg(regs, pos++);
+	else
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			if (__put_user((compat_ulong_t) get_reg(regs, pos++), u++))
+				return -EFAULT;
+
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					ELF_NGREG * sizeof(reg), -1);
+}
+
+static int gpr32_set(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_regs(target);
+	const compat_ulong_t *k = kbuf;
+	const compat_ulong_t __user *u = ubuf;
+	compat_ulong_t reg;
+
+	pos /= sizeof(reg);
+	count /= sizeof(reg);
+
+	if (kbuf)
+		for (; count > 0 && pos < ELF_NGREG; --count)
+			set_reg(regs, pos++, *k++);
+	else
+		for (; count > 0 && pos < ELF_NGREG; --count) {
+			if (__get_user(reg, u++))
+				return -EFAULT;
+			set_reg(regs, pos++, reg);
+		}
+
+	kbuf = k;
+	ubuf = u;
+	pos *= sizeof(reg);
+	count *= sizeof(reg);
+	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+					 ELF_NGREG * sizeof(reg), -1);
+}
+
+/*
+ * These are the regset flavors matching the 32bit native set.
+ */
+static const struct user_regset compat_regsets[] = {
+	[REGSET_GENERAL] = {
+		.core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
+		.size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
+		.get = gpr32_get, .set = gpr32_set
+	},
+	[REGSET_FP] = {
+		.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
+		.size = sizeof(__u64), .align = sizeof(__u64),
+		.get = fpr_get, .set = fpr_set
+	}
+};
+
+static const struct user_regset_view user_parisc_compat_view = {
+	.name = "parisc", .e_machine = EM_PARISC, .ei_osabi = ELFOSABI_LINUX,
+	.regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
+};
+#endif	/* CONFIG_64BIT */
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+	BUILD_BUG_ON(sizeof(struct user_regs_struct)/sizeof(long) != ELF_NGREG);
+	BUILD_BUG_ON(sizeof(struct user_fp_struct)/sizeof(__u64) != ELF_NFPREG);
+#ifdef CONFIG_64BIT
+	if (is_compat_task())
+		return &user_parisc_compat_view;
+#endif
+	return &user_parisc_native_view;
+}
+
+
+/* HAVE_REGS_AND_STACK_ACCESS_API feature */
+
+struct pt_regs_offset {
+	const char *name;
+	int offset;
+};
+
+#define REG_OFFSET_NAME(r)    {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REG_OFFSET_INDEX(r,i) {.name = #r#i, .offset = offsetof(struct pt_regs, r[i])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+	REG_OFFSET_INDEX(gr,0),
+	REG_OFFSET_INDEX(gr,1),
+	REG_OFFSET_INDEX(gr,2),
+	REG_OFFSET_INDEX(gr,3),
+	REG_OFFSET_INDEX(gr,4),
+	REG_OFFSET_INDEX(gr,5),
+	REG_OFFSET_INDEX(gr,6),
+	REG_OFFSET_INDEX(gr,7),
+	REG_OFFSET_INDEX(gr,8),
+	REG_OFFSET_INDEX(gr,9),
+	REG_OFFSET_INDEX(gr,10),
+	REG_OFFSET_INDEX(gr,11),
+	REG_OFFSET_INDEX(gr,12),
+	REG_OFFSET_INDEX(gr,13),
+	REG_OFFSET_INDEX(gr,14),
+	REG_OFFSET_INDEX(gr,15),
+	REG_OFFSET_INDEX(gr,16),
+	REG_OFFSET_INDEX(gr,17),
+	REG_OFFSET_INDEX(gr,18),
+	REG_OFFSET_INDEX(gr,19),
+	REG_OFFSET_INDEX(gr,20),
+	REG_OFFSET_INDEX(gr,21),
+	REG_OFFSET_INDEX(gr,22),
+	REG_OFFSET_INDEX(gr,23),
+	REG_OFFSET_INDEX(gr,24),
+	REG_OFFSET_INDEX(gr,25),
+	REG_OFFSET_INDEX(gr,26),
+	REG_OFFSET_INDEX(gr,27),
+	REG_OFFSET_INDEX(gr,28),
+	REG_OFFSET_INDEX(gr,29),
+	REG_OFFSET_INDEX(gr,30),
+	REG_OFFSET_INDEX(gr,31),
+	REG_OFFSET_INDEX(sr,0),
+	REG_OFFSET_INDEX(sr,1),
+	REG_OFFSET_INDEX(sr,2),
+	REG_OFFSET_INDEX(sr,3),
+	REG_OFFSET_INDEX(sr,4),
+	REG_OFFSET_INDEX(sr,5),
+	REG_OFFSET_INDEX(sr,6),
+	REG_OFFSET_INDEX(sr,7),
+	REG_OFFSET_INDEX(iasq,0),
+	REG_OFFSET_INDEX(iasq,1),
+	REG_OFFSET_INDEX(iaoq,0),
+	REG_OFFSET_INDEX(iaoq,1),
+	REG_OFFSET_NAME(cr27),
+	REG_OFFSET_NAME(ksp),
+	REG_OFFSET_NAME(kpc),
+	REG_OFFSET_NAME(sar),
+	REG_OFFSET_NAME(iir),
+	REG_OFFSET_NAME(isr),
+	REG_OFFSET_NAME(ior),
+	REG_OFFSET_NAME(ipsw),
+	REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:	the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->offset;
+	return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:	the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (roff->offset == offset)
+			return roff->name;
+	return NULL;
+}
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
new file mode 100644
index 0000000..2b16d8d
--- /dev/null
+++ b/arch/parisc/kernel/real2.S
@@ -0,0 +1,306 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
+ *
+ */
+
+#include <asm/pdc.h>
+#include <asm/psw.h>
+#include <asm/assembly.h>
+#include <asm/asm-offsets.h>
+
+#include <linux/linkage.h>
+
+
+	.section	.bss
+
+	.export pdc_result
+	.export pdc_result2
+	.align 8
+pdc_result:
+	.block	ASM_PDC_RESULT_SIZE
+pdc_result2:
+	.block	ASM_PDC_RESULT_SIZE
+
+	.export real_stack
+	.export real32_stack
+	.export real64_stack
+	.align	64
+real_stack:
+real32_stack:
+real64_stack:
+	.block	8192
+
+#define N_SAVED_REGS 9
+
+save_cr_space:
+	.block	REG_SZ * N_SAVED_REGS
+save_cr_end:
+
+
+/************************ 32-bit real-mode calls ***********************/
+/* This can be called in both narrow and wide kernels */
+
+	.text
+
+	/* unsigned long real32_call_asm(unsigned int *sp,
+	 *		unsigned int *arg0p,
+	 *		unsigned int iodc_fn)
+	 *	sp is value of stack pointer to adopt before calling PDC (virt)
+	 *	arg0p points to where saved arg values may be found
+	 *	iodc_fn is the IODC function to call
+	 */
+
+ENTRY_CFI(real32_call_asm)
+	STREG	%rp, -RP_OFFSET(%sp)	/* save RP */
+#ifdef CONFIG_64BIT
+	callee_save
+	ldo	2*REG_SZ(%sp), %sp	/* room for a couple more saves */
+	STREG	%r27, -1*REG_SZ(%sp)
+	STREG	%r29, -2*REG_SZ(%sp)
+#endif
+	STREG	%sp, -REG_SZ(%arg0)	/* save SP on real-mode stack */
+	copy	%arg0, %sp		/* adopt the real-mode SP */
+
+	/* save iodc_fn */
+	copy	%arg2, %r31
+
+	/* load up the arg registers from the saved arg area */
+	/* 32-bit calling convention passes first 4 args in registers */
+	ldw	0(%arg1), %arg0		/* note overwriting arg0 */
+	ldw	-8(%arg1), %arg2
+	ldw	-12(%arg1), %arg3
+	ldw	-4(%arg1), %arg1	/* obviously must do this one last! */
+
+	tophys_r1  %sp
+
+	b,l	rfi_virt2real,%r2
+	nop
+
+	b,l	save_control_regs,%r2		/* modifies r1, r2, r28 */
+	nop
+
+#ifdef CONFIG_64BIT
+	rsm	PSW_SM_W, %r0		/* go narrow */
+#endif
+
+	load32	PA(ric_ret), %r2
+	bv	0(%r31)
+	nop
+ric_ret:
+#ifdef CONFIG_64BIT
+	ssm	PSW_SM_W, %r0		/* go wide */
+#endif
+	/* restore CRs before going virtual in case we page fault */
+	b,l	restore_control_regs, %r2	/* modifies r1, r2, r26 */
+	nop
+
+	b,l	rfi_real2virt,%r2
+	nop
+
+	tovirt_r1 %sp
+	LDREG	-REG_SZ(%sp), %sp	/* restore SP */
+#ifdef CONFIG_64BIT
+	LDREG	-1*REG_SZ(%sp), %r27
+	LDREG	-2*REG_SZ(%sp), %r29
+	ldo	-2*REG_SZ(%sp), %sp
+	callee_rest
+#endif
+	LDREG	-RP_OFFSET(%sp), %rp	/* restore RP */
+	bv	0(%rp)
+	nop
+ENDPROC_CFI(real32_call_asm)
+
+
+#  define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where)
+#  define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r
+
+	.text
+ENTRY_CFI(save_control_regs)
+	load32	PA(save_cr_space), %r28
+	PUSH_CR(%cr24, %r28)
+	PUSH_CR(%cr25, %r28)
+	PUSH_CR(%cr26, %r28)
+	PUSH_CR(%cr27, %r28)
+	PUSH_CR(%cr28, %r28)
+	PUSH_CR(%cr29, %r28)
+	PUSH_CR(%cr30, %r28)
+	PUSH_CR(%cr31, %r28)
+	PUSH_CR(%cr15, %r28)
+	bv 0(%r2)
+	nop
+ENDPROC_CFI(save_control_regs)
+
+ENTRY_CFI(restore_control_regs)
+	load32	PA(save_cr_end), %r26
+	POP_CR(%cr15, %r26)
+	POP_CR(%cr31, %r26)
+	POP_CR(%cr30, %r26)
+	POP_CR(%cr29, %r26)
+	POP_CR(%cr28, %r26)
+	POP_CR(%cr27, %r26)
+	POP_CR(%cr26, %r26)
+	POP_CR(%cr25, %r26)
+	POP_CR(%cr24, %r26)
+	bv 0(%r2)
+	nop
+ENDPROC_CFI(restore_control_regs)
+
+/* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for
+ * more general-purpose use by the several places which need RFIs
+ */
+	.text
+	.align 128
+ENTRY_CFI(rfi_virt2real)
+#if !defined(BOOTLOADER)
+	/* switch to real mode... */
+	rsm		PSW_SM_I,%r0
+	load32		PA(rfi_v2r_1), %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+	
+	rsm             PSW_SM_Q,%r0  /* disable Q & I bits to load iia queue */
+	mtctl		%r0, %cr17	/* Clear IIASQ tail */
+	mtctl		%r0, %cr17	/* Clear IIASQ head */
+	mtctl		%r1, %cr18	/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18	/* IIAOQ tail */
+	load32          REAL_MODE_PSW, %r1
+	mtctl		%r1, %cr22
+	rfi
+	
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+rfi_v2r_1:
+	tophys_r1 %r2
+#endif /* defined(BOOTLOADER) */
+	bv	0(%r2)
+	nop
+ENDPROC_CFI(rfi_virt2real)
+
+	.text
+	.align 128
+ENTRY_CFI(rfi_real2virt)
+#if !defined(BOOTLOADER)
+	rsm		PSW_SM_I,%r0
+	load32		(rfi_r2v_1), %r1
+	nop
+	nop
+	nop
+	nop
+	nop
+	
+	rsm             PSW_SM_Q,%r0    /* disable Q bit to load iia queue */
+	mtctl		%r0, %cr17	/* Clear IIASQ tail */
+	mtctl		%r0, %cr17	/* Clear IIASQ head */
+	mtctl		%r1, %cr18	/* IIAOQ head */
+	ldo		4(%r1), %r1
+	mtctl		%r1, %cr18	/* IIAOQ tail */
+	load32		KERNEL_PSW, %r1
+	mtctl		%r1, %cr22
+	rfi
+	
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+rfi_r2v_1:
+	tovirt_r1 %r2
+#endif /* defined(BOOTLOADER) */
+	bv	0(%r2)
+	nop
+ENDPROC_CFI(rfi_real2virt)
+
+#ifdef CONFIG_64BIT
+
+/************************ 64-bit real-mode calls ***********************/
+/* This is only usable in wide kernels right now and will probably stay so */
+	.text
+	/* unsigned long real64_call_asm(unsigned long *sp,
+	 *		unsigned long *arg0p,
+	 *		unsigned long fn)
+	 *	sp is value of stack pointer to adopt before calling PDC (virt)
+	 *	arg0p points to where saved arg values may be found
+	 *	iodc_fn is the IODC function to call
+	 */
+ENTRY_CFI(real64_call_asm)
+	std	%rp, -0x10(%sp)		/* save RP */
+	std	%sp, -8(%arg0)		/* save SP on real-mode stack */
+	copy	%arg0, %sp		/* adopt the real-mode SP */
+
+	/* save fn */
+	copy	%arg2, %r31
+
+	/* set up the new ap */
+	ldo	64(%arg1), %r29
+
+	/* load up the arg registers from the saved arg area */
+	/* 32-bit calling convention passes first 4 args in registers */
+	ldd	0*REG_SZ(%arg1), %arg0		/* note overwriting arg0 */
+	ldd	2*REG_SZ(%arg1), %arg2
+	ldd	3*REG_SZ(%arg1), %arg3
+	ldd	4*REG_SZ(%arg1), %r22
+	ldd	5*REG_SZ(%arg1), %r21
+	ldd	6*REG_SZ(%arg1), %r20
+	ldd	7*REG_SZ(%arg1), %r19
+	ldd	1*REG_SZ(%arg1), %arg1		/* do this one last! */
+
+	tophys_r1 %sp
+
+	b,l	rfi_virt2real,%r2
+	nop
+
+	b,l	save_control_regs,%r2		/* modifies r1, r2, r28 */
+	nop
+
+	load32	PA(r64_ret), %r2
+	bv	0(%r31)
+	nop
+r64_ret:
+	/* restore CRs before going virtual in case we page fault */
+	b,l	restore_control_regs, %r2	/* modifies r1, r2, r26 */
+	nop
+
+	b,l	rfi_real2virt,%r2
+	nop
+
+	tovirt_r1 %sp
+	ldd	-8(%sp), %sp		/* restore SP */
+	ldd	-0x10(%sp), %rp		/* restore RP */
+	bv	0(%rp)
+	nop
+ENDPROC_CFI(real64_call_asm)
+
+#endif
+
+	.text
+	/* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
+	**	GCC 3.3 and later has a new function in libgcc.a for
+	**	comparing function pointers.
+	*/
+ENTRY_CFI(__canonicalize_funcptr_for_compare)
+#ifdef CONFIG_64BIT
+	bve (%r2)
+#else
+	bv %r0(%r2)
+#endif
+	copy %r26,%r28
+ENDPROC_CFI(__canonicalize_funcptr_for_compare)
+
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
new file mode 100644
index 0000000..4e87c35
--- /dev/null
+++ b/arch/parisc/kernel/setup.c
@@ -0,0 +1,424 @@
+/*
+ *    Initial setup-routines for HP 9000 based hardware.
+ *
+ *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *    Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
+ *    Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
+ *    Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
+ *    Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *    Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
+ *
+ *    Initial PA-RISC Version: 04-23-1999 by Helge Deller
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/initrd.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/seq_file.h>
+#define PCI_DEBUG
+#include <linux/pci.h>
+#undef PCI_DEBUG
+#include <linux/proc_fs.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/sched/clock.h>
+#include <linux/start_kernel.h>
+
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/pdc.h>
+#include <asm/led.h>
+#include <asm/machdep.h>	/* for pa7300lc_init() proto */
+#include <asm/pdc_chassis.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/unwind.h>
+#include <asm/smp.h>
+
+static char __initdata command_line[COMMAND_LINE_SIZE];
+
+/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
+struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
+struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
+struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
+
+void __init setup_cmdline(char **cmdline_p)
+{
+	extern unsigned int boot_args[];
+
+	/* Collect stuff passed in from the boot loader */
+
+	/* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */
+	if (boot_args[0] < 64) {
+		/* called from hpux boot loader */
+		boot_command_line[0] = '\0';
+	} else {
+		strlcpy(boot_command_line, (char *)__va(boot_args[1]),
+			COMMAND_LINE_SIZE);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
+		{
+		    initrd_start = (unsigned long)__va(boot_args[2]);
+		    initrd_end = (unsigned long)__va(boot_args[3]);
+		}
+#endif
+	}
+
+	strcpy(command_line, boot_command_line);
+	*cmdline_p = command_line;
+}
+
+#ifdef CONFIG_PA11
+void __init dma_ops_init(void)
+{
+	switch (boot_cpu_data.cpu_type) {
+	case pcx:
+		/*
+		 * We've got way too many dependencies on 1.1 semantics
+		 * to support 1.0 boxes at this point.
+		 */
+		panic(	"PA-RISC Linux currently only supports machines that conform to\n"
+			"the PA-RISC 1.1 or 2.0 architecture specification.\n");
+
+	case pcxl2:
+		pa7300lc_init();
+	case pcxl: /* falls through */
+	case pcxs:
+	case pcxt:
+		hppa_dma_ops = &dma_noncoherent_ops;
+		break;
+	default:
+		break;
+	}
+}
+#endif
+
+extern void collect_boot_cpu_data(void);
+
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_64BIT
+	extern int parisc_narrow_firmware;
+#endif
+	unwind_init();
+
+	init_per_cpu(smp_processor_id());	/* Set Modes & Enable FP */
+
+#ifdef CONFIG_64BIT
+	printk(KERN_INFO "The 64-bit Kernel has started...\n");
+#else
+	printk(KERN_INFO "The 32-bit Kernel has started...\n");
+#endif
+
+	printk(KERN_INFO "Kernel default page size is %d KB. Huge pages ",
+		(int)(PAGE_SIZE / 1024));
+#ifdef CONFIG_HUGETLB_PAGE
+	printk(KERN_CONT "enabled with %d MB physical and %d MB virtual size",
+		 1 << (REAL_HPAGE_SHIFT - 20), 1 << (HPAGE_SHIFT - 20));
+#else
+	printk(KERN_CONT "disabled");
+#endif
+	printk(KERN_CONT ".\n");
+
+	/*
+	 * Check if initial kernel page mappings are sufficient.
+	 * panic early if not, else we may access kernel functions
+	 * and variables which can't be reached.
+	 */
+	if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
+		panic("KERNEL_INITIAL_ORDER too small!");
+
+	pdc_console_init();
+
+#ifdef CONFIG_64BIT
+	if(parisc_narrow_firmware) {
+		printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
+	}
+#endif
+	setup_pdc();
+	setup_cmdline(cmdline_p);
+	collect_boot_cpu_data();
+	do_memory_inventory();  /* probe for physical memory */
+	parisc_cache_init();
+	paging_init();
+
+#ifdef CONFIG_CHASSIS_LCD_LED
+	/* initialize the LCD/LED after boot_cpu_data is available ! */
+	led_init();		/* LCD/LED initialization */
+#endif
+
+#ifdef CONFIG_PA11
+	dma_ops_init();
+#endif
+
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;	/* we use do_take_over_console() later ! */
+#endif
+
+	clear_sched_clock_stable();
+}
+
+/*
+ * Display CPU info for all CPUs.
+ * for parisc this is in processor.c
+ */
+extern int show_cpuinfo (struct seq_file *m, void *v);
+
+static void *
+c_start (struct seq_file *m, loff_t *pos)
+{
+    	/* Looks like the caller will call repeatedly until we return
+	 * 0, signaling EOF perhaps.  This could be used to sequence
+	 * through CPUs for example.  Since we print all cpu info in our
+	 * show_cpuinfo() disregarding 'pos' (which I assume is 'v' above)
+	 * we only allow for one "position".  */
+	return ((long)*pos < 1) ? (void *)1 : NULL;
+}
+
+static void *
+c_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void
+c_stop (struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo
+};
+
+static void __init parisc_proc_mkdir(void)
+{
+	/*
+	** Can't call proc_mkdir() until after proc_root_init() has been
+	** called by start_kernel(). In other words, this code can't
+	** live in arch/.../setup.c because start_parisc() calls
+	** start_kernel().
+	*/
+	switch (boot_cpu_data.cpu_type) {
+	case pcxl:
+	case pcxl2:
+		if (NULL == proc_gsc_root)
+		{
+			proc_gsc_root = proc_mkdir("bus/gsc", NULL);
+		}
+		break;
+        case pcxt_:
+        case pcxu:
+        case pcxu_:
+        case pcxw:
+        case pcxw_:
+        case pcxw2:
+                if (NULL == proc_runway_root)
+                {
+                        proc_runway_root = proc_mkdir("bus/runway", NULL);
+                }
+                break;
+	case mako:
+	case mako2:
+                if (NULL == proc_mckinley_root)
+                {
+                        proc_mckinley_root = proc_mkdir("bus/mckinley", NULL);
+                }
+                break;
+	default:
+		/* FIXME: this was added to prevent the compiler 
+		 * complaining about missing pcx, pcxs and pcxt
+		 * I'm assuming they have neither gsc nor runway */
+		break;
+	}
+}
+
+static struct resource central_bus = {
+	.name	= "Central Bus",
+	.start	= F_EXTEND(0xfff80000),
+	.end    = F_EXTEND(0xfffaffff),
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource local_broadcast = {
+	.name	= "Local Broadcast",
+	.start	= F_EXTEND(0xfffb0000),
+	.end	= F_EXTEND(0xfffdffff),
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource global_broadcast = {
+	.name	= "Global Broadcast",
+	.start	= F_EXTEND(0xfffe0000),
+	.end	= F_EXTEND(0xffffffff),
+	.flags	= IORESOURCE_MEM,
+};
+
+static int __init parisc_init_resources(void)
+{
+	int result;
+
+	result = request_resource(&iomem_resource, &central_bus);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %s address space!\n", 
+		       __FILE__, central_bus.name);
+		return result;
+	}
+
+	result = request_resource(&iomem_resource, &local_broadcast);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %saddress space!\n", 
+		       __FILE__, local_broadcast.name);
+		return result;
+	}
+
+	result = request_resource(&iomem_resource, &global_broadcast);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %s address space!\n", 
+		       __FILE__, global_broadcast.name);
+		return result;
+	}
+
+	return 0;
+}
+
+extern void gsc_init(void);
+extern void processor_init(void);
+extern void ccio_init(void);
+extern void hppb_init(void);
+extern void dino_init(void);
+extern void iosapic_init(void);
+extern void lba_init(void);
+extern void sba_init(void);
+extern void eisa_init(void);
+
+static int __init parisc_init(void)
+{
+	u32 osid = (OS_ID_LINUX << 16);
+
+	parisc_proc_mkdir();
+	parisc_init_resources();
+	do_device_inventory();                  /* probe for hardware */
+
+	parisc_pdc_chassis_init();
+	
+	/* set up a new led state on systems shipped LED State panel */
+	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
+
+	/* tell PDC we're Linux. Nevermind failure. */
+	pdc_stable_write(0x40, &osid, sizeof(osid));
+	
+	/* start with known state */
+	flush_cache_all_local();
+	flush_tlb_all_local(NULL);
+
+	processor_init();
+#ifdef CONFIG_SMP
+	pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
+		num_online_cpus(), num_present_cpus(),
+#else
+	pr_info("CPU(s): 1 x %s at %d.%06d MHz\n",
+#endif
+			boot_cpu_data.cpu_name,
+			boot_cpu_data.cpu_hz / 1000000,
+			boot_cpu_data.cpu_hz % 1000000	);
+
+	parisc_setup_cache_timing();
+
+	/* These are in a non-obvious order, will fix when we have an iotree */
+#if defined(CONFIG_IOSAPIC)
+	iosapic_init();
+#endif
+#if defined(CONFIG_IOMMU_SBA)
+	sba_init();
+#endif
+#if defined(CONFIG_PCI_LBA)
+	lba_init();
+#endif
+
+	/* CCIO before any potential subdevices */
+#if defined(CONFIG_IOMMU_CCIO)
+	ccio_init();
+#endif
+
+	/*
+	 * Need to register Asp & Wax before the EISA adapters for the IRQ
+	 * regions.  EISA must come before PCI to be sure it gets IRQ region
+	 * 0.
+	 */
+#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX)
+	gsc_init();
+#endif
+#ifdef CONFIG_EISA
+	eisa_init();
+#endif
+
+#if defined(CONFIG_HPPB)
+	hppb_init();
+#endif
+
+#if defined(CONFIG_GSC_DINO)
+	dino_init();
+#endif
+
+#ifdef CONFIG_CHASSIS_LCD_LED
+	register_led_regions();	/* register LED port info in procfs */
+#endif
+
+	return 0;
+}
+arch_initcall(parisc_init);
+
+void __init start_parisc(void)
+{
+	extern void early_trap_init(void);
+
+	int ret, cpunum;
+	struct pdc_coproc_cfg coproc_cfg;
+
+	cpunum = smp_processor_id();
+
+	init_cpu_topology();
+
+	set_firmware_width_unlocked();
+
+	ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
+	if (ret >= 0 && coproc_cfg.ccr_functional) {
+		mtctl(coproc_cfg.ccr_functional, 10);
+
+		per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
+		per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
+
+		asm volatile ("fstd	%fr0,8(%sp)");
+	} else {
+		panic("must have an fpu to boot linux");
+	}
+
+	early_trap_init(); /* initialize checksum of fault_vector */
+
+	start_kernel();
+	// not reached
+}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
new file mode 100644
index 0000000..342073f
--- /dev/null
+++ b/arch/parisc/kernel/signal.c
@@ -0,0 +1,615 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  linux/arch/parisc/kernel/signal.c: Architecture-specific signal
+ *  handling support.
+ *
+ *  Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
+ *  Copyright (C) 2000 Linuxcare, Inc.
+ *
+ *  Based on the ia64, i386, and alpha versions.
+ *
+ *  Like the IA-64, we are a recent enough port (we are *starting*
+ *  with glibc2.2) that we do not need to support the old non-realtime
+ *  Linux signals.  Therefore we don't.
+ */
+
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/tracehook.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/compat.h>
+#include <linux/elf.h>
+#include <asm/ucontext.h>
+#include <asm/rt_sigframe.h>
+#include <linux/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_COMPAT
+#include "signal32.h"
+#endif
+
+#define DEBUG_SIG 0 
+#define DEBUG_SIG_LEVEL 2
+
+#if DEBUG_SIG
+#define DBG(LEVEL, ...) \
+        ((DEBUG_SIG_LEVEL >= LEVEL) \
+	? printk(__VA_ARGS__) : (void) 0)
+#else
+#define DBG(LEVEL, ...)
+#endif
+	
+/* gcc will complain if a pointer is cast to an integer of different
+ * size.  If you really need to do this (and we do for an ELF32 user
+ * application in an ELF64 kernel) then you have to do a cast to an
+ * integer of the same size first.  The A() macro accomplishes
+ * this. */
+#define A(__x)	((unsigned long)(__x))
+
+/*
+ * Do a signal return - restore sigcontext.
+ */
+
+/* Trampoline for calling rt_sigreturn() */
+#define INSN_LDI_R25_0	 0x34190000 /* ldi  0,%r25 (in_syscall=0) */
+#define INSN_LDI_R25_1	 0x34190002 /* ldi  1,%r25 (in_syscall=1) */
+#define INSN_LDI_R20	 0x3414015a /* ldi  __NR_rt_sigreturn,%r20 */
+#define INSN_BLE_SR2_R0  0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
+#define INSN_NOP	 0x08000240 /* nop */
+/* For debugging */
+#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
+
+static long
+restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
+{
+	long err = 0;
+
+	err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
+	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
+	err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
+	err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
+	err |= __get_user(regs->sar, &sc->sc_sar);
+	DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n",
+			regs->iaoq[0],regs->iaoq[1]);
+	DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
+	return err;
+}
+
+void
+sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
+{
+	struct rt_sigframe __user *frame;
+	sigset_t set;
+	unsigned long usp = (regs->gr[30] & ~(0x01UL));
+	unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
+#ifdef CONFIG_64BIT
+	struct compat_rt_sigframe __user * compat_frame;
+	
+	if (is_compat_task())
+		sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
+#endif
+
+	current->restart_block.fn = do_no_restart_syscall;
+
+	/* Unwind the user stack to get the rt_sigframe structure. */
+	frame = (struct rt_sigframe __user *)
+		(usp - sigframe_size);
+	DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
+
+	regs->orig_r28 = 1; /* no restarts for sigreturn */
+
+#ifdef CONFIG_64BIT
+	compat_frame = (struct compat_rt_sigframe __user *)frame;
+	
+	if (is_compat_task()) {
+		DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
+		if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
+			goto give_sigsegv;
+	} else
+#endif
+	{
+		if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+			goto give_sigsegv;
+	}
+		
+	set_current_blocked(&set);
+
+	/* Good thing we saved the old gr[30], eh? */
+#ifdef CONFIG_64BIT
+	if (is_compat_task()) {
+		DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
+				&compat_frame->uc.uc_mcontext);
+// FIXME: Load upper half from register file
+		if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 
+					&compat_frame->regs, regs))
+			goto give_sigsegv;
+		DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
+				usp, &compat_frame->uc.uc_stack);
+		if (compat_restore_altstack(&compat_frame->uc.uc_stack))
+			goto give_sigsegv;
+	} else
+#endif
+	{
+		DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
+				&frame->uc.uc_mcontext);
+		if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
+			goto give_sigsegv;
+		DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
+				usp, &frame->uc.uc_stack);
+		if (restore_altstack(&frame->uc.uc_stack))
+			goto give_sigsegv;
+	}
+		
+
+
+	/* If we are on the syscall path IAOQ will not be restored, and
+	 * if we are on the interrupt path we must not corrupt gr31.
+	 */
+	if (in_syscall)
+		regs->gr[31] = regs->iaoq[0];
+#if DEBUG_SIG
+	DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
+	show_regs(regs);
+#endif
+	return;
+
+give_sigsegv:
+	DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
+	force_sig(SIGSEGV, current);
+	return;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static inline void __user *
+get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+{
+	/*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
+	  don't use the parameter it doesn't matter */
+
+	DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
+			(unsigned long)ka, sp, frame_size);
+	
+	/* Align alternate stack and reserve 64 bytes for the signal
+	   handler's frame marker.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
+		sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */
+
+	DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
+	return (void __user *) sp; /* Stacks grow up.  Fun. */
+}
+
+static long
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
+		 
+{
+	unsigned long flags = 0;
+	long err = 0;
+
+	if (on_sig_stack((unsigned long) sc))
+		flags |= PARISC_SC_FLAG_ONSTACK;
+	if (in_syscall) {
+		flags |= PARISC_SC_FLAG_IN_SYSCALL;
+		/* regs->iaoq is undefined in the syscall return path */
+		err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
+		err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
+		err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
+		err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
+		DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
+			regs->gr[31], regs->gr[31]+4);
+	} else {
+		err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
+		err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
+		DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 
+			regs->iaoq[0], regs->iaoq[1]);
+	}
+
+	err |= __put_user(flags, &sc->sc_flags);
+	err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
+	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
+	err |= __put_user(regs->sar, &sc->sc_sar);
+	DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
+
+	return err;
+}
+
+static long
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
+	       int in_syscall)
+{
+	struct rt_sigframe __user *frame;
+	unsigned long rp, usp;
+	unsigned long haddr, sigframe_size;
+	unsigned long start, end;
+	int err = 0;
+#ifdef CONFIG_64BIT
+	struct compat_rt_sigframe __user * compat_frame;
+#endif
+	
+	usp = (regs->gr[30] & ~(0x01UL));
+	/*FIXME: frame_size parameter is unused, remove it. */
+	frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
+
+	DBG(1,"SETUP_RT_FRAME: START\n");
+	DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
+
+	
+#ifdef CONFIG_64BIT
+
+	compat_frame = (struct compat_rt_sigframe __user *)frame;
+	
+	if (is_compat_task()) {
+		DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
+		err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
+		err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
+		DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
+		DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
+		err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
+					&compat_frame->regs, regs, in_syscall);
+		err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
+					 sizeof(compat_sigset_t));
+	} else
+#endif
+	{	
+		DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
+		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+		err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
+		DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
+		DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
+		err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
+		/* FIXME: Should probably be converted as well for the compat case */
+		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+	}
+	
+	if (err)
+		return -EFAULT;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace. The first words of tramp are used to
+	   save the previous sigrestartblock trampoline that might be
+	   on the stack. We start the sigreturn trampoline at 
+	   SIGRESTARTBLOCK_TRAMP+X. */
+	err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
+			&frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
+	err |= __put_user(INSN_LDI_R20, 
+			&frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
+	err |= __put_user(INSN_BLE_SR2_R0, 
+			&frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
+	err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
+
+#if DEBUG_SIG
+	/* Assert that we're flushing in the correct space... */
+	{
+		unsigned long sid;
+		asm ("mfsp %%sr3,%0" : "=r" (sid));
+		DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
+		       sid, frame->tramp);
+	}
+#endif
+
+	start = (unsigned long) &frame->tramp[0];
+	end = (unsigned long) &frame->tramp[TRAMP_SIZE];
+	flush_user_dcache_range_asm(start, end);
+	flush_user_icache_range_asm(start, end);
+
+	/* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
+	 * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
+	 * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
+	 */
+	rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
+
+	if (err)
+		return -EFAULT;
+
+	haddr = A(ksig->ka.sa.sa_handler);
+	/* The sa_handler may be a pointer to a function descriptor */
+#ifdef CONFIG_64BIT
+	if (is_compat_task()) {
+#endif
+		if (haddr & PA_PLABEL_FDESC) {
+			Elf32_Fdesc fdesc;
+			Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
+
+			err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
+
+			if (err)
+				return -EFAULT;
+
+			haddr = fdesc.addr;
+			regs->gr[19] = fdesc.gp;
+		}
+#ifdef CONFIG_64BIT
+	} else {
+		Elf64_Fdesc fdesc;
+		Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
+		
+		err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
+		
+		if (err)
+			return -EFAULT;
+		
+		haddr = fdesc.addr;
+		regs->gr[19] = fdesc.gp;
+		DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
+		     haddr, regs->gr[19], in_syscall);
+	}
+#endif
+
+	/* The syscall return path will create IAOQ values from r31.
+	 */
+	sigframe_size = PARISC_RT_SIGFRAME_SIZE;
+#ifdef CONFIG_64BIT
+	if (is_compat_task())
+		sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
+#endif
+	if (in_syscall) {
+		regs->gr[31] = haddr;
+#ifdef CONFIG_64BIT
+		if (!test_thread_flag(TIF_32BIT))
+			sigframe_size |= 1;
+#endif
+	} else {
+		unsigned long psw = USER_PSW;
+#ifdef CONFIG_64BIT
+		if (!test_thread_flag(TIF_32BIT))
+			psw |= PSW_W;
+#endif
+
+		/* If we are singlestepping, arrange a trap to be delivered
+		   when we return to userspace. Note the semantics -- we
+		   should trap before the first insn in the handler is
+		   executed. Ref:
+			http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
+		 */
+		if (pa_psw(current)->r) {
+			pa_psw(current)->r = 0;
+			psw |= PSW_R;
+			mtctl(-1, 0);
+		}
+
+		regs->gr[0] = psw;
+		regs->iaoq[0] = haddr | 3;
+		regs->iaoq[1] = regs->iaoq[0] + 4;
+	}
+
+	regs->gr[2]  = rp;                /* userland return pointer */
+	regs->gr[26] = ksig->sig;               /* signal number */
+	
+#ifdef CONFIG_64BIT
+	if (is_compat_task()) {
+		regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
+		regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
+	} else
+#endif
+	{		
+		regs->gr[25] = A(&frame->info); /* siginfo pointer */
+		regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
+	}
+	
+	DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
+	       regs->gr[30], sigframe_size,
+	       regs->gr[30] + sigframe_size);
+	/* Raise the user stack pointer to make a proper call frame. */
+	regs->gr[30] = (A(frame) + sigframe_size);
+
+
+	DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
+	       current->comm, current->pid, frame, regs->gr[30],
+	       regs->iaoq[0], regs->iaoq[1], rp);
+
+	return 0;
+}
+
+/*
+ * OK, we're invoking a handler.
+ */	
+
+static void
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
+{
+	int ret;
+	sigset_t *oldset = sigmask_to_save();
+
+	DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
+	       ksig->sig, ksig->ka, ksig->info, oldset, regs);
+	
+	/* Set up the stack frame */
+	ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
+
+	signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
+			  test_thread_flag(TIF_BLOCKSTEP));
+
+	DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
+		regs->gr[28]);
+}
+
+/*
+ * Check how the syscall number gets loaded into %r20 within
+ * the delay branch in userspace and adjust as needed.
+ */
+
+static void check_syscallno_in_delay_branch(struct pt_regs *regs)
+{
+	u32 opcode, source_reg;
+	u32 __user *uaddr;
+	int err;
+
+	/* Usually we don't have to restore %r20 (the system call number)
+	 * because it gets loaded in the delay slot of the branch external
+	 * instruction via the ldi instruction.
+	 * In some cases a register-to-register copy instruction might have
+	 * been used instead, in which case we need to copy the syscall
+	 * number into the source register before returning to userspace.
+	 */
+
+	/* A syscall is just a branch, so all we have to do is fiddle the
+	 * return pointer so that the ble instruction gets executed again.
+	 */
+	regs->gr[31] -= 8; /* delayed branching */
+
+	/* Get assembler opcode of code in delay branch */
+	uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
+	err = get_user(opcode, uaddr);
+	if (err)
+		return;
+
+	/* Check if delay branch uses "ldi int,%r20" */
+	if ((opcode & 0xffff0000) == 0x34140000)
+		return;	/* everything ok, just return */
+
+	/* Check if delay branch uses "nop" */
+	if (opcode == INSN_NOP)
+		return;
+
+	/* Check if delay branch uses "copy %rX,%r20" */
+	if ((opcode & 0xffe0ffff) == 0x08000254) {
+		source_reg = (opcode >> 16) & 31;
+		regs->gr[source_reg] = regs->gr[20];
+		return;
+	}
+
+	pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
+		current->comm, task_pid_nr(current), opcode);
+}
+
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+	if (regs->orig_r28)
+		return;
+	regs->orig_r28 = 1; /* no more restarts */
+	/* Check the return code */
+	switch (regs->gr[28]) {
+	case -ERESTART_RESTARTBLOCK:
+	case -ERESTARTNOHAND:
+		DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
+		regs->gr[28] = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (!(ka->sa.sa_flags & SA_RESTART)) {
+			DBG(1,"ERESTARTSYS: putting -EINTR\n");
+			regs->gr[28] = -EINTR;
+			break;
+		}
+		/* fallthrough */
+	case -ERESTARTNOINTR:
+		check_syscallno_in_delay_branch(regs);
+		break;
+	}
+}
+
+static inline void
+insert_restart_trampoline(struct pt_regs *regs)
+{
+	if (regs->orig_r28)
+		return;
+	regs->orig_r28 = 1; /* no more restarts */
+	switch(regs->gr[28]) {
+	case -ERESTART_RESTARTBLOCK: {
+		/* Restart the system call - no handlers present */
+		unsigned int *usp = (unsigned int *)regs->gr[30];
+		unsigned long start = (unsigned long) &usp[2];
+		unsigned long end  = (unsigned long) &usp[5];
+		long err = 0;
+
+		/* Setup a trampoline to restart the syscall
+		 * with __NR_restart_syscall
+		 *
+		 *  0: <return address (orig r31)>
+		 *  4: <2nd half for 64-bit>
+		 *  8: ldw 0(%sp), %r31
+		 * 12: be 0x100(%sr2, %r0)
+		 * 16: ldi __NR_restart_syscall, %r20
+		 */
+#ifdef CONFIG_64BIT
+		err |= put_user(regs->gr[31] >> 32, &usp[0]);
+		err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+		err |= put_user(0x0fc010df, &usp[2]);
+#else
+		err |= put_user(regs->gr[31], &usp[0]);
+		err |= put_user(0x0fc0109f, &usp[2]);
+#endif
+		err |= put_user(0xe0008200, &usp[3]);
+		err |= put_user(0x34140000, &usp[4]);
+
+		WARN_ON(err);
+
+		/* flush data/instruction cache for new insns */
+		flush_user_dcache_range_asm(start, end);
+		flush_user_icache_range_asm(start, end);
+
+		regs->gr[31] = regs->gr[30] + 8;
+		return;
+	}
+	case -ERESTARTNOHAND:
+	case -ERESTARTSYS:
+	case -ERESTARTNOINTR:
+		check_syscallno_in_delay_branch(regs);
+		return;
+	default:
+		break;
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * We need to be able to restore the syscall arguments (r21-r26) to
+ * restart syscalls.  Thus, the syscall path should save them in the
+ * pt_regs structure (it's okay to do so since they are caller-save
+ * registers).  As noted below, the syscall number gets restored for
+ * us due to the magic of delayed branching.
+ */
+asmlinkage void
+do_signal(struct pt_regs *regs, long in_syscall)
+{
+	struct ksignal ksig;
+
+	DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
+	       regs, regs->sr[7], in_syscall);
+
+	if (get_signal(&ksig)) {
+		DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
+		/* Restart a system call if necessary. */
+		if (in_syscall)
+			syscall_restart(regs, &ksig.ka);
+
+		handle_signal(&ksig, regs, in_syscall);
+		return;
+	}
+
+	/* Did we come from a system call? */
+	if (in_syscall)
+		insert_restart_trampoline(regs);
+	
+	DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
+		regs->gr[28]);
+
+	restore_saved_sigmask();
+}
+
+void do_notify_resume(struct pt_regs *regs, long in_syscall)
+{
+	if (test_thread_flag(TIF_SIGPENDING))
+		do_signal(regs, in_syscall);
+
+	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
+}
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
new file mode 100644
index 0000000..e8ef3eb
--- /dev/null
+++ b/arch/parisc/kernel/signal32.c
@@ -0,0 +1,262 @@
+/*    Signal support for 32-bit kernel builds
+ *
+ *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
+ *
+ *    Code was mostly borrowed from kernel/signal.c.
+ *    See kernel/signal.c for additional Copyrights.
+ *
+ *
+ *    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
+ */
+
+#include <linux/compat.h>
+#include <linux/module.h>
+#include <linux/unistd.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+
+#include <linux/uaccess.h>
+
+#include "signal32.h"
+
+#define DEBUG_COMPAT_SIG 0 
+#define DEBUG_COMPAT_SIG_LEVEL 2
+
+#if DEBUG_COMPAT_SIG
+#define DBG(LEVEL, ...) \
+	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
+	? printk(__VA_ARGS__) : (void) 0)
+#else
+#define DBG(LEVEL, ...)
+#endif
+
+long
+restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
+		struct pt_regs *regs)
+{
+	long err = 0;
+	compat_uint_t compat_reg;
+	compat_uint_t compat_regt;
+	int regn;
+	
+	/* When loading 32-bit values into 64-bit registers make
+	   sure to clear the upper 32-bits */
+	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
+	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
+	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
+	for(regn=0; regn < 32; regn++){
+		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
+		regs->gr[regn] = compat_reg;
+		/* Load upper half */
+		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
+		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
+		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
+				regn, regs->gr[regn], compat_regt, compat_reg);
+	}
+	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
+	/* XXX: BE WARNED FR's are 64-BIT! */
+	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
+		
+	/* Better safe than sorry, pass __get_user two things of
+	   the same size and let gcc do the upward conversion to 
+	   64-bits */		
+	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
+	/* Load upper half */
+	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
+	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
+	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
+	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
+			&sc->sc_iaoq[0], compat_reg);
+
+	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
+	/* Load upper half */
+	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
+	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
+	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
+	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
+			&sc->sc_iaoq[1],compat_reg);	
+	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
+			regs->iaoq[0],regs->iaoq[1]);		
+		
+	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
+	/* Load the upper half for iasq */
+	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
+	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
+	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
+	
+	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
+	/* Load the upper half for iasq */
+	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
+	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
+	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
+	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
+		regs->iasq[0],regs->iasq[1]);		
+
+	err |= __get_user(compat_reg, &sc->sc_sar);
+	/* Load the upper half for sar */
+	err |= __get_user(compat_regt, &rf->rf_sar);
+	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;	
+	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);	
+	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);		
+	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
+	
+	return err;
+}
+
+/*
+ * Set up the sigcontext structure for this process.
+ * This is not an easy task if the kernel is 64-bit, it will require
+ * that we examine the process personality to determine if we need to
+ * truncate for a 32-bit userspace.
+ */
+long
+setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
+		struct pt_regs *regs, int in_syscall)		 
+{
+	compat_int_t flags = 0;
+	long err = 0;
+	compat_uint_t compat_reg;
+	compat_uint_t compat_regb;
+	int regn;
+	
+	if (on_sig_stack((unsigned long) sc))
+		flags |= PARISC_SC_FLAG_ONSTACK;
+	
+	if (in_syscall) {
+		
+		DBG(1,"setup_sigcontext32: in_syscall\n");
+		
+		flags |= PARISC_SC_FLAG_IN_SYSCALL;
+		/* Truncate gr31 */
+		compat_reg = (compat_uint_t)(regs->gr[31]);
+		/* regs->iaoq is undefined in the syscall return path */
+		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
+		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
+				&sc->sc_iaoq[0], compat_reg);
+		
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
+		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
+		
+		
+		compat_reg = (compat_uint_t)(regs->gr[31]+4);
+		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
+		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
+				&sc->sc_iaoq[1], compat_reg);
+		/* Store upper half */
+		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
+		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
+		
+		/* Truncate sr3 */
+		compat_reg = (compat_uint_t)(regs->sr[3]);
+		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
+		err |= __put_user(compat_reg, &sc->sc_iasq[1]);		
+		
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
+		err |= __put_user(compat_reg, &rf->rf_iasq[1]);		
+		
+		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
+		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);		
+		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",				
+			regs->gr[31], regs->gr[31]+4);
+		
+	} else {
+		
+		compat_reg = (compat_uint_t)(regs->iaoq[0]);
+		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
+		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
+				&sc->sc_iaoq[0], compat_reg);
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);	
+		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
+		
+		compat_reg = (compat_uint_t)(regs->iaoq[1]);
+		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
+		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
+				&sc->sc_iaoq[1], compat_reg);
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
+		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
+		
+		
+		compat_reg = (compat_uint_t)(regs->iasq[0]);
+		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
+		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
+				&sc->sc_iasq[0], compat_reg);
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
+		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
+		
+		
+		compat_reg = (compat_uint_t)(regs->iasq[1]);
+		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
+		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
+				&sc->sc_iasq[1], compat_reg);
+		/* Store upper half */
+		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
+		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
+		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
+
+		/* Print out the IAOQ for debugging */		
+		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
+			regs->iaoq[0], regs->iaoq[1]);
+	}
+
+	err |= __put_user(flags, &sc->sc_flags);
+	
+	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
+	
+	for(regn=0; regn < 32; regn++){
+		/* Truncate a general register */
+		compat_reg = (compat_uint_t)(regs->gr[regn]);
+		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
+		/* Store upper half */
+		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
+		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
+
+		/* DEBUG: Write out the "upper / lower" register data */
+		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
+				compat_regb, compat_reg);
+	}
+	
+	/* Copy the floating point registers (same size)
+	   XXX: BE WARNED FR's are 64-BIT! */	
+	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
+	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
+		sizeof(regs->fr), sizeof(sc->sc_fr));
+	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
+
+	compat_reg = (compat_uint_t)(regs->sar);
+	err |= __put_user(compat_reg, &sc->sc_sar);
+	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
+	/* Store upper half */
+	compat_reg = (compat_uint_t)(regs->sar >> 32);
+	err |= __put_user(compat_reg, &rf->rf_sar);	
+	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
+	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
+
+	return err;
+}
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
new file mode 100644
index 0000000..a271dc0
--- /dev/null
+++ b/arch/parisc/kernel/signal32.h
@@ -0,0 +1,86 @@
+/* 
+ *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2003 Carlos O'Donell <carlos at parisc-linux.org>
+ *
+ *    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
+ */
+#ifndef _PARISC64_KERNEL_SIGNAL32_H
+#define _PARISC64_KERNEL_SIGNAL32_H
+
+#include <linux/compat.h>
+
+/* 32-bit ucontext as seen from an 64-bit kernel */
+struct compat_ucontext {
+        compat_uint_t uc_flags;
+        compat_uptr_t uc_link;
+        compat_stack_t uc_stack;        /* struct compat_sigaltstack (12 bytes)*/
+        /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */
+        compat_uint_t pad[1];
+        struct compat_sigcontext uc_mcontext;
+        compat_sigset_t uc_sigmask;     /* mask last for extensibility */
+};
+
+/* ELF32 signal handling */
+
+/* In a deft move of uber-hackery, we decide to carry the top half of all
+ * 64-bit registers in a non-portable, non-ABI, hidden structure.
+ * Userspace can read the hidden structure if it *wants* but is never
+ * guaranteed to be in the same place. In fact the uc_sigmask from the
+ * ucontext_t structure may push the hidden register file downards
+ */
+struct compat_regfile {
+        /* Upper half of all the 64-bit registers that were truncated
+           on a copy to a 32-bit userspace */
+        compat_int_t rf_gr[32];
+        compat_int_t rf_iasq[2];
+        compat_int_t rf_iaoq[2];
+        compat_int_t rf_sar;
+};
+
+#define COMPAT_SIGRETURN_TRAMP 4
+#define COMPAT_SIGRESTARTBLOCK_TRAMP 5
+#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
+				COMPAT_SIGRESTARTBLOCK_TRAMP)
+
+struct compat_rt_sigframe {
+        /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c
+                Secondary to that it must protect the ERESTART_RESTARTBLOCK
+                trampoline we left on the stack (we were bad and didn't
+                change sp so we could run really fast.) */
+        compat_uint_t tramp[COMPAT_TRAMP_SIZE];
+        compat_siginfo_t info;
+        struct compat_ucontext uc;
+        /* Hidden location of truncated registers, *must* be last. */
+        struct compat_regfile regs;
+};
+
+/*
+ * The 32-bit ABI wants at least 48 bytes for a function call frame:
+ * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of
+ * which Linux/parisc uses is sp-20 for the saved return pointer...)
+ * Then, the stack pointer must be rounded to a cache line (64 bytes).
+ */
+#define SIGFRAME32              64
+#define FUNCTIONCALLFRAME32     48
+#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
+
+long restore_sigcontext32(struct compat_sigcontext __user *sc, 
+		struct compat_regfile __user *rf,
+		struct pt_regs *regs);
+long setup_sigcontext32(struct compat_sigcontext __user *sc, 
+		struct compat_regfile __user *rf,
+		struct pt_regs *regs, int in_syscall);
+
+#endif
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
new file mode 100644
index 0000000..5e26dbe
--- /dev/null
+++ b/arch/parisc/kernel/smp.c
@@ -0,0 +1,430 @@
+/*
+** SMP Support
+**
+** Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+** Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+** Copyright (C) 2001,2004 Grant Grundler <grundler@parisc-linux.org>
+** 
+** Lots of stuff stolen from arch/alpha/kernel/smp.c
+** ...and then parisc stole from arch/ia64/kernel/smp.c. Thanks David! :^)
+**
+** Thanks to John Curry and Ullas Ponnadi. I learned a lot from their work.
+** -grant (1/12/2001)
+**
+**	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.
+*/
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched/mm.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/mm.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/ftrace.h>
+#include <linux/cpu.h>
+
+#include <linux/atomic.h>
+#include <asm/current.h>
+#include <asm/delay.h>
+#include <asm/tlbflush.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>		/* for CPU_IRQ_REGION and friends */
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/unistd.h>
+#include <asm/cacheflush.h>
+
+#undef DEBUG_SMP
+#ifdef DEBUG_SMP
+static int smp_debug_lvl = 0;
+#define smp_debug(lvl, printargs...)		\
+		if (lvl >= smp_debug_lvl)	\
+			printk(printargs);
+#else
+#define smp_debug(lvl, ...)	do { } while(0)
+#endif /* DEBUG_SMP */
+
+volatile struct task_struct *smp_init_current_idle_task;
+
+/* track which CPU is booting */
+static volatile int cpu_now_booting;
+
+static int parisc_max_cpus = 1;
+
+static DEFINE_PER_CPU(spinlock_t, ipi_lock);
+
+enum ipi_message_type {
+	IPI_NOP=0,
+	IPI_RESCHEDULE=1,
+	IPI_CALL_FUNC,
+	IPI_CPU_START,
+	IPI_CPU_STOP,
+	IPI_CPU_TEST
+};
+
+
+/********** SMP inter processor interrupt and communication routines */
+
+#undef PER_CPU_IRQ_REGION
+#ifdef PER_CPU_IRQ_REGION
+/* XXX REVISIT Ignore for now.
+**    *May* need this "hook" to register IPI handler
+**    once we have perCPU ExtIntr switch tables.
+*/
+static void
+ipi_init(int cpuid)
+{
+#error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region
+
+	if(cpu_online(cpuid) )
+	{
+		switch_to_idle_task(current);
+	}
+
+	return;
+}
+#endif
+
+
+/*
+** Yoink this CPU from the runnable list... 
+**
+*/
+static void
+halt_processor(void) 
+{
+	/* REVISIT : redirect I/O Interrupts to another CPU? */
+	/* REVISIT : does PM *know* this CPU isn't available? */
+	set_cpu_online(smp_processor_id(), false);
+	local_irq_disable();
+	for (;;)
+		;
+}
+
+
+irqreturn_t __irq_entry
+ipi_interrupt(int irq, void *dev_id) 
+{
+	int this_cpu = smp_processor_id();
+	struct cpuinfo_parisc *p = &per_cpu(cpu_data, this_cpu);
+	unsigned long ops;
+	unsigned long flags;
+
+	for (;;) {
+		spinlock_t *lock = &per_cpu(ipi_lock, this_cpu);
+		spin_lock_irqsave(lock, flags);
+		ops = p->pending_ipi;
+		p->pending_ipi = 0;
+		spin_unlock_irqrestore(lock, flags);
+
+		mb(); /* Order bit clearing and data access. */
+
+		if (!ops)
+		    break;
+
+		while (ops) {
+			unsigned long which = ffz(~ops);
+
+			ops &= ~(1 << which);
+
+			switch (which) {
+			case IPI_NOP:
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_NOP\n", this_cpu);
+				break;
+				
+			case IPI_RESCHEDULE:
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
+				inc_irq_stat(irq_resched_count);
+				scheduler_ipi();
+				break;
+
+			case IPI_CALL_FUNC:
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC\n", this_cpu);
+				generic_smp_call_function_interrupt();
+				break;
+
+			case IPI_CPU_START:
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
+				break;
+
+			case IPI_CPU_STOP:
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_STOP\n", this_cpu);
+				halt_processor();
+				break;
+
+			case IPI_CPU_TEST:
+				smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu);
+				break;
+
+			default:
+				printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
+					this_cpu, which);
+				return IRQ_NONE;
+			} /* Switch */
+		/* let in any pending interrupts */
+		local_irq_enable();
+		local_irq_disable();
+		} /* while (ops) */
+	}
+	return IRQ_HANDLED;
+}
+
+
+static inline void
+ipi_send(int cpu, enum ipi_message_type op)
+{
+	struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpu);
+	spinlock_t *lock = &per_cpu(ipi_lock, cpu);
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+	p->pending_ipi |= 1 << op;
+	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, p->hpa);
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static void
+send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op)
+{
+	int cpu;
+
+	for_each_cpu(cpu, mask)
+		ipi_send(cpu, op);
+}
+
+static inline void
+send_IPI_single(int dest_cpu, enum ipi_message_type op)
+{
+	BUG_ON(dest_cpu == NO_PROC_ID);
+
+	ipi_send(dest_cpu, op);
+}
+
+static inline void
+send_IPI_allbutself(enum ipi_message_type op)
+{
+	int i;
+	
+	for_each_online_cpu(i) {
+		if (i != smp_processor_id())
+			send_IPI_single(i, op);
+	}
+}
+
+
+inline void 
+smp_send_stop(void)	{ send_IPI_allbutself(IPI_CPU_STOP); }
+
+void 
+smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
+
+void
+smp_send_all_nop(void)
+{
+	send_IPI_allbutself(IPI_NOP);
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	send_IPI_mask(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+	send_IPI_single(cpu, IPI_CALL_FUNC);
+}
+
+/*
+ * Called by secondaries to update state and initialize CPU registers.
+ */
+static void __init
+smp_cpu_init(int cpunum)
+{
+	extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
+	extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
+
+	/* Set modes and Enable floating point coprocessor */
+	init_per_cpu(cpunum);
+
+	disable_sr_hashing();
+
+	mb();
+
+	/* Well, support 2.4 linux scheme as well. */
+	if (cpu_online(cpunum))	{
+		extern void machine_halt(void); /* arch/parisc.../process.c */
+
+		printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
+		machine_halt();
+	}
+
+	notify_cpu_starting(cpunum);
+
+	set_cpu_online(cpunum, true);
+
+	/* Initialise the idle task for this CPU */
+	mmgrab(&init_mm);
+	current->active_mm = &init_mm;
+	BUG_ON(current->mm);
+	enter_lazy_tlb(&init_mm, current);
+
+	init_IRQ();   /* make sure no IRQs are enabled or pending */
+	start_cpu_itimer();
+}
+
+
+/*
+ * Slaves start using C here. Indirectly called from smp_slave_stext.
+ * Do what start_kernel() and main() do for boot strap processor (aka monarch)
+ */
+void __init smp_callin(unsigned long pdce_proc)
+{
+	int slave_id = cpu_now_booting;
+
+#ifdef CONFIG_64BIT
+	WARN_ON(((unsigned long)(PAGE0->mem_pdc_hi) << 32
+			| PAGE0->mem_pdc) != pdce_proc);
+#endif
+
+	smp_cpu_init(slave_id);
+	preempt_disable();
+
+	flush_cache_all_local(); /* start with known state */
+	flush_tlb_all_local(NULL);
+
+	local_irq_enable();  /* Interrupts have been off until now */
+
+	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+
+	/* NOTREACHED */
+	panic("smp_callin() AAAAaaaaahhhh....\n");
+}
+
+/*
+ * Bring one cpu online.
+ */
+int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
+{
+	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
+	long timeout;
+
+	task_thread_info(idle)->cpu = cpuid;
+
+	/* Let _start know what logical CPU we're booting
+	** (offset into init_tasks[],cpu_data[])
+	*/
+	cpu_now_booting = cpuid;
+
+	/* 
+	** boot strap code needs to know the task address since
+	** it also contains the process stack.
+	*/
+	smp_init_current_idle_task = idle ;
+	mb();
+
+	printk(KERN_INFO "Releasing cpu %d now, hpa=%lx\n", cpuid, p->hpa);
+
+	/*
+	** This gets PDC to release the CPU from a very tight loop.
+	**
+	** From the PA-RISC 2.0 Firmware Architecture Reference Specification:
+	** "The MEM_RENDEZ vector specifies the location of OS_RENDEZ which 
+	** is executed after receiving the rendezvous signal (an interrupt to 
+	** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the 
+	** contents of memory are valid."
+	*/
+	gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, p->hpa);
+	mb();
+
+	/* 
+	 * OK, wait a bit for that CPU to finish staggering about. 
+	 * Slave will set a bit when it reaches smp_cpu_init().
+	 * Once the "monarch CPU" sees the bit change, it can move on.
+	 */
+	for (timeout = 0; timeout < 10000; timeout++) {
+		if(cpu_online(cpuid)) {
+			/* Which implies Slave has started up */
+			cpu_now_booting = 0;
+			smp_init_current_idle_task = NULL;
+			goto alive ;
+		}
+		udelay(100);
+		barrier();
+	}
+	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
+	return -1;
+
+alive:
+	/* Remember the Slave data */
+	smp_debug(100, KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
+		cpuid, timeout * 100);
+	return 0;
+}
+
+void __init smp_prepare_boot_cpu(void)
+{
+	int bootstrap_processor = per_cpu(cpu_data, 0).cpuid;
+
+	/* Setup BSP mappings */
+	printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
+
+	set_cpu_online(bootstrap_processor, true);
+	set_cpu_present(bootstrap_processor, true);
+}
+
+
+
+/*
+** inventory.c:do_inventory() hasn't yet been run and thus we
+** don't 'discover' the additional CPUs until later.
+*/
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		spin_lock_init(&per_cpu(ipi_lock, cpu));
+
+	init_cpu_present(cpumask_of(0));
+
+	parisc_max_cpus = max_cpus;
+	if (!max_cpus)
+		printk(KERN_INFO "SMP mode deactivated.\n");
+}
+
+
+void smp_cpus_done(unsigned int cpu_max)
+{
+	return;
+}
+
+
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
+{
+	if (cpu != 0 && cpu < parisc_max_cpus && smp_boot_one_cpu(cpu, tidle))
+		return -ENOSYS;
+
+	return cpu_online(cpu) ? 0 : -ENOSYS;
+}
+
+#ifdef CONFIG_PROC_FS
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return -EINVAL;
+}
+#endif
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c
new file mode 100644
index 0000000..ec5835e
--- /dev/null
+++ b/arch/parisc/kernel/stacktrace.c
@@ -0,0 +1,50 @@
+/*
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *  based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
+ *  and parisc unwind functions by Randolph Chung <tausq@debian.org>
+ *
+ *  TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
+ */
+#include <linux/module.h>
+#include <linux/stacktrace.h>
+
+#include <asm/unwind.h>
+
+static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+{
+	struct unwind_frame_info info;
+
+	unwind_frame_init_task(&info, task, NULL);
+
+	/* unwind stack and save entries in stack_trace struct */
+	trace->nr_entries = 0;
+	while (trace->nr_entries < trace->max_entries) {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			break;
+
+		if (__kernel_text_address(info.ip))
+			trace->entries[trace->nr_entries++] = info.ip;
+	}
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+	dump_trace(current, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+	dump_trace(tsk, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
new file mode 100644
index 0000000..376ea0d
--- /dev/null
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -0,0 +1,388 @@
+
+/*
+ *    PARISC specific syscalls
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *    Copyright (C) 1999-2014 Helge Deller <deller@gmx.de>
+ *
+ *
+ *    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
+ */
+
+#include <linux/uaccess.h>
+#include <asm/elf.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/sched/signal.h>
+#include <linux/sched/mm.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/utsname.h>
+#include <linux/personality.h>
+#include <linux/random.h>
+
+/* we construct an artificial offset for the mapping based on the physical
+ * address of the kernel mapping variable */
+#define GET_LAST_MMAP(filp)		\
+	(filp ? ((unsigned long) filp->f_mapping) >> 8 : 0UL)
+#define SET_LAST_MMAP(filp, val)	\
+	 { /* nothing */ }
+
+static int get_offset(unsigned int last_mmap)
+{
+	return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
+}
+
+static unsigned long shared_align_offset(unsigned int last_mmap,
+					 unsigned long pgoff)
+{
+	return (get_offset(last_mmap) + pgoff) << PAGE_SHIFT;
+}
+
+static inline unsigned long COLOR_ALIGN(unsigned long addr,
+			 unsigned int last_mmap, unsigned long pgoff)
+{
+	unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
+	unsigned long off  = (SHM_COLOUR-1) &
+		(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
+
+	return base + off;
+}
+
+/*
+ * Top of mmap area (just below the process stack).
+ */
+
+/*
+ * When called from arch_get_unmapped_area(), rlim_stack will be NULL,
+ * indicating that "current" should be used instead of a passed-in
+ * value from the exec bprm as done with arch_pick_mmap_layout().
+ */
+static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
+{
+	unsigned long stack_base;
+
+	/* Limit stack size - see setup_arg_pages() in fs/exec.c */
+	stack_base = rlim_stack ? rlim_stack->rlim_max
+				: rlimit_max(RLIMIT_STACK);
+	if (stack_base > STACK_SIZE_MAX)
+		stack_base = STACK_SIZE_MAX;
+
+	/* Add space for stack randomization. */
+	stack_base += (STACK_RND_MASK << PAGE_SHIFT);
+
+	return PAGE_ALIGN(STACK_TOP - stack_base);
+}
+
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma, *prev;
+	unsigned long task_size = TASK_SIZE;
+	int do_color_align, last_mmap;
+	struct vm_unmapped_area_info info;
+
+	if (len > task_size)
+		return -ENOMEM;
+
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	last_mmap = GET_LAST_MMAP(filp);
+
+	if (flags & MAP_FIXED) {
+		if ((flags & MAP_SHARED) && last_mmap &&
+		    (addr - shared_align_offset(last_mmap, pgoff))
+				& (SHM_COLOUR - 1))
+			return -EINVAL;
+		goto found_addr;
+	}
+
+	if (addr) {
+		if (do_color_align && last_mmap)
+			addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+
+		vma = find_vma_prev(mm, addr, &prev);
+		if (task_size - len >= addr &&
+		    (!vma || addr + len <= vm_start_gap(vma)) &&
+		    (!prev || addr >= vm_end_gap(prev)))
+			goto found_addr;
+	}
+
+	info.flags = 0;
+	info.length = len;
+	info.low_limit = mm->mmap_legacy_base;
+	info.high_limit = mmap_upper_limit(NULL);
+	info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+	info.align_offset = shared_align_offset(last_mmap, pgoff);
+	addr = vm_unmapped_area(&info);
+
+found_addr:
+	if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK))
+		SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT));
+
+	return addr;
+}
+
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+			  const unsigned long len, const unsigned long pgoff,
+			  const unsigned long flags)
+{
+	struct vm_area_struct *vma, *prev;
+	struct mm_struct *mm = current->mm;
+	unsigned long addr = addr0;
+	int do_color_align, last_mmap;
+	struct vm_unmapped_area_info info;
+
+	/* requested length too big for entire address space */
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	last_mmap = GET_LAST_MMAP(filp);
+
+	if (flags & MAP_FIXED) {
+		if ((flags & MAP_SHARED) && last_mmap &&
+		    (addr - shared_align_offset(last_mmap, pgoff))
+			& (SHM_COLOUR - 1))
+			return -EINVAL;
+		goto found_addr;
+	}
+
+	/* requesting a specific address */
+	if (addr) {
+		if (do_color_align && last_mmap)
+			addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+
+		vma = find_vma_prev(mm, addr, &prev);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vm_start_gap(vma)) &&
+		    (!prev || addr >= vm_end_gap(prev)))
+			goto found_addr;
+	}
+
+	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+	info.length = len;
+	info.low_limit = PAGE_SIZE;
+	info.high_limit = mm->mmap_base;
+	info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+	info.align_offset = shared_align_offset(last_mmap, pgoff);
+	addr = vm_unmapped_area(&info);
+	if (!(addr & ~PAGE_MASK))
+		goto found_addr;
+	VM_BUG_ON(addr != -ENOMEM);
+
+	/*
+	 * A failed mmap() very likely causes application failure,
+	 * so fall back to the bottom-up function here. This scenario
+	 * can happen with large stack limits and large mmap()
+	 * allocations.
+	 */
+	return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
+
+found_addr:
+	if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK))
+		SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT));
+
+	return addr;
+}
+
+static int mmap_is_legacy(void)
+{
+	if (current->personality & ADDR_COMPAT_LAYOUT)
+		return 1;
+
+	/* parisc stack always grows up - so a unlimited stack should
+	 * not be an indicator to use the legacy memory layout.
+	 * if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+	 *	return 1;
+	 */
+
+	return sysctl_legacy_va_layout;
+}
+
+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	if (current->flags & PF_RANDOMIZE)
+		rnd = get_random_int() & MMAP_RND_MASK;
+
+	return rnd << PAGE_SHIFT;
+}
+
+unsigned long arch_mmap_rnd(void)
+{
+	return (get_random_int() & MMAP_RND_MASK) << PAGE_SHIFT;
+}
+
+static unsigned long mmap_legacy_base(void)
+{
+	return TASK_UNMAPPED_BASE + mmap_rnd();
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
+{
+	mm->mmap_legacy_base = mmap_legacy_base();
+	mm->mmap_base = mmap_upper_limit(rlim_stack);
+
+	if (mmap_is_legacy()) {
+		mm->mmap_base = mm->mmap_legacy_base;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+	} else {
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+	}
+}
+
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long fd,
+	unsigned long pgoff)
+{
+	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
+	   we have. */
+	return ksys_mmap_pgoff(addr, len, prot, flags, fd,
+			       pgoff >> (PAGE_SHIFT - 12));
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+		unsigned long prot, unsigned long flags, unsigned long fd,
+		unsigned long offset)
+{
+	if (!(offset & ~PAGE_MASK)) {
+		return ksys_mmap_pgoff(addr, len, prot, flags, fd,
+					offset >> PAGE_SHIFT);
+	} else {
+		return -EINVAL;
+	}
+}
+
+/* Fucking broken ABI */
+
+#ifdef CONFIG_64BIT
+asmlinkage long parisc_truncate64(const char __user * path,
+					unsigned int high, unsigned int low)
+{
+	return ksys_truncate(path, (long)high << 32 | low);
+}
+
+asmlinkage long parisc_ftruncate64(unsigned int fd,
+					unsigned int high, unsigned int low)
+{
+	return ksys_ftruncate(fd, (long)high << 32 | low);
+}
+
+/* stubs for the benefit of the syscall_table since truncate64 and truncate 
+ * are identical on LP64 */
+asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
+{
+	return ksys_truncate(path, length);
+}
+asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
+{
+	return ksys_ftruncate(fd, length);
+}
+asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_fcntl(fd, cmd, arg);
+}
+#else
+
+asmlinkage long parisc_truncate64(const char __user * path,
+					unsigned int high, unsigned int low)
+{
+	return ksys_truncate(path, (loff_t)high << 32 | low);
+}
+
+asmlinkage long parisc_ftruncate64(unsigned int fd,
+					unsigned int high, unsigned int low)
+{
+	return sys_ftruncate64(fd, (loff_t)high << 32 | low);
+}
+#endif
+
+asmlinkage ssize_t parisc_pread64(unsigned int fd, char __user *buf, size_t count,
+					unsigned int high, unsigned int low)
+{
+	return ksys_pread64(fd, buf, count, (loff_t)high << 32 | low);
+}
+
+asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf,
+			size_t count, unsigned int high, unsigned int low)
+{
+	return ksys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
+}
+
+asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low,
+		                    size_t count)
+{
+	return ksys_readahead(fd, (loff_t)high << 32 | low, count);
+}
+
+asmlinkage long parisc_fadvise64_64(int fd,
+			unsigned int high_off, unsigned int low_off,
+			unsigned int high_len, unsigned int low_len, int advice)
+{
+	return ksys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off,
+			(loff_t)high_len << 32 | low_len, advice);
+}
+
+asmlinkage long parisc_sync_file_range(int fd,
+			u32 hi_off, u32 lo_off, u32 hi_nbytes, u32 lo_nbytes,
+			unsigned int flags)
+{
+	return ksys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off,
+			(loff_t)hi_nbytes << 32 | lo_nbytes, flags);
+}
+
+asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo,
+				u32 lenhi, u32 lenlo)
+{
+	return ksys_fallocate(fd, mode, ((u64)offhi << 32) | offlo,
+			      ((u64)lenhi << 32) | lenlo);
+}
+
+long parisc_personality(unsigned long personality)
+{
+	long err;
+
+	if (personality(current->personality) == PER_LINUX32
+	    && personality(personality) == PER_LINUX)
+		personality = (personality & ~PER_MASK) | PER_LINUX32;
+
+	err = sys_personality(personality);
+	if (personality(err) == PER_LINUX32)
+		err = (err & ~PER_MASK) | PER_LINUX;
+
+	return err;
+}
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
new file mode 100644
index 0000000..2a12a54
--- /dev/null
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * sys_parisc32.c: Conversion between 32bit and 64bit native syscalls.
+ *
+ * Copyright (C) 2000-2001 Hewlett Packard Company
+ * Copyright (C) 2000 John Marvin
+ * Copyright (C) 2001 Matthew Wilcox
+ * Copyright (C) 2014 Helge Deller <deller@gmx.de>
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * environment. Based heavily on sys_ia32.c and sys_sparc32.c.
+ */
+
+#include <linux/compat.h>
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+
+
+asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
+	int r22, int r21, int r20)
+{
+    printk(KERN_ERR "%s(%d): Unimplemented 32 on 64 syscall #%d!\n", 
+    	current->comm, current->pid, r20);
+    return -ENOSYS;
+}
+
+asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags,
+	compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
+	const char  __user * pathname)
+{
+	return sys_fanotify_mark(fanotify_fd, flags,
+			((__u64)mask1 << 32) | mask0,
+			 dfd, pathname);
+}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
new file mode 100644
index 0000000..f453997
--- /dev/null
+++ b/arch/parisc/kernel/syscall.S
@@ -0,0 +1,964 @@
+/* 
+ * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+ * 
+ * System call entry code / Linux gateway page
+ * Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
+ * Licensed under the GNU GPL.
+ * thanks to Philipp Rumpf, Mike Shaver and various others
+ * sorry about the wall, puffin..
+ */
+
+/*
+How does the Linux gateway page on PA-RISC work?
+------------------------------------------------
+The Linux gateway page on PA-RISC is "special".
+It actually has PAGE_GATEWAY bits set (this is linux terminology; in parisc
+terminology it's Execute, promote to PL0) in the page map.  So anything
+executing on this page executes with kernel level privilege (there's more to it
+than that: to have this happen, you also have to use a branch with a ,gate
+completer to activate the privilege promotion).  The upshot is that everything
+that runs on the gateway page runs at kernel privilege but with the current
+user process address space (although you have access to kernel space via %sr2).
+For the 0x100 syscall entry, we redo the space registers to point to the kernel
+address space (preserving the user address space in %sr3), move to wide mode if
+required, save the user registers and branch into the kernel syscall entry
+point.  For all the other functions, we execute at kernel privilege but don't
+flip address spaces. The basic upshot of this is that these code snippets are
+executed atomically (because the kernel can't be pre-empted) and they may
+perform architecturally forbidden (to PL3) operations (like setting control
+registers).
+*/
+
+
+#include <asm/asm-offsets.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/page.h>
+#include <asm/psw.h>
+#include <asm/thread_info.h>
+#include <asm/assembly.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+#include <linux/linkage.h>
+
+	/* We fill the empty parts of the gateway page with
+ 	 * something that will kill the kernel or a
+ 	 * userspace application.
+	 */
+#define KILL_INSN	break	0,0
+
+	.level          LEVEL
+
+	.text
+
+	.import syscall_exit,code
+	.import syscall_exit_rfi,code
+
+	/* Linux gateway page is aliased to virtual page 0 in the kernel
+	 * address space. Since it is a gateway page it cannot be
+	 * dereferenced, so null pointers will still fault. We start
+	 * the actual entry point at 0x100. We put break instructions
+	 * at the beginning of the page to trap null indirect function
+	 * pointers.
+	 */
+
+	.align PAGE_SIZE
+ENTRY(linux_gateway_page)
+
+        /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
+	.rept 44
+	KILL_INSN
+	.endr
+
+	/* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */
+	/* Light-weight-syscall entry must always be located at 0xb0 */
+	/* WARNING: Keep this number updated with table size changes */
+#define __NR_lws_entries (3)
+
+lws_entry:
+	gate	lws_start, %r0		/* increase privilege */
+	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
+
+	/* Fill from 0xb8 to 0xe0 */
+	.rept 10
+	KILL_INSN
+	.endr
+
+	/* This function MUST be located at 0xe0 for glibc's threading 
+	mechanism to work. DO NOT MOVE THIS CODE EVER! */
+set_thread_pointer:
+	gate	.+8, %r0		/* increase privilege */
+	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
+	be	0(%sr7,%r31)		/* return to user space */
+	mtctl	%r26, %cr27		/* move arg0 to the control register */
+
+	/* Increase the chance of trapping if random jumps occur to this
+	address, fill from 0xf0 to 0x100 */
+	.rept 4
+	KILL_INSN
+	.endr
+
+/* This address must remain fixed at 0x100 for glibc's syscalls to work */
+	.align LINUX_GATEWAY_ADDR
+linux_gateway_entry:
+	gate	.+8, %r0			/* become privileged */
+	mtsp	%r0,%sr4			/* get kernel space into sr4 */
+	mtsp	%r0,%sr5			/* get kernel space into sr5 */
+	mtsp	%r0,%sr6			/* get kernel space into sr6 */
+
+#ifdef CONFIG_64BIT
+	/* Store W bit on entry to the syscall in case it's a wide userland
+	 * process. */
+	ssm	PSW_SM_W, %r1
+	extrd,u	%r1,PSW_W_BIT,1,%r1
+	/* sp must be aligned on 4, so deposit the W bit setting into
+	 * the bottom of sp temporarily */
+	or,ev	%r1,%r30,%r30
+	b,n	1f
+	/* The top halves of argument registers must be cleared on syscall
+	 * entry from narrow executable.
+	 */
+	depdi	0, 31, 32, %r26
+	depdi	0, 31, 32, %r25
+	depdi	0, 31, 32, %r24
+	depdi	0, 31, 32, %r23
+	depdi	0, 31, 32, %r22
+	depdi	0, 31, 32, %r21
+1:	
+#endif
+
+	/* We use a rsm/ssm pair to prevent sr3 from being clobbered
+	 * by external interrupts.
+	 */
+	mfsp    %sr7,%r1                        /* save user sr7 */
+	rsm	PSW_SM_I, %r0			/* disable interrupts */
+	mtsp    %r1,%sr3                        /* and store it in sr3 */
+
+	mfctl   %cr30,%r1
+	xor     %r1,%r30,%r30                   /* ye olde xor trick */
+	xor     %r1,%r30,%r1
+	xor     %r1,%r30,%r30
+	
+	ldo     THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */
+
+	/* N.B.: It is critical that we don't set sr7 to 0 until r30
+	 *       contains a valid kernel stack pointer. It is also
+	 *       critical that we don't start using the kernel stack
+	 *       until after sr7 has been set to 0.
+	 */
+
+	mtsp	%r0,%sr7			/* get kernel space into sr7 */
+	ssm	PSW_SM_I, %r0			/* enable interrupts */
+	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
+	mfctl	%cr30,%r1			/* get task ptr in %r1 */
+	LDREG	TI_TASK(%r1),%r1
+
+	/* Save some registers for sigcontext and potential task
+	   switch (see entry.S for the details of which ones are
+	   saved/restored).  TASK_PT_PSW is zeroed so we can see whether
+	   a process is on a syscall or not.  For an interrupt the real
+	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
+	STREG	%r0,  TASK_PT_PSW(%r1)
+	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
+	STREG	%r19, TASK_PT_GR19(%r1)
+
+	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
+#ifdef CONFIG_64BIT
+	extrd,u	%r2,63,1,%r19			/* W hidden in bottom bit */
+#if 0
+	xor	%r19,%r2,%r2			/* clear bottom bit */
+	depd,z	%r19,1,1,%r19
+	std	%r19,TASK_PT_PSW(%r1)
+#endif
+#endif
+	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
+	
+	STREG	%r20, TASK_PT_GR20(%r1)		/* Syscall number */
+	STREG	%r21, TASK_PT_GR21(%r1)
+	STREG	%r22, TASK_PT_GR22(%r1)
+	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
+	STREG	%r24, TASK_PT_GR24(%r1)		/* 3rd argument */
+	STREG	%r25, TASK_PT_GR25(%r1)		/* 2nd argument */
+	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
+	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
+	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
+	STREG   %r0, TASK_PT_ORIG_R28(%r1)      /* don't prohibit restarts */
+	STREG	%r29, TASK_PT_GR29(%r1)		/* return value 1 */
+	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
+	
+	ldo	TASK_PT_FR0(%r1), %r27		/* save fpregs from the kernel */
+	save_fp	%r27				/* or potential task switch  */
+
+	mfctl	%cr11, %r27			/* i.e. SAR */
+	STREG	%r27, TASK_PT_SAR(%r1)
+
+	loadgp
+
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+	copy	%r19,%r2			/* W bit back to r2 */
+#else
+	/* no need to save these on stack in wide mode because the first 8
+	 * args are passed in registers */
+	stw     %r22, -52(%r30)                 /* 5th argument */
+	stw     %r21, -56(%r30)                 /* 6th argument */
+#endif
+
+	/* Are we being ptraced? */
+	mfctl	%cr30, %r1
+	LDREG	TI_FLAGS(%r1),%r1
+	ldi	_TIF_SYSCALL_TRACE_MASK, %r19
+	and,COND(=) %r1, %r19, %r0
+	b,n	.Ltracesys
+	
+	/* Note!  We cannot use the syscall table that is mapped
+	nearby since the gateway page is mapped execute-only. */
+
+#ifdef CONFIG_64BIT
+	ldil	L%sys_call_table, %r1
+	or,=	%r2,%r2,%r2
+	addil	L%(sys_call_table64-sys_call_table), %r1
+	ldo	R%sys_call_table(%r1), %r19
+	or,=	%r2,%r2,%r2
+	ldo	R%sys_call_table64(%r1), %r19
+#else
+	load32	sys_call_table, %r19
+#endif	
+	comiclr,>>	__NR_Linux_syscalls, %r20, %r0
+	b,n	.Lsyscall_nosys
+	
+	LDREGX  %r20(%r19), %r19
+
+	/* If this is a sys_rt_sigreturn call, and the signal was received
+	 * when not in_syscall, then we want to return via syscall_exit_rfi,
+	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
+	 * trampoline code in signal.c).
+	 */
+	ldi	__NR_rt_sigreturn,%r2
+	comb,=	%r2,%r20,.Lrt_sigreturn
+.Lin_syscall:
+	ldil	L%syscall_exit,%r2
+	be      0(%sr7,%r19)
+	ldo	R%syscall_exit(%r2),%r2
+.Lrt_sigreturn:
+	comib,<> 0,%r25,.Lin_syscall
+	ldil	L%syscall_exit_rfi,%r2
+	be      0(%sr7,%r19)
+	ldo	R%syscall_exit_rfi(%r2),%r2
+
+	/* Note!  Because we are not running where we were linked, any
+	calls to functions external to this file must be indirect.  To
+	be safe, we apply the opposite rule to functions within this
+	file, with local labels given to them to ensure correctness. */
+	
+.Lsyscall_nosys:
+syscall_nosys:
+	ldil	L%syscall_exit,%r1
+	be	R%syscall_exit(%sr7,%r1)
+	ldo	-ENOSYS(%r0),%r28		   /* set errno */
+
+
+/* Warning! This trace code is a virtual duplicate of the code above so be
+ * sure to maintain both! */
+.Ltracesys:
+tracesys:
+	/* Need to save more registers so the debugger can see where we
+	 * are.  This saves only the lower 8 bits of PSW, so that the C
+	 * bit is still clear on syscalls, and the D bit is set if this
+	 * full register save path has been executed.  We check the D
+	 * bit on syscall_return_rfi to determine which registers to
+	 * restore.  An interrupt results in a full PSW saved with the
+	 * C bit set, a non-straced syscall entry results in C and D clear
+	 * in the saved PSW.
+	 */
+	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+	LDREG	TI_TASK(%r1), %r1
+	ssm	0,%r2
+	STREG	%r2,TASK_PT_PSW(%r1)		/* Lower 8 bits only!! */
+	mfsp	%sr0,%r2
+	STREG	%r2,TASK_PT_SR0(%r1)
+	mfsp	%sr1,%r2
+	STREG	%r2,TASK_PT_SR1(%r1)
+	mfsp	%sr2,%r2
+	STREG	%r2,TASK_PT_SR2(%r1)
+	mfsp	%sr3,%r2
+	STREG	%r2,TASK_PT_SR3(%r1)
+	STREG	%r2,TASK_PT_SR4(%r1)
+	STREG	%r2,TASK_PT_SR5(%r1)
+	STREG	%r2,TASK_PT_SR6(%r1)
+	STREG	%r2,TASK_PT_SR7(%r1)
+	STREG	%r2,TASK_PT_IASQ0(%r1)
+	STREG	%r2,TASK_PT_IASQ1(%r1)
+	LDREG	TASK_PT_GR31(%r1),%r2
+	STREG	%r2,TASK_PT_IAOQ0(%r1)
+	ldo	4(%r2),%r2
+	STREG	%r2,TASK_PT_IAOQ1(%r1)
+	ldo	TASK_REGS(%r1),%r2
+	/* reg_save %r2 */
+	STREG	%r3,PT_GR3(%r2)
+	STREG	%r4,PT_GR4(%r2)
+	STREG	%r5,PT_GR5(%r2)
+	STREG	%r6,PT_GR6(%r2)
+	STREG	%r7,PT_GR7(%r2)
+	STREG	%r8,PT_GR8(%r2)
+	STREG	%r9,PT_GR9(%r2)
+	STREG	%r10,PT_GR10(%r2)
+	STREG	%r11,PT_GR11(%r2)
+	STREG	%r12,PT_GR12(%r2)
+	STREG	%r13,PT_GR13(%r2)
+	STREG	%r14,PT_GR14(%r2)
+	STREG	%r15,PT_GR15(%r2)
+	STREG	%r16,PT_GR16(%r2)
+	STREG	%r17,PT_GR17(%r2)
+	STREG	%r18,PT_GR18(%r2)
+	/* Finished saving things for the debugger */
+
+	copy	%r2,%r26
+	ldil	L%do_syscall_trace_enter,%r1
+	ldil	L%tracesys_next,%r2
+	be	R%do_syscall_trace_enter(%sr7,%r1)
+	ldo	R%tracesys_next(%r2),%r2
+	
+tracesys_next:
+	/* do_syscall_trace_enter either returned the syscallno, or -1L,
+	 *  so we skip restoring the PT_GR20 below, since we pulled it from
+	 *  task->thread.regs.gr[20] above.
+	 */
+	copy	%ret0,%r20
+
+	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+	LDREG	TI_TASK(%r1), %r1
+	LDREG   TASK_PT_GR28(%r1), %r28		/* Restore return value */
+	LDREG   TASK_PT_GR26(%r1), %r26		/* Restore the users args */
+	LDREG   TASK_PT_GR25(%r1), %r25
+	LDREG   TASK_PT_GR24(%r1), %r24
+	LDREG   TASK_PT_GR23(%r1), %r23
+	LDREG   TASK_PT_GR22(%r1), %r22
+	LDREG   TASK_PT_GR21(%r1), %r21
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#else
+	stw     %r22, -52(%r30)                 /* 5th argument */
+	stw     %r21, -56(%r30)                 /* 6th argument */
+#endif
+
+	cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */
+	comiclr,>>	__NR_Linux_syscalls, %r20, %r0
+	b,n	.Ltracesys_nosys
+
+	/* Note!  We cannot use the syscall table that is mapped
+	nearby since the gateway page is mapped execute-only. */
+
+#ifdef CONFIG_64BIT
+	LDREG	TASK_PT_GR30(%r1), %r19		/* get users sp back */
+	extrd,u	%r19,63,1,%r2			/* W hidden in bottom bit */
+
+	ldil	L%sys_call_table, %r1
+	or,=	%r2,%r2,%r2
+	addil	L%(sys_call_table64-sys_call_table), %r1
+	ldo	R%sys_call_table(%r1), %r19
+	or,=	%r2,%r2,%r2
+	ldo	R%sys_call_table64(%r1), %r19
+#else
+	load32	sys_call_table, %r19
+#endif
+
+	LDREGX  %r20(%r19), %r19
+
+	/* If this is a sys_rt_sigreturn call, and the signal was received
+	 * when not in_syscall, then we want to return via syscall_exit_rfi,
+	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
+	 * trampoline code in signal.c).
+	 */
+	ldi	__NR_rt_sigreturn,%r2
+	comb,=	%r2,%r20,.Ltrace_rt_sigreturn
+.Ltrace_in_syscall:
+	ldil	L%tracesys_exit,%r2
+	be      0(%sr7,%r19)
+	ldo	R%tracesys_exit(%r2),%r2
+
+.Ltracesys_nosys:
+	ldo	-ENOSYS(%r0),%r28		/* set errno */
+
+	/* Do *not* call this function on the gateway page, because it
+	makes a direct call to syscall_trace. */
+	
+tracesys_exit:
+	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+	LDREG	TI_TASK(%r1), %r1
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+	ldo	TASK_REGS(%r1),%r26
+	BL	do_syscall_trace_exit,%r2
+	STREG   %r28,TASK_PT_GR28(%r1)          /* save return value now */
+	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+	LDREG	TI_TASK(%r1), %r1
+	LDREG   TASK_PT_GR28(%r1), %r28		/* Restore return val. */
+
+	ldil	L%syscall_exit,%r1
+	be,n	R%syscall_exit(%sr7,%r1)
+
+.Ltrace_rt_sigreturn:
+	comib,<> 0,%r25,.Ltrace_in_syscall
+	ldil	L%tracesys_sigexit,%r2
+	be      0(%sr7,%r19)
+	ldo	R%tracesys_sigexit(%r2),%r2
+
+tracesys_sigexit:
+	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+	LDREG	TI_TASK(%r1), %r1
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+	BL	do_syscall_trace_exit,%r2
+	ldo	TASK_REGS(%r1),%r26
+
+	ldil	L%syscall_exit_rfi,%r1
+	be,n	R%syscall_exit_rfi(%sr7,%r1)
+
+
+	/*********************************************************
+		32/64-bit Light-Weight-Syscall ABI
+
+		* - Indicates a hint for userspace inline asm
+		implementations.
+
+		Syscall number (caller-saves)
+	        - %r20
+	        * In asm clobber.
+
+		Argument registers (caller-saves)
+	        - %r26, %r25, %r24, %r23, %r22
+	        * In asm input.
+
+		Return registers (caller-saves)
+	        - %r28 (return), %r21 (errno)
+	        * In asm output.
+
+		Caller-saves registers
+	        - %r1, %r27, %r29
+	        - %r2 (return pointer)
+	        - %r31 (ble link register)
+	        * In asm clobber.
+
+		Callee-saves registers
+	        - %r3-%r18
+	        - %r30 (stack pointer)
+	        * Not in asm clobber.
+
+		If userspace is 32-bit:
+		Callee-saves registers
+	        - %r19 (32-bit PIC register)
+
+		Differences from 32-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r19.
+
+		If userspace is 64-bit:
+		Callee-saves registers
+		- %r27 (64-bit PIC register)
+
+		Differences from 64-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r27.
+
+		Error codes returned by entry path:
+
+		ENOSYS - r20 was an invalid LWS number.
+
+	*********************************************************/
+lws_start:
+
+#ifdef CONFIG_64BIT
+	ssm	PSW_SM_W, %r1
+	extrd,u	%r1,PSW_W_BIT,1,%r1
+	/* sp must be aligned on 4, so deposit the W bit setting into
+	 * the bottom of sp temporarily */
+	or,ev	%r1,%r30,%r30
+
+	/* Clip LWS number to a 32-bit value for 32-bit processes */
+	depdi	0, 31, 32, %r20
+#endif	
+
+        /* Is the lws entry number valid? */
+	comiclr,>>	__NR_lws_entries, %r20, %r0
+	b,n	lws_exit_nosys
+
+	/* Load table start */
+	ldil	L%lws_table, %r1
+	ldo	R%lws_table(%r1), %r28	/* Scratch use of r28 */
+	LDREGX	%r20(%sr2,r28), %r21	/* Scratch use of r21 */
+
+	/* Jump to lws, lws table pointers already relocated */
+	be,n	0(%sr2,%r21)
+
+lws_exit_nosys:
+	ldo	-ENOSYS(%r0),%r21		   /* set errno */
+	/* Fall through: Return to userspace */
+
+lws_exit:
+#ifdef CONFIG_64BIT
+	/* decide whether to reset the wide mode bit
+	 *
+	 * For a syscall, the W bit is stored in the lowest bit
+	 * of sp.  Extract it and reset W if it is zero */
+	extrd,u,*<>	%r30,63,1,%r1
+	rsm	PSW_SM_W, %r0
+	/* now reset the lowest bit of sp if it was set */
+	xor	%r30,%r1,%r30
+#endif
+	be,n	0(%sr7, %r31)
+
+
+	
+	/***************************************************
+		Implementing 32bit CAS as an atomic operation:
+
+		%r26 - Address to examine
+		%r25 - Old value to check (old)
+		%r24 - New value to set (new)
+		%r28 - Return prev through this register.
+		%r21 - Kernel error code
+
+		If debugging is DISabled:
+
+		%r21 has the following meanings:
+
+		EAGAIN - CAS is busy, ldcw failed, try again.
+		EFAULT - Read or write failed.		
+
+		If debugging is enabled:
+
+		EDEADLOCK - CAS called recursively.
+		EAGAIN && r28 == 1 - CAS is busy. Lock contended.
+		EAGAIN && r28 == 2 - CAS is busy. ldcw failed.
+		EFAULT - Read or write failed.
+
+		Scratch: r20, r28, r1
+
+	****************************************************/
+
+	/* Do not enable LWS debugging */
+#define ENABLE_LWS_DEBUG 0 
+
+	/* ELF64 Process entry path */
+lws_compare_and_swap64:
+#ifdef CONFIG_64BIT
+	b,n	lws_compare_and_swap
+#else
+	/* If we are not a 64-bit kernel, then we don't
+	 * have 64-bit input registers, and calling
+	 * the 64-bit LWS CAS returns ENOSYS.
+	 */
+	b,n	lws_exit_nosys
+#endif
+
+	/* ELF32 Process entry path */
+lws_compare_and_swap32:
+#ifdef CONFIG_64BIT
+	/* Clip all the input registers */
+	depdi	0, 31, 32, %r26
+	depdi	0, 31, 32, %r25
+	depdi	0, 31, 32, %r24
+#endif
+
+lws_compare_and_swap:
+	/* Load start of lock table */
+	ldil	L%lws_lock_start, %r20
+	ldo	R%lws_lock_start(%r20), %r28
+
+	/* Extract four bits from r26 and hash lock (Bits 4-7) */
+	extru  %r26, 27, 4, %r20
+
+	/* Find lock to use, the hash is either one of 0 to
+	   15, multiplied by 16 (keep it 16-byte aligned)
+	   and add to the lock table offset. */
+	shlw	%r20, 4, %r20
+	add	%r20, %r28, %r20
+
+# if ENABLE_LWS_DEBUG
+	/*	
+		DEBUG, check for deadlock! 
+		If the thread register values are the same
+		then we were the one that locked it last and
+		this is a recurisve call that will deadlock.
+		We *must* giveup this call and fail.
+	*/
+	ldw	4(%sr2,%r20), %r28			/* Load thread register */
+	/* WARNING: If cr27 cycles to the same value we have problems */
+	mfctl	%cr27, %r21				/* Get current thread register */
+	cmpb,<>,n	%r21, %r28, cas_lock		/* Called recursive? */
+	b	lws_exit				/* Return error! */
+	ldo	-EDEADLOCK(%r0), %r21
+cas_lock:
+	cmpb,=,n	%r0, %r28, cas_nocontend	/* Is nobody using it? */
+	ldo	1(%r0), %r28				/* 1st case */
+	b	lws_exit				/* Contended... */
+	ldo	-EAGAIN(%r0), %r21			/* Spin in userspace */
+cas_nocontend:
+# endif
+/* ENABLE_LWS_DEBUG */
+
+	rsm	PSW_SM_I, %r0				/* Disable interrupts */
+	/* COW breaks can cause contention on UP systems */
+	LDCW	0(%sr2,%r20), %r28			/* Try to acquire the lock */
+	cmpb,<>,n	%r0, %r28, cas_action		/* Did we get it? */
+cas_wouldblock:
+	ldo	2(%r0), %r28				/* 2nd case */
+	ssm	PSW_SM_I, %r0
+	b	lws_exit				/* Contended... */
+	ldo	-EAGAIN(%r0), %r21			/* Spin in userspace */
+
+	/*
+		prev = *addr;
+		if ( prev == old )
+		  *addr = new;
+		return prev;
+	*/
+
+	/* NOTES:
+		This all works becuse intr_do_signal
+		and schedule both check the return iasq
+		and see that we are on the kernel page
+		so this process is never scheduled off
+		or is ever sent any signal of any sort,
+		thus it is wholly atomic from usrspaces
+		perspective
+	*/
+cas_action:
+#if defined CONFIG_SMP && ENABLE_LWS_DEBUG
+	/* DEBUG */
+	mfctl	%cr27, %r1
+	stw	%r1, 4(%sr2,%r20)
+#endif
+	/* The load and store could fail */
+1:	ldw	0(%r26), %r28
+	sub,<>	%r28, %r25, %r0
+2:	stw	%r24, 0(%r26)
+	/* Free lock */
+	sync
+	stw	%r20, 0(%sr2,%r20)
+#if ENABLE_LWS_DEBUG
+	/* Clear thread register indicator */
+	stw	%r0, 4(%sr2,%r20)
+#endif
+	/* Enable interrupts */
+	ssm	PSW_SM_I, %r0
+	/* Return to userspace, set no error */
+	b	lws_exit
+	copy	%r0, %r21
+
+3:		
+	/* Error occurred on load or store */
+	/* Free lock */
+	sync
+	stw	%r20, 0(%sr2,%r20)
+#if ENABLE_LWS_DEBUG
+	stw	%r0, 4(%sr2,%r20)
+#endif
+	ssm	PSW_SM_I, %r0
+	b	lws_exit
+	ldo	-EFAULT(%r0),%r21	/* set errno */
+	nop
+	nop
+	nop
+	nop
+
+	/* Two exception table entries, one for the load,
+	   the other for the store. Either return -EFAULT.
+	   Each of the entries must be relocated. */
+	ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)
+
+
+	/***************************************************
+		New CAS implementation which uses pointers and variable size
+		information. The value pointed by old and new MUST NOT change
+		while performing CAS. The lock only protect the value at %r26.
+
+		%r26 - Address to examine
+		%r25 - Pointer to the value to check (old)
+		%r24 - Pointer to the value to set (new)
+		%r23 - Size of the variable (0/1/2/3 for 8/16/32/64 bit)
+		%r28 - Return non-zero on failure
+		%r21 - Kernel error code
+
+		%r21 has the following meanings:
+
+		EAGAIN - CAS is busy, ldcw failed, try again.
+		EFAULT - Read or write failed.
+
+		Scratch: r20, r22, r28, r29, r1, fr4 (32bit for 64bit CAS only)
+
+	****************************************************/
+
+	/* ELF32 Process entry path */
+lws_compare_and_swap_2:
+#ifdef CONFIG_64BIT
+	/* Clip the input registers. We don't need to clip %r23 as we
+	   only use it for word operations */
+	depdi	0, 31, 32, %r26
+	depdi	0, 31, 32, %r25
+	depdi	0, 31, 32, %r24
+#endif
+
+	/* Check the validity of the size pointer */
+	subi,>>= 3, %r23, %r0
+	b,n	lws_exit_nosys
+
+	/* Jump to the functions which will load the old and new values into
+	   registers depending on the their size */
+	shlw	%r23, 2, %r29
+	blr	%r29, %r0
+	nop
+
+	/* 8bit load */
+4:	ldb	0(%r25), %r25
+	b	cas2_lock_start
+5:	ldb	0(%r24), %r24
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* 16bit load */
+6:	ldh	0(%r25), %r25
+	b	cas2_lock_start
+7:	ldh	0(%r24), %r24
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* 32bit load */
+8:	ldw	0(%r25), %r25
+	b	cas2_lock_start
+9:	ldw	0(%r24), %r24
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* 64bit load */
+#ifdef CONFIG_64BIT
+10:	ldd	0(%r25), %r25
+11:	ldd	0(%r24), %r24
+#else
+	/* Load old value into r22/r23 - high/low */
+10:	ldw	0(%r25), %r22
+11:	ldw	4(%r25), %r23
+	/* Load new value into fr4 for atomic store later */
+12:	flddx	0(%r24), %fr4
+#endif
+
+cas2_lock_start:
+	/* Load start of lock table */
+	ldil	L%lws_lock_start, %r20
+	ldo	R%lws_lock_start(%r20), %r28
+
+	/* Extract four bits from r26 and hash lock (Bits 4-7) */
+	extru  %r26, 27, 4, %r20
+
+	/* Find lock to use, the hash is either one of 0 to
+	   15, multiplied by 16 (keep it 16-byte aligned)
+	   and add to the lock table offset. */
+	shlw	%r20, 4, %r20
+	add	%r20, %r28, %r20
+
+	rsm	PSW_SM_I, %r0			/* Disable interrupts */
+	/* COW breaks can cause contention on UP systems */
+	LDCW	0(%sr2,%r20), %r28		/* Try to acquire the lock */
+	cmpb,<>,n	%r0, %r28, cas2_action	/* Did we get it? */
+cas2_wouldblock:
+	ldo	2(%r0), %r28			/* 2nd case */
+	ssm	PSW_SM_I, %r0
+	b	lws_exit			/* Contended... */
+	ldo	-EAGAIN(%r0), %r21		/* Spin in userspace */
+
+	/*
+		prev = *addr;
+		if ( prev == old )
+		  *addr = new;
+		return prev;
+	*/
+
+	/* NOTES:
+		This all works becuse intr_do_signal
+		and schedule both check the return iasq
+		and see that we are on the kernel page
+		so this process is never scheduled off
+		or is ever sent any signal of any sort,
+		thus it is wholly atomic from usrspaces
+		perspective
+	*/
+cas2_action:
+	/* Jump to the correct function */
+	blr	%r29, %r0
+	/* Set %r28 as non-zero for now */
+	ldo	1(%r0),%r28
+
+	/* 8bit CAS */
+13:	ldb	0(%r26), %r29
+	sub,=	%r29, %r25, %r0
+	b,n	cas2_end
+14:	stb	%r24, 0(%r26)
+	b	cas2_end
+	copy	%r0, %r28
+	nop
+	nop
+
+	/* 16bit CAS */
+15:	ldh	0(%r26), %r29
+	sub,=	%r29, %r25, %r0
+	b,n	cas2_end
+16:	sth	%r24, 0(%r26)
+	b	cas2_end
+	copy	%r0, %r28
+	nop
+	nop
+
+	/* 32bit CAS */
+17:	ldw	0(%r26), %r29
+	sub,=	%r29, %r25, %r0
+	b,n	cas2_end
+18:	stw	%r24, 0(%r26)
+	b	cas2_end
+	copy	%r0, %r28
+	nop
+	nop
+
+	/* 64bit CAS */
+#ifdef CONFIG_64BIT
+19:	ldd	0(%r26), %r29
+	sub,*=	%r29, %r25, %r0
+	b,n	cas2_end
+20:	std	%r24, 0(%r26)
+	copy	%r0, %r28
+#else
+	/* Compare first word */
+19:	ldw	0(%r26), %r29
+	sub,=	%r29, %r22, %r0
+	b,n	cas2_end
+	/* Compare second word */
+20:	ldw	4(%r26), %r29
+	sub,=	%r29, %r23, %r0
+	b,n	cas2_end
+	/* Perform the store */
+21:	fstdx	%fr4, 0(%r26)
+	copy	%r0, %r28
+#endif
+
+cas2_end:
+	/* Free lock */
+	sync
+	stw	%r20, 0(%sr2,%r20)
+	/* Enable interrupts */
+	ssm	PSW_SM_I, %r0
+	/* Return to userspace, set no error */
+	b	lws_exit
+	copy	%r0, %r21
+
+22:
+	/* Error occurred on load or store */
+	/* Free lock */
+	sync
+	stw	%r20, 0(%sr2,%r20)
+	ssm	PSW_SM_I, %r0
+	ldo	1(%r0),%r28
+	b	lws_exit
+	ldo	-EFAULT(%r0),%r21	/* set errno */
+	nop
+	nop
+	nop
+
+	/* Exception table entries, for the load and store, return EFAULT.
+	   Each of the entries must be relocated. */
+	ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 22b-linux_gateway_page)
+#ifndef CONFIG_64BIT
+	ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 22b-linux_gateway_page)
+	ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 22b-linux_gateway_page)
+#endif
+
+	/* Make sure nothing else is placed on this page */
+	.align PAGE_SIZE
+END(linux_gateway_page)
+ENTRY(end_linux_gateway_page)
+
+	/* Relocate symbols assuming linux_gateway_page is mapped
+	   to virtual address 0x0 */
+
+#define LWS_ENTRY(_name_) ASM_ULONG_INSN (lws_##_name_ - linux_gateway_page)
+
+	.section .rodata,"a"
+
+	.align 8
+	/* Light-weight-syscall table */
+	/* Start of lws table. */
+ENTRY(lws_table)
+	LWS_ENTRY(compare_and_swap32)		/* 0 - ELF32 Atomic 32bit CAS */
+	LWS_ENTRY(compare_and_swap64)		/* 1 - ELF64 Atomic 32bit CAS */
+	LWS_ENTRY(compare_and_swap_2)		/* 2 - ELF32 Atomic 64bit CAS */
+END(lws_table)
+	/* End of lws table */
+
+	.align 8
+ENTRY(sys_call_table)
+	.export sys_call_table,data
+#include "syscall_table.S"
+END(sys_call_table)
+
+#ifdef CONFIG_64BIT
+	.align 8
+ENTRY(sys_call_table64)
+#define SYSCALL_TABLE_64BIT
+#include "syscall_table.S"
+END(sys_call_table64)
+#endif
+
+	/*
+		All light-weight-syscall atomic operations 
+		will use this set of locks 
+
+		NOTE: The lws_lock_start symbol must be
+		at least 16-byte aligned for safe use
+		with ldcw.
+	*/
+	.section .data
+	.align	L1_CACHE_BYTES
+ENTRY(lws_lock_start)
+	/* lws locks */
+	.rept 16
+	/* Keep locks aligned at 16-bytes */
+	.word 1
+	.word 0 
+	.word 0
+	.word 0
+	.endr
+END(lws_lock_start)
+	.previous
+
+.end
+
+
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
new file mode 100644
index 0000000..fe3f2a4
--- /dev/null
+++ b/arch/parisc/kernel/syscall_table.S
@@ -0,0 +1,459 @@
+/*    System Call Table
+ *
+ *    Copyright (C) 1999-2004 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 Alan Modra <amodra at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler at parisc-linux.org>
+ *    Copyright (C) 2001 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001-2007 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2005-2006 Kyle McMartin <kyle at parisc-linux.org>
+ *
+ *    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
+ */
+
+#if defined(CONFIG_64BIT) && !defined(SYSCALL_TABLE_64BIT)
+/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
+ * narrow palinux.  Use ENTRY_DIFF for those where a 32-bit specific
+ * implementation is required on wide palinux.  Use ENTRY_COMP where
+ * the compatibility layer has a useful 32-bit implementation.
+ */
+#define ENTRY_SAME(_name_) .dword sys_##_name_
+#define ENTRY_DIFF(_name_) .dword sys32_##_name_
+#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
+#define ENTRY_OURS(_name_) .dword parisc_##_name_
+#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
+#elif defined(CONFIG_64BIT) && defined(SYSCALL_TABLE_64BIT)
+#define ENTRY_SAME(_name_) .dword sys_##_name_
+#define ENTRY_DIFF(_name_) .dword sys_##_name_
+#define ENTRY_UHOH(_name_) .dword sys_##_name_
+#define ENTRY_OURS(_name_) .dword sys_##_name_
+#define ENTRY_COMP(_name_) .dword sys_##_name_
+#else
+#define ENTRY_SAME(_name_) .word sys_##_name_
+#define ENTRY_DIFF(_name_) .word sys_##_name_
+#define ENTRY_UHOH(_name_) .word sys_##_name_
+#define ENTRY_OURS(_name_) .word parisc_##_name_
+#define ENTRY_COMP(_name_) .word sys_##_name_
+#endif
+
+90:	ENTRY_SAME(restart_syscall)	/* 0 */
+91:	ENTRY_SAME(exit)
+	ENTRY_SAME(fork_wrapper)
+	ENTRY_SAME(read)
+	ENTRY_SAME(write)
+	ENTRY_COMP(open)		/* 5 */
+	ENTRY_SAME(close)
+	ENTRY_SAME(waitpid)
+	ENTRY_SAME(creat)
+	ENTRY_SAME(link)
+	ENTRY_SAME(unlink)		/* 10 */
+	ENTRY_COMP(execve)
+	ENTRY_SAME(chdir)
+	/* See comments in kernel/time.c!!! Maybe we don't need this? */
+	ENTRY_COMP(time)
+	ENTRY_SAME(mknod)
+	ENTRY_SAME(chmod)		/* 15 */
+	ENTRY_SAME(lchown)
+	ENTRY_SAME(socket)
+	/* struct stat is MAYBE identical wide and narrow ?? */
+	ENTRY_COMP(newstat)
+	ENTRY_COMP(lseek)
+	ENTRY_SAME(getpid)		/* 20 */
+	/* the 'void * data' parameter may need re-packing in wide */
+	ENTRY_COMP(mount)
+	/* concerned about struct sockaddr in wide/narrow */
+	/* ---> I think sockaddr is OK unless the compiler packs the struct */
+	/*      differently to align the char array */
+	ENTRY_SAME(bind)
+	ENTRY_SAME(setuid)
+	ENTRY_SAME(getuid)
+	ENTRY_COMP(stime)		/* 25 */
+	ENTRY_COMP(ptrace)
+	ENTRY_SAME(alarm)
+	/* see stat comment */
+	ENTRY_COMP(newfstat)
+	ENTRY_SAME(pause)
+	/* struct utimbuf uses time_t which might vary */
+	ENTRY_COMP(utime)		/* 30 */
+	/* struct sockaddr... */
+	ENTRY_SAME(connect)
+	ENTRY_SAME(listen)
+	ENTRY_SAME(access)
+	ENTRY_SAME(nice)
+	/* struct sockaddr... */
+	ENTRY_SAME(accept)		/* 35 */
+	ENTRY_SAME(sync)
+	ENTRY_SAME(kill)
+	ENTRY_SAME(rename)
+	ENTRY_SAME(mkdir)
+	ENTRY_SAME(rmdir)		/* 40 */
+	ENTRY_SAME(dup)
+	ENTRY_SAME(pipe)
+	ENTRY_COMP(times)
+	/* struct sockaddr... */
+	ENTRY_SAME(getsockname)
+	/* it seems possible brk() could return a >4G pointer... */
+	ENTRY_SAME(brk)			/* 45 */
+	ENTRY_SAME(setgid)
+	ENTRY_SAME(getgid)
+	ENTRY_SAME(signal)
+	ENTRY_SAME(geteuid)
+	ENTRY_SAME(getegid)		/* 50 */
+	ENTRY_SAME(acct)
+	ENTRY_SAME(umount)
+	/* struct sockaddr... */
+	ENTRY_SAME(getpeername)
+	ENTRY_COMP(ioctl)
+	ENTRY_COMP(fcntl)		/* 55 */
+	ENTRY_SAME(socketpair)
+	ENTRY_SAME(setpgid)
+	ENTRY_SAME(send)
+	ENTRY_SAME(newuname)
+	ENTRY_SAME(umask)		/* 60 */
+	ENTRY_SAME(chroot)
+	ENTRY_COMP(ustat)
+	ENTRY_SAME(dup2)
+	ENTRY_SAME(getppid)
+	ENTRY_SAME(getpgrp)		/* 65 */
+	ENTRY_SAME(setsid)
+	ENTRY_SAME(pivot_root)
+	/* I don't like this */
+	ENTRY_UHOH(sgetmask)
+	ENTRY_UHOH(ssetmask)
+	ENTRY_SAME(setreuid)		/* 70 */
+	ENTRY_SAME(setregid)
+	ENTRY_SAME(mincore)
+	ENTRY_COMP(sigpending)
+	ENTRY_SAME(sethostname)
+	/* Following 3 have linux-common-code structs containing longs -( */
+	ENTRY_COMP(setrlimit)		/* 75 */
+	ENTRY_COMP(getrlimit)
+	ENTRY_COMP(getrusage)
+	/* struct timeval and timezone are maybe?? consistent wide and narrow */
+	ENTRY_COMP(gettimeofday)
+	ENTRY_COMP(settimeofday)
+	ENTRY_SAME(getgroups)		/* 80 */
+	ENTRY_SAME(setgroups)
+	/* struct socketaddr... */
+	ENTRY_SAME(sendto)
+	ENTRY_SAME(symlink)
+	/* see stat comment */
+	ENTRY_COMP(newlstat)
+	ENTRY_SAME(readlink)		/* 85 */
+	ENTRY_SAME(ni_syscall)	/* was uselib */
+	ENTRY_SAME(swapon)
+	ENTRY_SAME(reboot)
+	ENTRY_SAME(mmap2)
+	ENTRY_SAME(mmap)		/* 90 */
+	ENTRY_SAME(munmap)
+	ENTRY_COMP(truncate)
+	ENTRY_COMP(ftruncate)
+	ENTRY_SAME(fchmod)
+	ENTRY_SAME(fchown)		/* 95 */
+	ENTRY_SAME(getpriority)
+	ENTRY_SAME(setpriority)
+	ENTRY_SAME(recv)
+	ENTRY_COMP(statfs)
+	ENTRY_COMP(fstatfs)		/* 100 */
+	ENTRY_SAME(stat64)
+	ENTRY_SAME(ni_syscall)	/* was socketcall */
+	ENTRY_SAME(syslog)
+	/* even though manpage says struct timeval contains longs, ours has
+	 * time_t and suseconds_t -- both of which are safe wide/narrow */
+	ENTRY_COMP(setitimer)
+	ENTRY_COMP(getitimer)		/* 105 */
+	ENTRY_SAME(capget)
+	ENTRY_SAME(capset)
+	ENTRY_OURS(pread64)
+	ENTRY_OURS(pwrite64)
+	ENTRY_SAME(getcwd)		/* 110 */
+	ENTRY_SAME(vhangup)
+	ENTRY_SAME(fstat64)
+	ENTRY_SAME(vfork_wrapper)
+	/* struct rusage contains longs... */
+	ENTRY_COMP(wait4)
+	ENTRY_SAME(swapoff)		/* 115 */
+	ENTRY_COMP(sysinfo)
+	ENTRY_SAME(shutdown)
+	ENTRY_SAME(fsync)
+	ENTRY_SAME(madvise)
+	ENTRY_SAME(clone_wrapper)	/* 120 */
+	ENTRY_SAME(setdomainname)
+	ENTRY_COMP(sendfile)
+	/* struct sockaddr... */
+	ENTRY_SAME(recvfrom)
+	/* struct timex contains longs */
+	ENTRY_COMP(adjtimex)
+	ENTRY_SAME(mprotect)		/* 125 */
+	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
+	ENTRY_COMP(sigprocmask)
+	ENTRY_SAME(ni_syscall)	/* create_module */
+	ENTRY_SAME(init_module)
+	ENTRY_SAME(delete_module)
+	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
+	/* time_t inside struct dqblk */
+	ENTRY_SAME(quotactl)
+	ENTRY_SAME(getpgid)
+	ENTRY_SAME(fchdir)
+	ENTRY_SAME(bdflush)
+	ENTRY_SAME(sysfs)		/* 135 */
+	ENTRY_OURS(personality)
+	ENTRY_SAME(ni_syscall)	/* for afs_syscall */
+	ENTRY_SAME(setfsuid)
+	ENTRY_SAME(setfsgid)
+	/* I think this might work */
+	ENTRY_SAME(llseek)		/* 140 */
+	ENTRY_COMP(getdents)
+	/* it is POSSIBLE that select will be OK because even though fd_set
+	 * contains longs, the macros and sizes are clever. */
+	ENTRY_COMP(select)
+	ENTRY_SAME(flock)
+	ENTRY_SAME(msync)
+	/* struct iovec contains pointers */
+	ENTRY_COMP(readv)		/* 145 */
+	ENTRY_COMP(writev)
+	ENTRY_SAME(getsid)
+	ENTRY_SAME(fdatasync)
+	/* struct __sysctl_args is a mess */
+	ENTRY_COMP(sysctl)
+	ENTRY_SAME(mlock)		/* 150 */
+	ENTRY_SAME(munlock)
+	ENTRY_SAME(mlockall)
+	ENTRY_SAME(munlockall)
+	/* struct sched_param is ok for now */
+	ENTRY_SAME(sched_setparam)
+	ENTRY_SAME(sched_getparam)	/* 155 */
+	ENTRY_SAME(sched_setscheduler)
+	ENTRY_SAME(sched_getscheduler)
+	ENTRY_SAME(sched_yield)
+	ENTRY_SAME(sched_get_priority_max)
+	ENTRY_SAME(sched_get_priority_min)	/* 160 */
+	ENTRY_COMP(sched_rr_get_interval)
+	ENTRY_COMP(nanosleep)
+	ENTRY_SAME(mremap)
+	ENTRY_SAME(setresuid)
+	ENTRY_SAME(getresuid)		/* 165 */
+	ENTRY_COMP(sigaltstack)
+	ENTRY_SAME(ni_syscall)		/* query_module */
+	ENTRY_SAME(poll)
+	/* structs contain pointers and an in_addr... */
+	ENTRY_SAME(ni_syscall)		/* was nfsservctl */
+	ENTRY_SAME(setresgid)		/* 170 */
+	ENTRY_SAME(getresgid)
+	ENTRY_SAME(prctl)
+	/* signals need a careful review */
+	ENTRY_SAME(rt_sigreturn_wrapper)
+	ENTRY_COMP(rt_sigaction)
+	ENTRY_COMP(rt_sigprocmask)	/* 175 */
+	ENTRY_COMP(rt_sigpending)
+	ENTRY_COMP(rt_sigtimedwait)
+	/* even though the struct siginfo_t is different, it appears like
+	 * all the paths use values which should be same wide and narrow.
+	 * Also the struct is padded to 128 bytes which means we don't have
+	 * to worry about faulting trying to copy in a larger 64-bit
+	 * struct from a 32-bit user-space app.
+	 */
+	ENTRY_COMP(rt_sigqueueinfo)
+	ENTRY_COMP(rt_sigsuspend)
+	ENTRY_SAME(chown)		/* 180 */
+	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
+	ENTRY_COMP(setsockopt)
+	ENTRY_COMP(getsockopt)
+	ENTRY_COMP(sendmsg)
+	ENTRY_COMP(recvmsg)
+	ENTRY_SAME(semop)		/* 185 */
+	ENTRY_SAME(semget)
+	ENTRY_COMP(semctl)
+	ENTRY_COMP(msgsnd)
+	ENTRY_COMP(msgrcv)
+	ENTRY_SAME(msgget)		/* 190 */
+	ENTRY_COMP(msgctl)
+	ENTRY_COMP(shmat)
+	ENTRY_SAME(shmdt)
+	ENTRY_SAME(shmget)
+	ENTRY_COMP(shmctl)		/* 195 */
+	ENTRY_SAME(ni_syscall)		/* streams1 */
+	ENTRY_SAME(ni_syscall)		/* streams2 */
+	ENTRY_SAME(lstat64)
+	ENTRY_OURS(truncate64)
+	ENTRY_OURS(ftruncate64)		/* 200 */
+	ENTRY_SAME(getdents64)
+	ENTRY_COMP(fcntl64)
+	ENTRY_SAME(ni_syscall)	/* attrctl -- dead */
+	ENTRY_SAME(ni_syscall)	/* acl_get -- dead */
+	ENTRY_SAME(ni_syscall)		/* 205 (acl_set -- dead) */
+	ENTRY_SAME(gettid)
+	ENTRY_OURS(readahead)
+	ENTRY_SAME(tkill)
+	ENTRY_COMP(sendfile64)
+	ENTRY_COMP(futex)		/* 210 */
+	ENTRY_COMP(sched_setaffinity)
+	ENTRY_COMP(sched_getaffinity)
+	ENTRY_SAME(ni_syscall)	/* set_thread_area */
+	ENTRY_SAME(ni_syscall)	/* get_thread_area */
+	ENTRY_COMP(io_setup)		/* 215 */
+	ENTRY_SAME(io_destroy)
+	ENTRY_COMP(io_getevents)
+	ENTRY_COMP(io_submit)
+	ENTRY_SAME(io_cancel)
+	ENTRY_SAME(ni_syscall)		/* 220: was alloc_hugepages */
+	ENTRY_SAME(ni_syscall)		/* was free_hugepages */
+	ENTRY_SAME(exit_group)
+	ENTRY_COMP(lookup_dcookie)
+	ENTRY_SAME(epoll_create)
+	ENTRY_SAME(epoll_ctl)		/* 225 */
+	ENTRY_SAME(epoll_wait)
+ 	ENTRY_SAME(remap_file_pages)
+	ENTRY_COMP(semtimedop)
+	ENTRY_COMP(mq_open)
+	ENTRY_SAME(mq_unlink)		/* 230 */
+	ENTRY_COMP(mq_timedsend)
+	ENTRY_COMP(mq_timedreceive)
+	ENTRY_COMP(mq_notify)
+	ENTRY_COMP(mq_getsetattr)
+	ENTRY_COMP(waitid)		/* 235 */
+	ENTRY_OURS(fadvise64_64)
+	ENTRY_SAME(set_tid_address)
+	ENTRY_SAME(setxattr)
+	ENTRY_SAME(lsetxattr)
+	ENTRY_SAME(fsetxattr)		/* 240 */
+	ENTRY_SAME(getxattr)
+	ENTRY_SAME(lgetxattr)
+	ENTRY_SAME(fgetxattr)
+	ENTRY_SAME(listxattr)
+	ENTRY_SAME(llistxattr)		/* 245 */
+	ENTRY_SAME(flistxattr)
+	ENTRY_SAME(removexattr)
+	ENTRY_SAME(lremovexattr)
+	ENTRY_SAME(fremovexattr)
+	ENTRY_COMP(timer_create)	/* 250 */
+	ENTRY_COMP(timer_settime)
+	ENTRY_COMP(timer_gettime)
+	ENTRY_SAME(timer_getoverrun)
+	ENTRY_SAME(timer_delete)
+	ENTRY_COMP(clock_settime)	/* 255 */
+	ENTRY_COMP(clock_gettime)
+	ENTRY_COMP(clock_getres)
+	ENTRY_COMP(clock_nanosleep)
+	ENTRY_SAME(tgkill)
+	ENTRY_COMP(mbind)		/* 260 */
+	ENTRY_COMP(get_mempolicy)
+	ENTRY_COMP(set_mempolicy)
+	ENTRY_SAME(ni_syscall)	/* 263: reserved for vserver */
+	ENTRY_SAME(add_key)
+	ENTRY_SAME(request_key)		/* 265 */
+	ENTRY_COMP(keyctl)
+	ENTRY_SAME(ioprio_set)
+	ENTRY_SAME(ioprio_get)
+	ENTRY_SAME(inotify_init)
+	ENTRY_SAME(inotify_add_watch)	/* 270 */
+	ENTRY_SAME(inotify_rm_watch)
+	ENTRY_SAME(migrate_pages)
+	ENTRY_COMP(pselect6)
+	ENTRY_COMP(ppoll)
+	ENTRY_COMP(openat)		/* 275 */
+	ENTRY_SAME(mkdirat)
+	ENTRY_SAME(mknodat)
+	ENTRY_SAME(fchownat)
+	ENTRY_COMP(futimesat)
+	ENTRY_SAME(fstatat64)		/* 280 */
+	ENTRY_SAME(unlinkat)
+	ENTRY_SAME(renameat)
+	ENTRY_SAME(linkat)
+	ENTRY_SAME(symlinkat)
+	ENTRY_SAME(readlinkat)		/* 285 */
+	ENTRY_SAME(fchmodat)
+	ENTRY_SAME(faccessat)
+	ENTRY_SAME(unshare)
+	ENTRY_COMP(set_robust_list)
+	ENTRY_COMP(get_robust_list)	/* 290 */
+	ENTRY_SAME(splice)
+	ENTRY_OURS(sync_file_range)
+	ENTRY_SAME(tee)
+	ENTRY_COMP(vmsplice)
+	ENTRY_COMP(move_pages)		/* 295 */
+	ENTRY_SAME(getcpu)
+	ENTRY_COMP(epoll_pwait)
+	ENTRY_COMP(statfs64)
+	ENTRY_COMP(fstatfs64)
+	ENTRY_COMP(kexec_load)		/* 300 */
+	ENTRY_COMP(utimensat)
+	ENTRY_COMP(signalfd)
+	ENTRY_SAME(ni_syscall)		/* was timerfd */
+	ENTRY_SAME(eventfd)
+	ENTRY_OURS(fallocate)		/* 305 */
+	ENTRY_SAME(timerfd_create)
+	ENTRY_COMP(timerfd_settime)
+	ENTRY_COMP(timerfd_gettime)
+	ENTRY_COMP(signalfd4)
+	ENTRY_SAME(eventfd2)		/* 310 */
+	ENTRY_SAME(epoll_create1)
+	ENTRY_SAME(dup3)
+	ENTRY_SAME(pipe2)
+	ENTRY_SAME(inotify_init1)
+	ENTRY_COMP(preadv)		/* 315 */
+	ENTRY_COMP(pwritev)
+	ENTRY_COMP(rt_tgsigqueueinfo)
+	ENTRY_SAME(perf_event_open)
+	ENTRY_COMP(recvmmsg)
+	ENTRY_SAME(accept4)		/* 320 */
+	ENTRY_SAME(prlimit64)
+	ENTRY_SAME(fanotify_init)
+	ENTRY_DIFF(fanotify_mark)
+	ENTRY_COMP(clock_adjtime)
+	ENTRY_SAME(name_to_handle_at)	/* 325 */
+	ENTRY_COMP(open_by_handle_at)
+	ENTRY_SAME(syncfs)
+	ENTRY_SAME(setns)
+	ENTRY_COMP(sendmmsg)
+	ENTRY_COMP(process_vm_readv)	/* 330 */
+	ENTRY_COMP(process_vm_writev)
+	ENTRY_SAME(kcmp)
+	ENTRY_SAME(finit_module)
+	ENTRY_SAME(sched_setattr)
+	ENTRY_SAME(sched_getattr)	/* 335 */
+	ENTRY_COMP(utimes)
+	ENTRY_SAME(renameat2)
+	ENTRY_SAME(seccomp)
+	ENTRY_SAME(getrandom)
+	ENTRY_SAME(memfd_create)	/* 340 */
+	ENTRY_SAME(bpf)
+	ENTRY_COMP(execveat)
+	ENTRY_SAME(membarrier)
+	ENTRY_SAME(userfaultfd)
+	ENTRY_SAME(mlock2)		/* 345 */
+	ENTRY_SAME(copy_file_range)
+	ENTRY_COMP(preadv2)
+	ENTRY_COMP(pwritev2)
+	ENTRY_SAME(statx)
+	ENTRY_COMP(io_pgetevents)	/* 350 */
+
+
+.ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))
+.error "size of syscall table does not fit value of __NR_Linux_syscalls"
+.endif
+
+#undef ENTRY_SAME
+#undef ENTRY_DIFF
+#undef ENTRY_UHOH
+#undef ENTRY_COMP
+#undef ENTRY_OURS
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
new file mode 100644
index 0000000..a1e772f
--- /dev/null
+++ b/arch/parisc/kernel/time.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  linux/arch/parisc/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
+ *  Copyright (C) 1999 SuSE GmbH, (Philipp Rumpf, prumpf@tux.org)
+ *
+ * 1994-07-02  Alan Modra
+ *             fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ * 1998-12-20  Updated NTP code according to technical memorandum Jan '96
+ *             "A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/sched/clock.h>
+#include <linux/sched_clock.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/profile.h>
+#include <linux/clocksource.h>
+#include <linux/platform_device.h>
+#include <linux/ftrace.h>
+
+#include <linux/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/param.h>
+#include <asm/pdc.h>
+#include <asm/led.h>
+
+#include <linux/timex.h>
+
+static unsigned long clocktick __read_mostly;	/* timer cycles per tick */
+
+/*
+ * We keep time on PA-RISC Linux by using the Interval Timer which is
+ * a pair of registers; one is read-only and one is write-only; both
+ * accessed through CR16.  The read-only register is 32 or 64 bits wide,
+ * and increments by 1 every CPU clock tick.  The architecture only
+ * guarantees us a rate between 0.5 and 2, but all implementations use a
+ * rate of 1.  The write-only register is 32-bits wide.  When the lowest
+ * 32 bits of the read-only register compare equal to the write-only
+ * register, it raises a maskable external interrupt.  Each processor has
+ * an Interval Timer of its own and they are not synchronised.  
+ *
+ * We want to generate an interrupt every 1/HZ seconds.  So we program
+ * CR16 to interrupt every @clocktick cycles.  The it_value in cpu_data
+ * is programmed with the intended time of the next tick.  We can be
+ * held off for an arbitrarily long period of time by interrupts being
+ * disabled, so we may miss one or more ticks.
+ */
+irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
+{
+	unsigned long now;
+	unsigned long next_tick;
+	unsigned long ticks_elapsed = 0;
+	unsigned int cpu = smp_processor_id();
+	struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+
+	/* gcc can optimize for "read-only" case with a local clocktick */
+	unsigned long cpt = clocktick;
+
+	profile_tick(CPU_PROFILING);
+
+	/* Initialize next_tick to the old expected tick time. */
+	next_tick = cpuinfo->it_value;
+
+	/* Calculate how many ticks have elapsed. */
+	now = mfctl(16);
+	do {
+		++ticks_elapsed;
+		next_tick += cpt;
+	} while (next_tick - now > cpt);
+
+	/* Store (in CR16 cycles) up to when we are accounting right now. */
+	cpuinfo->it_value = next_tick;
+
+	/* Go do system house keeping. */
+	if (cpu == 0)
+		xtime_update(ticks_elapsed);
+
+	update_process_times(user_mode(get_irq_regs()));
+
+	/* Skip clockticks on purpose if we know we would miss those.
+	 * The new CR16 must be "later" than current CR16 otherwise
+	 * itimer would not fire until CR16 wrapped - e.g 4 seconds
+	 * later on a 1Ghz processor. We'll account for the missed
+	 * ticks on the next timer interrupt.
+	 * We want IT to fire modulo clocktick even if we miss/skip some.
+	 * But those interrupts don't in fact get delivered that regularly.
+	 *
+	 * "next_tick - now" will always give the difference regardless
+	 * if one or the other wrapped. If "now" is "bigger" we'll end up
+	 * with a very large unsigned number.
+	 */
+	now = mfctl(16);
+	while (next_tick - now > cpt)
+		next_tick += cpt;
+
+	/* Program the IT when to deliver the next interrupt.
+	 * Only bottom 32-bits of next_tick are writable in CR16!
+	 * Timer interrupt will be delivered at least a few hundred cycles
+	 * after the IT fires, so if we are too close (<= 8000 cycles) to the
+	 * next cycle, simply skip it.
+	 */
+	if (next_tick - now <= 8000)
+		next_tick += cpt;
+	mtctl(next_tick, 16);
+
+	return IRQ_HANDLED;
+}
+
+
+unsigned long profile_pc(struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+
+	if (regs->gr[0] & PSW_N)
+		pc -= 4;
+
+#ifdef CONFIG_SMP
+	if (in_lock_functions(pc))
+		pc = regs->gr[2];
+#endif
+
+	return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+
+/* clock source code */
+
+static u64 notrace read_cr16(struct clocksource *cs)
+{
+	return get_cycles();
+}
+
+static struct clocksource clocksource_cr16 = {
+	.name			= "cr16",
+	.rating			= 300,
+	.read			= read_cr16,
+	.mask			= CLOCKSOURCE_MASK(BITS_PER_LONG),
+	.flags			= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init start_cpu_itimer(void)
+{
+	unsigned int cpu = smp_processor_id();
+	unsigned long next_tick = mfctl(16) + clocktick;
+
+	mtctl(next_tick, 16);		/* kick off Interval Timer (CR16) */
+
+	per_cpu(cpu_data, cpu).it_value = next_tick;
+}
+
+#if IS_ENABLED(CONFIG_RTC_DRV_GENERIC)
+static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+	struct pdc_tod tod_data;
+
+	memset(tm, 0, sizeof(*tm));
+	if (pdc_tod_read(&tod_data) < 0)
+		return -EOPNOTSUPP;
+
+	/* we treat tod_sec as unsigned, so this can work until year 2106 */
+	rtc_time64_to_tm(tod_data.tod_sec, tm);
+	return 0;
+}
+
+static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+	time64_t secs = rtc_tm_to_time64(tm);
+
+	if (pdc_tod_set(secs, 0) < 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static const struct rtc_class_ops rtc_generic_ops = {
+	.read_time = rtc_generic_get_time,
+	.set_time = rtc_generic_set_time,
+};
+
+static int __init rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(NULL, "rtc-generic", -1,
+					     &rtc_generic_ops,
+					     sizeof(rtc_generic_ops));
+
+	return PTR_ERR_OR_ZERO(pdev);
+}
+device_initcall(rtc_init);
+#endif
+
+void read_persistent_clock64(struct timespec64 *ts)
+{
+	static struct pdc_tod tod_data;
+	if (pdc_tod_read(&tod_data) == 0) {
+		ts->tv_sec = tod_data.tod_sec;
+		ts->tv_nsec = tod_data.tod_usec * 1000;
+	} else {
+		printk(KERN_ERR "Error reading tod clock\n");
+	        ts->tv_sec = 0;
+		ts->tv_nsec = 0;
+	}
+}
+
+
+static u64 notrace read_cr16_sched_clock(void)
+{
+	return get_cycles();
+}
+
+
+/*
+ * timer interrupt and sched_clock() initialization
+ */
+
+void __init time_init(void)
+{
+	unsigned long cr16_hz;
+
+	clocktick = (100 * PAGE0->mem_10msec) / HZ;
+	start_cpu_itimer();	/* get CPU 0 started */
+
+	cr16_hz = 100 * PAGE0->mem_10msec;  /* Hz */
+
+	/* register as sched_clock source */
+	sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz);
+}
+
+static int __init init_cr16_clocksource(void)
+{
+	/*
+	 * The cr16 interval timers are not syncronized across CPUs on
+	 * different sockets, so mark them unstable and lower rating on
+	 * multi-socket SMP systems.
+	 */
+	if (num_online_cpus() > 1 && !running_on_qemu) {
+		int cpu;
+		unsigned long cpu0_loc;
+		cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
+
+		for_each_online_cpu(cpu) {
+			if (cpu == 0)
+				continue;
+			if ((cpu0_loc != 0) &&
+			    (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
+				continue;
+
+			clocksource_cr16.name = "cr16_unstable";
+			clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
+			clocksource_cr16.rating = 0;
+			break;
+		}
+	}
+
+	/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
+	 *	in sync:
+	 *	(clocksource_cr16.flags == CLOCK_SOURCE_IS_CONTINUOUS) */
+
+	/* register at clocksource framework */
+	clocksource_register_hz(&clocksource_cr16,
+		100 * PAGE0->mem_10msec);
+
+	return 0;
+}
+
+device_initcall(init_cr16_clocksource);
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
new file mode 100644
index 0000000..0a10e4d
--- /dev/null
+++ b/arch/parisc/kernel/topology.c
@@ -0,0 +1,142 @@
+/*
+ * arch/parisc/kernel/topology.c
+ *
+ * Copyright (C) 2017 Helge Deller <deller@gmx.de>
+ *
+ * based on arch/arm/kernel/topology.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/sched/topology.h>
+
+#include <asm/topology.h>
+
+ /*
+  * cpu topology table
+  */
+struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+	return &cpu_topology[cpu].core_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+	struct cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+	int cpu;
+
+	/* update core and thread sibling masks */
+	for_each_possible_cpu(cpu) {
+		cpu_topo = &cpu_topology[cpu];
+
+		if (cpuid_topo->socket_id != cpu_topo->socket_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+		if (cpuid_topo->core_id != cpu_topo->core_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+	}
+	smp_wmb();
+}
+
+static int dualcores_found __initdata;
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void __init store_cpu_topology(unsigned int cpuid)
+{
+	struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid];
+	struct cpuinfo_parisc *p;
+	int max_socket = -1;
+	unsigned long cpu;
+
+	/* If the cpu topology has been already set, just return */
+	if (cpuid_topo->core_id != -1)
+		return;
+
+	/* create cpu topology mapping */
+	cpuid_topo->thread_id = -1;
+	cpuid_topo->core_id = 0;
+
+	p = &per_cpu(cpu_data, cpuid);
+	for_each_online_cpu(cpu) {
+		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+
+		if (cpu == cpuid) /* ignore current cpu */
+			continue;
+
+		if (cpuinfo->cpu_loc == p->cpu_loc) {
+			cpuid_topo->core_id = cpu_topology[cpu].core_id;
+			if (p->cpu_loc) {
+				cpuid_topo->core_id++;
+				cpuid_topo->socket_id = cpu_topology[cpu].socket_id;
+				dualcores_found = 1;
+				continue;
+			}
+		}
+
+		if (cpuid_topo->socket_id == -1)
+			max_socket = max(max_socket, cpu_topology[cpu].socket_id);
+	}
+
+	if (cpuid_topo->socket_id == -1)
+		cpuid_topo->socket_id = max_socket + 1;
+
+	update_siblings_masks(cpuid);
+
+	pr_info("CPU%u: thread %d, cpu %d, socket %d\n",
+		cpuid, cpu_topology[cpuid].thread_id,
+		cpu_topology[cpuid].core_id,
+		cpu_topology[cpuid].socket_id);
+}
+
+static struct sched_domain_topology_level parisc_mc_topology[] = {
+#ifdef CONFIG_SCHED_MC
+	{ cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+#endif
+
+	{ cpu_cpu_mask, SD_INIT_NAME(DIE) },
+	{ NULL, },
+};
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+	unsigned int cpu;
+
+	/* init core mask and capacity */
+	for_each_possible_cpu(cpu) {
+		struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]);
+
+		cpu_topo->thread_id = -1;
+		cpu_topo->core_id =  -1;
+		cpu_topo->socket_id = -1;
+		cpumask_clear(&cpu_topo->core_sibling);
+		cpumask_clear(&cpu_topo->thread_sibling);
+	}
+	smp_wmb();
+
+	/* Set scheduler topology descriptor */
+	if (dualcores_found)
+		set_sched_topology(parisc_mc_topology);
+}
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
new file mode 100644
index 0000000..abeb532
--- /dev/null
+++ b/arch/parisc/kernel/traps.c
@@ -0,0 +1,838 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  linux/arch/parisc/traps.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1999, 2000  Philipp Rumpf <prumpf@tux.org>
+ */
+
+/*
+ * 'Traps.c' handles hardware traps and faults after we have saved some
+ * state in 'asm.s'.
+ */
+
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <linux/bug.h>
+#include <linux/ratelimit.h>
+#include <linux/uaccess.h>
+
+#include <asm/assembly.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/unaligned.h>
+#include <linux/atomic.h>
+#include <asm/smp.h>
+#include <asm/pdc.h>
+#include <asm/pdc_chassis.h>
+#include <asm/unwind.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+#include "../math-emu/math-emu.h"	/* for handle_fpe() */
+
+static void parisc_show_stack(struct task_struct *task,
+	struct pt_regs *regs);
+
+static int printbinary(char *buf, unsigned long x, int nbits)
+{
+	unsigned long mask = 1UL << (nbits - 1);
+	while (mask != 0) {
+		*buf++ = (mask & x ? '1' : '0');
+		mask >>= 1;
+	}
+	*buf = '\0';
+
+	return nbits;
+}
+
+#ifdef CONFIG_64BIT
+#define RFMT "%016lx"
+#else
+#define RFMT "%08lx"
+#endif
+#define FFMT "%016llx"	/* fpregs are 64-bit always */
+
+#define PRINTREGS(lvl,r,f,fmt,x)	\
+	printk("%s%s%02d-%02d  " fmt " " fmt " " fmt " " fmt "\n",	\
+		lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1],		\
+		(r)[(x)+2], (r)[(x)+3])
+
+static void print_gr(char *level, struct pt_regs *regs)
+{
+	int i;
+	char buf[64];
+
+	printk("%s\n", level);
+	printk("%s     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
+	printbinary(buf, regs->gr[0], 32);
+	printk("%sPSW: %s %s\n", level, buf, print_tainted());
+
+	for (i = 0; i < 32; i += 4)
+		PRINTREGS(level, regs->gr, "r", RFMT, i);
+}
+
+static void print_fr(char *level, struct pt_regs *regs)
+{
+	int i;
+	char buf[64];
+	struct { u32 sw[2]; } s;
+
+	/* FR are 64bit everywhere. Need to use asm to get the content
+	 * of fpsr/fper1, and we assume that we won't have a FP Identify
+	 * in our way, otherwise we're screwed.
+	 * The fldd is used to restore the T-bit if there was one, as the
+	 * store clears it anyway.
+	 * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */
+	asm volatile ("fstd %%fr0,0(%1)	\n\t"
+		      "fldd 0(%1),%%fr0	\n\t"
+		      : "=m" (s) : "r" (&s) : "r0");
+
+	printk("%s\n", level);
+	printk("%s      VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
+	printbinary(buf, s.sw[0], 32);
+	printk("%sFPSR: %s\n", level, buf);
+	printk("%sFPER1: %08x\n", level, s.sw[1]);
+
+	/* here we'll print fr0 again, tho it'll be meaningless */
+	for (i = 0; i < 32; i += 4)
+		PRINTREGS(level, regs->fr, "fr", FFMT, i);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	int i, user;
+	char *level;
+	unsigned long cr30, cr31;
+
+	user = user_mode(regs);
+	level = user ? KERN_DEBUG : KERN_CRIT;
+
+	show_regs_print_info(level);
+
+	print_gr(level, regs);
+
+	for (i = 0; i < 8; i += 4)
+		PRINTREGS(level, regs->sr, "sr", RFMT, i);
+
+	if (user)
+		print_fr(level, regs);
+
+	cr30 = mfctl(30);
+	cr31 = mfctl(31);
+	printk("%s\n", level);
+	printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n",
+	       level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]);
+	printk("%s IIR: %08lx    ISR: " RFMT "  IOR: " RFMT "\n",
+	       level, regs->iir, regs->isr, regs->ior);
+	printk("%s CPU: %8d   CR30: " RFMT " CR31: " RFMT "\n",
+	       level, current_thread_info()->cpu, cr30, cr31);
+	printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
+
+	if (user) {
+		printk("%s IAOQ[0]: " RFMT "\n", level, regs->iaoq[0]);
+		printk("%s IAOQ[1]: " RFMT "\n", level, regs->iaoq[1]);
+		printk("%s RP(r2): " RFMT "\n", level, regs->gr[2]);
+	} else {
+		printk("%s IAOQ[0]: %pS\n", level, (void *) regs->iaoq[0]);
+		printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
+		printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
+
+		parisc_show_stack(current, regs);
+	}
+}
+
+static DEFINE_RATELIMIT_STATE(_hppa_rs,
+	DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
+
+#define parisc_printk_ratelimited(critical, regs, fmt, ...)	{	      \
+	if ((critical || show_unhandled_signals) && __ratelimit(&_hppa_rs)) { \
+		printk(fmt, ##__VA_ARGS__);				      \
+		show_regs(regs);					      \
+	}								      \
+}
+
+
+static void do_show_stack(struct unwind_frame_info *info)
+{
+	int i = 1;
+
+	printk(KERN_CRIT "Backtrace:\n");
+	while (i <= MAX_UNWIND_ENTRIES) {
+		if (unwind_once(info) < 0 || info->ip == 0)
+			break;
+
+		if (__kernel_text_address(info->ip)) {
+			printk(KERN_CRIT " [<" RFMT ">] %pS\n",
+				info->ip, (void *) info->ip);
+			i++;
+		}
+	}
+	printk(KERN_CRIT "\n");
+}
+
+static void parisc_show_stack(struct task_struct *task,
+	struct pt_regs *regs)
+{
+	struct unwind_frame_info info;
+
+	unwind_frame_init_task(&info, task, regs);
+
+	do_show_stack(&info);
+}
+
+void show_stack(struct task_struct *t, unsigned long *sp)
+{
+	parisc_show_stack(t, NULL);
+}
+
+int is_valid_bugaddr(unsigned long iaoq)
+{
+	return 1;
+}
+
+void die_if_kernel(char *str, struct pt_regs *regs, long err)
+{
+	if (user_mode(regs)) {
+		if (err == 0)
+			return; /* STFU */
+
+		parisc_printk_ratelimited(1, regs,
+			KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
+			current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
+
+		return;
+	}
+
+	oops_in_progress = 1;
+
+	oops_enter();
+
+	/* Amuse the user in a SPARC fashion */
+	if (err) printk(KERN_CRIT
+			"      _______________________________ \n"
+			"     < Your System ate a SPARC! Gah! >\n"
+			"      ------------------------------- \n"
+			"             \\   ^__^\n"
+			"                 (__)\\       )\\/\\\n"
+			"                  U  ||----w |\n"
+			"                     ||     ||\n");
+	
+	/* unlock the pdc lock if necessary */
+	pdc_emergency_unlock();
+
+	/* maybe the kernel hasn't booted very far yet and hasn't been able 
+	 * to initialize the serial or STI console. In that case we should 
+	 * re-enable the pdc console, so that the user will be able to 
+	 * identify the problem. */
+	if (!console_drivers)
+		pdc_console_restart();
+	
+	if (err)
+		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
+			current->comm, task_pid_nr(current), str, err);
+
+	/* Wot's wrong wif bein' racy? */
+	if (current->thread.flags & PARISC_KERNEL_DEATH) {
+		printk(KERN_CRIT "%s() recursion detected.\n", __func__);
+		local_irq_enable();
+		while (1);
+	}
+	current->thread.flags |= PARISC_KERNEL_DEATH;
+
+	show_regs(regs);
+	dump_stack();
+	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
+
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops)
+		panic("Fatal exception");
+
+	oops_exit();
+	do_exit(SIGSEGV);
+}
+
+/* gdb uses break 4,8 */
+#define GDB_BREAK_INSN 0x10004
+static void handle_gdb_break(struct pt_regs *regs, int wot)
+{
+	force_sig_fault(SIGTRAP, wot,
+			(void __user *) (regs->iaoq[0] & ~3), current);
+}
+
+static void handle_break(struct pt_regs *regs)
+{
+	unsigned iir = regs->iir;
+
+	if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) {
+		/* check if a BUG() or WARN() trapped here.  */
+		enum bug_trap_type tt;
+		tt = report_bug(regs->iaoq[0] & ~3, regs);
+		if (tt == BUG_TRAP_TYPE_WARN) {
+			regs->iaoq[0] += 4;
+			regs->iaoq[1] += 4;
+			return; /* return to next instruction when WARN_ON().  */
+		}
+		die_if_kernel("Unknown kernel breakpoint", regs,
+			(tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
+	}
+
+	if (unlikely(iir != GDB_BREAK_INSN))
+		parisc_printk_ratelimited(0, regs,
+			KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
+			iir & 31, (iir>>13) & ((1<<13)-1),
+			task_pid_nr(current), current->comm);
+
+	/* send standard GDB signal */
+	handle_gdb_break(regs, TRAP_BRKPT);
+}
+
+static void default_trap(int code, struct pt_regs *regs)
+{
+	printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());
+	show_regs(regs);
+}
+
+void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap;
+
+
+void transfer_pim_to_trap_frame(struct pt_regs *regs)
+{
+    register int i;
+    extern unsigned int hpmc_pim_data[];
+    struct pdc_hpmc_pim_11 *pim_narrow;
+    struct pdc_hpmc_pim_20 *pim_wide;
+
+    if (boot_cpu_data.cpu_type >= pcxu) {
+
+	pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
+
+	/*
+	 * Note: The following code will probably generate a
+	 * bunch of truncation error warnings from the compiler.
+	 * Could be handled with an ifdef, but perhaps there
+	 * is a better way.
+	 */
+
+	regs->gr[0] = pim_wide->cr[22];
+
+	for (i = 1; i < 32; i++)
+	    regs->gr[i] = pim_wide->gr[i];
+
+	for (i = 0; i < 32; i++)
+	    regs->fr[i] = pim_wide->fr[i];
+
+	for (i = 0; i < 8; i++)
+	    regs->sr[i] = pim_wide->sr[i];
+
+	regs->iasq[0] = pim_wide->cr[17];
+	regs->iasq[1] = pim_wide->iasq_back;
+	regs->iaoq[0] = pim_wide->cr[18];
+	regs->iaoq[1] = pim_wide->iaoq_back;
+
+	regs->sar  = pim_wide->cr[11];
+	regs->iir  = pim_wide->cr[19];
+	regs->isr  = pim_wide->cr[20];
+	regs->ior  = pim_wide->cr[21];
+    }
+    else {
+	pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
+
+	regs->gr[0] = pim_narrow->cr[22];
+
+	for (i = 1; i < 32; i++)
+	    regs->gr[i] = pim_narrow->gr[i];
+
+	for (i = 0; i < 32; i++)
+	    regs->fr[i] = pim_narrow->fr[i];
+
+	for (i = 0; i < 8; i++)
+	    regs->sr[i] = pim_narrow->sr[i];
+
+	regs->iasq[0] = pim_narrow->cr[17];
+	regs->iasq[1] = pim_narrow->iasq_back;
+	regs->iaoq[0] = pim_narrow->cr[18];
+	regs->iaoq[1] = pim_narrow->iaoq_back;
+
+	regs->sar  = pim_narrow->cr[11];
+	regs->iir  = pim_narrow->cr[19];
+	regs->isr  = pim_narrow->cr[20];
+	regs->ior  = pim_narrow->cr[21];
+    }
+
+    /*
+     * The following fields only have meaning if we came through
+     * another path. So just zero them here.
+     */
+
+    regs->ksp = 0;
+    regs->kpc = 0;
+    regs->orig_r28 = 0;
+}
+
+
+/*
+ * This routine is called as a last resort when everything else
+ * has gone clearly wrong. We get called for faults in kernel space,
+ * and HPMC's.
+ */
+void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
+{
+	static DEFINE_SPINLOCK(terminate_lock);
+
+	oops_in_progress = 1;
+
+	set_eiem(0);
+	local_irq_disable();
+	spin_lock(&terminate_lock);
+
+	/* unlock the pdc lock if necessary */
+	pdc_emergency_unlock();
+
+	/* restart pdc console if necessary */
+	if (!console_drivers)
+		pdc_console_restart();
+
+	/* Not all paths will gutter the processor... */
+	switch(code){
+
+	case 1:
+		transfer_pim_to_trap_frame(regs);
+		break;
+
+	default:
+		/* Fall through */
+		break;
+
+	}
+	    
+	{
+		/* show_stack(NULL, (unsigned long *)regs->gr[30]); */
+		struct unwind_frame_info info;
+		unwind_frame_init(&info, current, regs);
+		do_show_stack(&info);
+	}
+
+	printk("\n");
+	pr_crit("%s: Code=%d (%s) regs=%p (Addr=" RFMT ")\n",
+		msg, code, trap_name(code), regs, offset);
+	show_regs(regs);
+
+	spin_unlock(&terminate_lock);
+
+	/* put soft power button back under hardware control;
+	 * if the user had pressed it once at any time, the 
+	 * system will shut down immediately right here. */
+	pdc_soft_power_button(0);
+	
+	/* Call kernel panic() so reboot timeouts work properly 
+	 * FIXME: This function should be on the list of
+	 * panic notifiers, and we should call panic
+	 * directly from the location that we wish. 
+	 * e.g. We should not call panic from
+	 * parisc_terminate, but rather the oter way around.
+	 * This hack works, prints the panic message twice,
+	 * and it enables reboot timers!
+	 */
+	panic(msg);
+}
+
+void notrace handle_interruption(int code, struct pt_regs *regs)
+{
+	unsigned long fault_address = 0;
+	unsigned long fault_space = 0;
+	int si_code;
+
+	if (code == 1)
+	    pdc_console_restart();  /* switch back to pdc if HPMC */
+	else
+	    local_irq_enable();
+
+	/* Security check:
+	 * If the priority level is still user, and the
+	 * faulting space is not equal to the active space
+	 * then the user is attempting something in a space
+	 * that does not belong to them. Kill the process.
+	 *
+	 * This is normally the situation when the user
+	 * attempts to jump into the kernel space at the
+	 * wrong offset, be it at the gateway page or a
+	 * random location.
+	 *
+	 * We cannot normally signal the process because it
+	 * could *be* on the gateway page, and processes
+	 * executing on the gateway page can't have signals
+	 * delivered.
+	 * 
+	 * We merely readjust the address into the users
+	 * space, at a destination address of zero, and
+	 * allow processing to continue.
+	 */
+	if (((unsigned long)regs->iaoq[0] & 3) &&
+	    ((unsigned long)regs->iasq[0] != (unsigned long)regs->sr[7])) { 
+		/* Kill the user process later */
+		regs->iaoq[0] = 0 | 3;
+		regs->iaoq[1] = regs->iaoq[0] + 4;
+		regs->iasq[0] = regs->iasq[1] = regs->sr[7];
+		regs->gr[0] &= ~PSW_B;
+		return;
+	}
+	
+#if 0
+	printk(KERN_CRIT "Interruption # %d\n", code);
+#endif
+
+	switch(code) {
+
+	case  1:
+		/* High-priority machine check (HPMC) */
+		
+		/* set up a new led state on systems shipped with a LED State panel */
+		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
+
+		parisc_terminate("High Priority Machine Check (HPMC)",
+				regs, code, 0);
+		/* NOT REACHED */
+		
+	case  2:
+		/* Power failure interrupt */
+		printk(KERN_CRIT "Power failure interrupt !\n");
+		return;
+
+	case  3:
+		/* Recovery counter trap */
+		regs->gr[0] &= ~PSW_R;
+		if (user_space(regs))
+			handle_gdb_break(regs, TRAP_TRACE);
+		/* else this must be the start of a syscall - just let it run */
+		return;
+
+	case  5:
+		/* Low-priority machine check */
+		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
+		
+		flush_cache_all();
+		flush_tlb_all();
+		cpu_lpmc(5, regs);
+		return;
+
+	case  PARISC_ITLB_TRAP:
+		/* Instruction TLB miss fault/Instruction page fault */
+		fault_address = regs->iaoq[0];
+		fault_space   = regs->iasq[0];
+		break;
+
+	case  8:
+		/* Illegal instruction trap */
+		die_if_kernel("Illegal instruction", regs, code);
+		si_code = ILL_ILLOPC;
+		goto give_sigill;
+
+	case  9:
+		/* Break instruction trap */
+		handle_break(regs);
+		return;
+
+	case 10:
+		/* Privileged operation trap */
+		die_if_kernel("Privileged operation", regs, code);
+		si_code = ILL_PRVOPC;
+		goto give_sigill;
+
+	case 11:
+		/* Privileged register trap */
+		if ((regs->iir & 0xffdfffe0) == 0x034008a0) {
+
+			/* This is a MFCTL cr26/cr27 to gr instruction.
+			 * PCXS traps on this, so we need to emulate it.
+			 */
+
+			if (regs->iir & 0x00200000)
+				regs->gr[regs->iir & 0x1f] = mfctl(27);
+			else
+				regs->gr[regs->iir & 0x1f] = mfctl(26);
+
+			regs->iaoq[0] = regs->iaoq[1];
+			regs->iaoq[1] += 4;
+			regs->iasq[0] = regs->iasq[1];
+			return;
+		}
+
+		die_if_kernel("Privileged register usage", regs, code);
+		si_code = ILL_PRVREG;
+	give_sigill:
+		force_sig_fault(SIGILL, si_code,
+				(void __user *) regs->iaoq[0], current);
+		return;
+
+	case 12:
+		/* Overflow Trap, let the userland signal handler do the cleanup */
+		force_sig_fault(SIGFPE, FPE_INTOVF,
+				(void __user *) regs->iaoq[0], current);
+		return;
+		
+	case 13:
+		/* Conditional Trap
+		   The condition succeeds in an instruction which traps
+		   on condition  */
+		if(user_mode(regs)){
+			/* Let userspace app figure it out from the insn pointed
+			 * to by si_addr.
+			 */
+			force_sig_fault(SIGFPE, FPE_CONDTRAP,
+					(void __user *) regs->iaoq[0], current);
+			return;
+		} 
+		/* The kernel doesn't want to handle condition codes */
+		break;
+		
+	case 14:
+		/* Assist Exception Trap, i.e. floating point exception. */
+		die_if_kernel("Floating point exception", regs, 0); /* quiet */
+		__inc_irq_stat(irq_fpassist_count);
+		handle_fpe(regs);
+		return;
+
+	case 15:
+		/* Data TLB miss fault/Data page fault */
+		/* Fall through */
+	case 16:
+		/* Non-access instruction TLB miss fault */
+		/* The instruction TLB entry needed for the target address of the FIC
+		   is absent, and hardware can't find it, so we get to cleanup */
+		/* Fall through */
+	case 17:
+		/* Non-access data TLB miss fault/Non-access data page fault */
+		/* FIXME: 
+			 Still need to add slow path emulation code here!
+			 If the insn used a non-shadow register, then the tlb
+			 handlers could not have their side-effect (e.g. probe
+			 writing to a target register) emulated since rfir would
+			 erase the changes to said register. Instead we have to
+			 setup everything, call this function we are in, and emulate
+			 by hand. Technically we need to emulate:
+			 fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw
+		*/
+		fault_address = regs->ior;
+		fault_space = regs->isr;
+		break;
+
+	case 18:
+		/* PCXS only -- later cpu's split this into types 26,27 & 28 */
+		/* Check for unaligned access */
+		if (check_unaligned(regs)) {
+			handle_unaligned(regs);
+			return;
+		}
+		/* Fall Through */
+	case 26: 
+		/* PCXL: Data memory access rights trap */
+		fault_address = regs->ior;
+		fault_space   = regs->isr;
+		break;
+
+	case 19:
+		/* Data memory break trap */
+		regs->gr[0] |= PSW_X; /* So we can single-step over the trap */
+		/* fall thru */
+	case 21:
+		/* Page reference trap */
+		handle_gdb_break(regs, TRAP_HWBKPT);
+		return;
+
+	case 25:
+		/* Taken branch trap */
+		regs->gr[0] &= ~PSW_T;
+		if (user_space(regs))
+			handle_gdb_break(regs, TRAP_BRANCH);
+		/* else this must be the start of a syscall - just let it
+		 * run.
+		 */
+		return;
+
+	case  7:  
+		/* Instruction access rights */
+		/* PCXL: Instruction memory protection trap */
+
+		/*
+		 * This could be caused by either: 1) a process attempting
+		 * to execute within a vma that does not have execute
+		 * permission, or 2) an access rights violation caused by a
+		 * flush only translation set up by ptep_get_and_clear().
+		 * So we check the vma permissions to differentiate the two.
+		 * If the vma indicates we have execute permission, then
+		 * the cause is the latter one. In this case, we need to
+		 * call do_page_fault() to fix the problem.
+		 */
+
+		if (user_mode(regs)) {
+			struct vm_area_struct *vma;
+
+			down_read(&current->mm->mmap_sem);
+			vma = find_vma(current->mm,regs->iaoq[0]);
+			if (vma && (regs->iaoq[0] >= vma->vm_start)
+				&& (vma->vm_flags & VM_EXEC)) {
+
+				fault_address = regs->iaoq[0];
+				fault_space = regs->iasq[0];
+
+				up_read(&current->mm->mmap_sem);
+				break; /* call do_page_fault() */
+			}
+			up_read(&current->mm->mmap_sem);
+		}
+		/* Fall Through */
+	case 27: 
+		/* Data memory protection ID trap */
+		if (code == 27 && !user_mode(regs) &&
+			fixup_exception(regs))
+			return;
+
+		die_if_kernel("Protection id trap", regs, code);
+		force_sig_fault(SIGSEGV, SEGV_MAPERR,
+				(code == 7)?
+				((void __user *) regs->iaoq[0]) :
+				((void __user *) regs->ior), current);
+		return;
+
+	case 28: 
+		/* Unaligned data reference trap */
+		handle_unaligned(regs);
+		return;
+
+	default:
+		if (user_mode(regs)) {
+			parisc_printk_ratelimited(0, regs, KERN_DEBUG
+				"handle_interruption() pid=%d command='%s'\n",
+				task_pid_nr(current), current->comm);
+			/* SIGBUS, for lack of a better one. */
+			force_sig_fault(SIGBUS, BUS_OBJERR,
+					(void __user *)regs->ior, current);
+			return;
+		}
+		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+		
+		parisc_terminate("Unexpected interruption", regs, code, 0);
+		/* NOT REACHED */
+	}
+
+	if (user_mode(regs)) {
+	    if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
+		parisc_printk_ratelimited(0, regs, KERN_DEBUG
+				"User fault %d on space 0x%08lx, pid=%d command='%s'\n",
+				code, fault_space,
+				task_pid_nr(current), current->comm);
+		force_sig_fault(SIGSEGV, SEGV_MAPERR,
+				(void __user *)regs->ior, current);
+		return;
+	    }
+	}
+	else {
+
+	    /*
+	     * The kernel should never fault on its own address space,
+	     * unless pagefault_disable() was called before.
+	     */
+
+	    if (fault_space == 0 && !faulthandler_disabled())
+	    {
+		/* Clean up and return if in exception table. */
+		if (fixup_exception(regs))
+			return;
+		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
+		parisc_terminate("Kernel Fault", regs, code, fault_address);
+	    }
+	}
+
+	do_page_fault(regs, code, fault_address);
+}
+
+
+void __init initialize_ivt(const void *iva)
+{
+	extern u32 os_hpmc_size;
+	extern const u32 os_hpmc[];
+
+	int i;
+	u32 check = 0;
+	u32 *ivap;
+	u32 *hpmcp;
+	u32 length, instr;
+
+	if (strcmp((const char *)iva, "cows can fly"))
+		panic("IVT invalid");
+
+	ivap = (u32 *)iva;
+
+	for (i = 0; i < 8; i++)
+	    *ivap++ = 0;
+
+	/*
+	 * Use PDC_INSTR firmware function to get instruction that invokes
+	 * PDCE_CHECK in HPMC handler.  See programming note at page 1-31 of
+	 * the PA 1.1 Firmware Architecture document.
+	 */
+	if (pdc_instr(&instr) == PDC_OK)
+		ivap[0] = instr;
+
+	/*
+	 * Rules for the checksum of the HPMC handler:
+	 * 1. The IVA does not point to PDC/PDH space (ie: the OS has installed
+	 *    its own IVA).
+	 * 2. The word at IVA + 32 is nonzero.
+	 * 3. If Length (IVA + 60) is not zero, then Length (IVA + 60) and
+	 *    Address (IVA + 56) are word-aligned.
+	 * 4. The checksum of the 8 words starting at IVA + 32 plus the sum of
+	 *    the Length/4 words starting at Address is zero.
+	 */
+
+	/* Setup IVA and compute checksum for HPMC handler */
+	ivap[6] = (u32)__pa(os_hpmc);
+	length = os_hpmc_size;
+	ivap[7] = length;
+
+	hpmcp = (u32 *)os_hpmc;
+
+	for (i=0; i<length/4; i++)
+	    check += *hpmcp++;
+
+	for (i=0; i<8; i++)
+	    check += ivap[i];
+
+	ivap[5] = -check;
+}
+	
+
+/* early_trap_init() is called before we set up kernel mappings and
+ * write-protect the kernel */
+void  __init early_trap_init(void)
+{
+	extern const void fault_vector_20;
+
+#ifndef CONFIG_64BIT
+	extern const void fault_vector_11;
+	initialize_ivt(&fault_vector_11);
+#endif
+
+	initialize_ivt(&fault_vector_20);
+}
+
+void __init trap_init(void)
+{
+}
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
new file mode 100644
index 0000000..932bfc0
--- /dev/null
+++ b/arch/parisc/kernel/unaligned.c
@@ -0,0 +1,758 @@
+/*
+ *    Unaligned memory access handler
+ *
+ *    Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ *    Significantly tweaked by LaMont Jones <lamont@debian.org>
+ *
+ *    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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched/signal.h>
+#include <linux/sched/debug.h>
+#include <linux/signal.h>
+#include <linux/ratelimit.h>
+#include <linux/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/traps.h>
+
+/* #define DEBUG_UNALIGNED 1 */
+
+#ifdef DEBUG_UNALIGNED
+#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
+#ifdef CONFIG_64BIT
+#define RFMT "%016lx"
+#else
+#define RFMT "%08lx"
+#endif
+
+#define FIXUP_BRANCH(lbl) \
+	"\tldil L%%" #lbl ", %%r1\n"			\
+	"\tldo R%%" #lbl "(%%r1), %%r1\n"		\
+	"\tbv,n %%r0(%%r1)\n"
+/* If you use FIXUP_BRANCH, then you must list this clobber */
+#define FIXUP_BRANCH_CLOBBER "r1"
+
+/* 1111 1100 0000 0000 0001 0011 1100 0000 */
+#define OPCODE1(a,b,c)	((a)<<26|(b)<<12|(c)<<6) 
+#define OPCODE2(a,b)	((a)<<26|(b)<<1)
+#define OPCODE3(a,b)	((a)<<26|(b)<<2)
+#define OPCODE4(a)	((a)<<26)
+#define OPCODE1_MASK	OPCODE1(0x3f,1,0xf)
+#define OPCODE2_MASK 	OPCODE2(0x3f,1)
+#define OPCODE3_MASK	OPCODE3(0x3f,1)
+#define OPCODE4_MASK    OPCODE4(0x3f)
+
+/* skip LDB - never unaligned (index) */
+#define OPCODE_LDH_I	OPCODE1(0x03,0,0x1)
+#define OPCODE_LDW_I	OPCODE1(0x03,0,0x2)
+#define OPCODE_LDD_I	OPCODE1(0x03,0,0x3)
+#define OPCODE_LDDA_I	OPCODE1(0x03,0,0x4)
+#define OPCODE_LDCD_I	OPCODE1(0x03,0,0x5)
+#define OPCODE_LDWA_I	OPCODE1(0x03,0,0x6)
+#define OPCODE_LDCW_I	OPCODE1(0x03,0,0x7)
+/* skip LDB - never unaligned (short) */
+#define OPCODE_LDH_S	OPCODE1(0x03,1,0x1)
+#define OPCODE_LDW_S	OPCODE1(0x03,1,0x2)
+#define OPCODE_LDD_S	OPCODE1(0x03,1,0x3)
+#define OPCODE_LDDA_S	OPCODE1(0x03,1,0x4)
+#define OPCODE_LDCD_S	OPCODE1(0x03,1,0x5)
+#define OPCODE_LDWA_S	OPCODE1(0x03,1,0x6)
+#define OPCODE_LDCW_S	OPCODE1(0x03,1,0x7)
+/* skip STB - never unaligned */
+#define OPCODE_STH	OPCODE1(0x03,1,0x9)
+#define OPCODE_STW	OPCODE1(0x03,1,0xa)
+#define OPCODE_STD	OPCODE1(0x03,1,0xb)
+/* skip STBY - never unaligned */
+/* skip STDBY - never unaligned */
+#define OPCODE_STWA	OPCODE1(0x03,1,0xe)
+#define OPCODE_STDA	OPCODE1(0x03,1,0xf)
+
+#define OPCODE_FLDWX	OPCODE1(0x09,0,0x0)
+#define OPCODE_FLDWXR	OPCODE1(0x09,0,0x1)
+#define OPCODE_FSTWX	OPCODE1(0x09,0,0x8)
+#define OPCODE_FSTWXR	OPCODE1(0x09,0,0x9)
+#define OPCODE_FLDWS	OPCODE1(0x09,1,0x0)
+#define OPCODE_FLDWSR	OPCODE1(0x09,1,0x1)
+#define OPCODE_FSTWS	OPCODE1(0x09,1,0x8)
+#define OPCODE_FSTWSR	OPCODE1(0x09,1,0x9)
+#define OPCODE_FLDDX	OPCODE1(0x0b,0,0x0)
+#define OPCODE_FSTDX	OPCODE1(0x0b,0,0x8)
+#define OPCODE_FLDDS	OPCODE1(0x0b,1,0x0)
+#define OPCODE_FSTDS	OPCODE1(0x0b,1,0x8)
+
+#define OPCODE_LDD_L	OPCODE2(0x14,0)
+#define OPCODE_FLDD_L	OPCODE2(0x14,1)
+#define OPCODE_STD_L	OPCODE2(0x1c,0)
+#define OPCODE_FSTD_L	OPCODE2(0x1c,1)
+
+#define OPCODE_LDW_M	OPCODE3(0x17,1)
+#define OPCODE_FLDW_L	OPCODE3(0x17,0)
+#define OPCODE_FSTW_L	OPCODE3(0x1f,0)
+#define OPCODE_STW_M	OPCODE3(0x1f,1)
+
+#define OPCODE_LDH_L    OPCODE4(0x11)
+#define OPCODE_LDW_L    OPCODE4(0x12)
+#define OPCODE_LDWM     OPCODE4(0x13)
+#define OPCODE_STH_L    OPCODE4(0x19)
+#define OPCODE_STW_L    OPCODE4(0x1A)
+#define OPCODE_STWM     OPCODE4(0x1B)
+
+#define MAJOR_OP(i) (((i)>>26)&0x3f)
+#define R1(i) (((i)>>21)&0x1f)
+#define R2(i) (((i)>>16)&0x1f)
+#define R3(i) ((i)&0x1f)
+#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1))
+#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0))
+#define IM5_2(i) IM((i)>>16,5)
+#define IM5_3(i) IM((i),5)
+#define IM14(i) IM((i),14)
+
+#define ERR_NOTHANDLED	-1
+#define ERR_PAGEFAULT	-2
+
+int unaligned_enabled __read_mostly = 1;
+
+static int emulate_ldh(struct pt_regs *regs, int toreg)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
+	int ret;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n", 
+		regs->isr, regs->ior, toreg);
+
+	__asm__ __volatile__  (
+"	mtsp	%4, %%sr1\n"
+"1:	ldbs	0(%%sr1,%3), %%r20\n"
+"2:	ldbs	1(%%sr1,%3), %0\n"
+"	depw	%%r20, 23, 24, %0\n"
+"	copy	%%r0, %1\n"
+"3:	\n"
+"	.section .fixup,\"ax\"\n"
+"4:	ldi	-2, %1\n"
+	FIXUP_BRANCH(3b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
+	: "=r" (val), "=r" (ret)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r20", FIXUP_BRANCH_CLOBBER );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (toreg)
+		regs->gr[toreg] = val;
+
+	return ret;
+}
+
+static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
+	int ret;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n", 
+		regs->isr, regs->ior, toreg);
+
+	__asm__ __volatile__  (
+"	zdep	%3,28,2,%%r19\n"		/* r19=(ofs&3)*8 */
+"	mtsp	%4, %%sr1\n"
+"	depw	%%r0,31,2,%3\n"
+"1:	ldw	0(%%sr1,%3),%0\n"
+"2:	ldw	4(%%sr1,%3),%%r20\n"
+"	subi	32,%%r19,%%r19\n"
+"	mtctl	%%r19,11\n"
+"	vshd	%0,%%r20,%0\n"
+"	copy	%%r0, %1\n"
+"3:	\n"
+"	.section .fixup,\"ax\"\n"
+"4:	ldi	-2, %1\n"
+	FIXUP_BRANCH(3b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
+	: "=r" (val), "=r" (ret)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (flop)
+		((__u32*)(regs->fr))[toreg] = val;
+	else if (toreg)
+		regs->gr[toreg] = val;
+
+	return ret;
+}
+static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
+{
+	unsigned long saddr = regs->ior;
+	__u64 val = 0;
+	int ret;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n", 
+		regs->isr, regs->ior, toreg);
+#ifdef CONFIG_PA20
+
+#ifndef CONFIG_64BIT
+	if (!flop)
+		return -1;
+#endif
+	__asm__ __volatile__  (
+"	depd,z	%3,60,3,%%r19\n"		/* r19=(ofs&7)*8 */
+"	mtsp	%4, %%sr1\n"
+"	depd	%%r0,63,3,%3\n"
+"1:	ldd	0(%%sr1,%3),%0\n"
+"2:	ldd	8(%%sr1,%3),%%r20\n"
+"	subi	64,%%r19,%%r19\n"
+"	mtsar	%%r19\n"
+"	shrpd	%0,%%r20,%%sar,%0\n"
+"	copy	%%r0, %1\n"
+"3:	\n"
+"	.section .fixup,\"ax\"\n"
+"4:	ldi	-2, %1\n"
+	FIXUP_BRANCH(3b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
+	: "=r" (val), "=r" (ret)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
+#else
+    {
+	unsigned long valh=0,vall=0;
+	__asm__ __volatile__  (
+"	zdep	%5,29,2,%%r19\n"		/* r19=(ofs&3)*8 */
+"	mtsp	%6, %%sr1\n"
+"	dep	%%r0,31,2,%5\n"
+"1:	ldw	0(%%sr1,%5),%0\n"
+"2:	ldw	4(%%sr1,%5),%1\n"
+"3:	ldw	8(%%sr1,%5),%%r20\n"
+"	subi	32,%%r19,%%r19\n"
+"	mtsar	%%r19\n"
+"	vshd	%0,%1,%0\n"
+"	vshd	%1,%%r20,%1\n"
+"	copy	%%r0, %2\n"
+"4:	\n"
+"	.section .fixup,\"ax\"\n"
+"5:	ldi	-2, %2\n"
+	FIXUP_BRANCH(4b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,5b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,5b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,5b)
+	: "=r" (valh), "=r" (vall), "=r" (ret)
+	: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
+	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
+	val=((__u64)valh<<32)|(__u64)vall;
+    }
+#endif
+
+	DPRINTF("val = 0x%llx\n", val);
+
+	if (flop)
+		regs->fr[toreg] = val;
+	else if (toreg)
+		regs->gr[toreg] = val;
+
+	return ret;
+}
+
+static int emulate_sth(struct pt_regs *regs, int frreg)
+{
+	unsigned long val = regs->gr[frreg];
+	int ret;
+
+	if (!frreg)
+		val = 0;
+
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg, 
+		val, regs->isr, regs->ior);
+
+	__asm__ __volatile__ (
+"	mtsp %3, %%sr1\n"
+"	extrw,u %1, 23, 8, %%r19\n"
+"1:	stb %1, 1(%%sr1, %2)\n"
+"2:	stb %%r19, 0(%%sr1, %2)\n"
+"	copy	%%r0, %0\n"
+"3:	\n"
+"	.section .fixup,\"ax\"\n"
+"4:	ldi	-2, %0\n"
+	FIXUP_BRANCH(3b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
+	: "=r" (ret)
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", FIXUP_BRANCH_CLOBBER );
+
+	return ret;
+}
+
+static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
+{
+	unsigned long val;
+	int ret;
+
+	if (flop)
+		val = ((__u32*)(regs->fr))[frreg];
+	else if (frreg)
+		val = regs->gr[frreg];
+	else
+		val = 0;
+
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg, 
+		val, regs->isr, regs->ior);
+
+
+	__asm__ __volatile__ (
+"	mtsp %3, %%sr1\n"
+"	zdep	%2, 28, 2, %%r19\n"
+"	dep	%%r0, 31, 2, %2\n"
+"	mtsar	%%r19\n"
+"	depwi,z	-2, %%sar, 32, %%r19\n"
+"1:	ldw	0(%%sr1,%2),%%r20\n"
+"2:	ldw	4(%%sr1,%2),%%r21\n"
+"	vshd	%%r0, %1, %%r22\n"
+"	vshd	%1, %%r0, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"	stw	%%r20,0(%%sr1,%2)\n"
+"	stw	%%r21,4(%%sr1,%2)\n"
+"	copy	%%r0, %0\n"
+"3:	\n"
+"	.section .fixup,\"ax\"\n"
+"4:	ldi	-2, %0\n"
+	FIXUP_BRANCH(3b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
+	: "=r" (ret)
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+
+	return 0;
+}
+static int emulate_std(struct pt_regs *regs, int frreg, int flop)
+{
+	__u64 val;
+	int ret;
+
+	if (flop)
+		val = regs->fr[frreg];
+	else if (frreg)
+		val = regs->gr[frreg];
+	else
+		val = 0;
+
+	DPRINTF("store r%d (0x%016llx) to " RFMT ":" RFMT " for 8 bytes\n", frreg, 
+		val,  regs->isr, regs->ior);
+
+#ifdef CONFIG_PA20
+#ifndef CONFIG_64BIT
+	if (!flop)
+		return -1;
+#endif
+	__asm__ __volatile__ (
+"	mtsp %3, %%sr1\n"
+"	depd,z	%2, 60, 3, %%r19\n"
+"	depd	%%r0, 63, 3, %2\n"
+"	mtsar	%%r19\n"
+"	depdi,z	-2, %%sar, 64, %%r19\n"
+"1:	ldd	0(%%sr1,%2),%%r20\n"
+"2:	ldd	8(%%sr1,%2),%%r21\n"
+"	shrpd	%%r0, %1, %%sar, %%r22\n"
+"	shrpd	%1, %%r0, %%sar, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"3:	std	%%r20,0(%%sr1,%2)\n"
+"4:	std	%%r21,8(%%sr1,%2)\n"
+"	copy	%%r0, %0\n"
+"5:	\n"
+"	.section .fixup,\"ax\"\n"
+"6:	ldi	-2, %0\n"
+	FIXUP_BRANCH(5b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(4b,6b)
+	: "=r" (ret)
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+#else
+    {
+	unsigned long valh=(val>>32),vall=(val&0xffffffffl);
+	__asm__ __volatile__ (
+"	mtsp	%4, %%sr1\n"
+"	zdep	%2, 29, 2, %%r19\n"
+"	dep	%%r0, 31, 2, %2\n"
+"	mtsar	%%r19\n"
+"	zvdepi	-2, 32, %%r19\n"
+"1:	ldw	0(%%sr1,%3),%%r20\n"
+"2:	ldw	8(%%sr1,%3),%%r21\n"
+"	vshd	%1, %2, %%r1\n"
+"	vshd	%%r0, %1, %1\n"
+"	vshd	%2, %%r0, %2\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%1, %%r20, %1\n"
+"	or	%2, %%r21, %2\n"
+"3:	stw	%1,0(%%sr1,%1)\n"
+"4:	stw	%%r1,4(%%sr1,%3)\n"
+"5:	stw	%2,8(%%sr1,%3)\n"
+"	copy	%%r0, %0\n"
+"6:	\n"
+"	.section .fixup,\"ax\"\n"
+"7:	ldi	-2, %0\n"
+	FIXUP_BRANCH(6b)
+"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(4b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(5b,7b)
+	: "=r" (ret)
+	: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
+    }
+#endif
+
+	return ret;
+}
+
+void handle_unaligned(struct pt_regs *regs)
+{
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
+	unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
+	int modify = 0;
+	int ret = ERR_NOTHANDLED;
+	register int flop=0;	/* true if this is a flop */
+
+	__inc_irq_stat(irq_unaligned_count);
+
+	/* log a message with pacing */
+	if (user_mode(regs)) {
+		if (current->thread.flags & PARISC_UAC_SIGBUS) {
+			goto force_sigbus;
+		}
+
+		if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
+			__ratelimit(&ratelimit)) {
+			char buf[256];
+			sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
+				current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
+			printk(KERN_WARNING "%s", buf);
+#ifdef DEBUG_UNALIGNED
+			show_regs(regs);
+#endif		
+		}
+
+		if (!unaligned_enabled)
+			goto force_sigbus;
+	}
+
+	/* handle modification - OK, it's ugly, see the instruction manual */
+	switch (MAJOR_OP(regs->iir))
+	{
+	case 0x03:
+	case 0x09:
+	case 0x0b:
+		if (regs->iir&0x20)
+		{
+			modify = 1;
+			if (regs->iir&0x1000)		/* short loads */
+				if (regs->iir&0x200)
+					newbase += IM5_3(regs->iir);
+				else
+					newbase += IM5_2(regs->iir);
+			else if (regs->iir&0x2000)	/* scaled indexed */
+			{
+				int shift=0;
+				switch (regs->iir & OPCODE1_MASK)
+				{
+				case OPCODE_LDH_I:
+					shift= 1; break;
+				case OPCODE_LDW_I:
+					shift= 2; break;
+				case OPCODE_LDD_I:
+				case OPCODE_LDDA_I:
+					shift= 3; break;
+				}
+				newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0)<<shift;
+			} else				/* simple indexed */
+				newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0);
+		}
+		break;
+	case 0x13:
+	case 0x1b:
+		modify = 1;
+		newbase += IM14(regs->iir);
+		break;
+	case 0x14:
+	case 0x1c:
+		if (regs->iir&8)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~0xe);
+		}
+		break;
+	case 0x16:
+	case 0x1e:
+		modify = 1;
+		newbase += IM14(regs->iir&6);
+		break;
+	case 0x17:
+	case 0x1f:
+		if (regs->iir&4)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~4);
+		}
+		break;
+	}
+
+	/* TODO: make this cleaner... */
+	switch (regs->iir & OPCODE1_MASK)
+	{
+	case OPCODE_LDH_I:
+	case OPCODE_LDH_S:
+		ret = emulate_ldh(regs, R3(regs->iir));
+		break;
+
+	case OPCODE_LDW_I:
+	case OPCODE_LDWA_I:
+	case OPCODE_LDW_S:
+	case OPCODE_LDWA_S:
+		ret = emulate_ldw(regs, R3(regs->iir),0);
+		break;
+
+	case OPCODE_STH:
+		ret = emulate_sth(regs, R2(regs->iir));
+		break;
+
+	case OPCODE_STW:
+	case OPCODE_STWA:
+		ret = emulate_stw(regs, R2(regs->iir),0);
+		break;
+
+#ifdef CONFIG_PA20
+	case OPCODE_LDD_I:
+	case OPCODE_LDDA_I:
+	case OPCODE_LDD_S:
+	case OPCODE_LDDA_S:
+		ret = emulate_ldd(regs, R3(regs->iir),0);
+		break;
+
+	case OPCODE_STD:
+	case OPCODE_STDA:
+		ret = emulate_std(regs, R2(regs->iir),0);
+		break;
+#endif
+
+	case OPCODE_FLDWX:
+	case OPCODE_FLDWS:
+	case OPCODE_FLDWXR:
+	case OPCODE_FLDWSR:
+		flop=1;
+		ret = emulate_ldw(regs,FR3(regs->iir),1);
+		break;
+
+	case OPCODE_FLDDX:
+	case OPCODE_FLDDS:
+		flop=1;
+		ret = emulate_ldd(regs,R3(regs->iir),1);
+		break;
+
+	case OPCODE_FSTWX:
+	case OPCODE_FSTWS:
+	case OPCODE_FSTWXR:
+	case OPCODE_FSTWSR:
+		flop=1;
+		ret = emulate_stw(regs,FR3(regs->iir),1);
+		break;
+
+	case OPCODE_FSTDX:
+	case OPCODE_FSTDS:
+		flop=1;
+		ret = emulate_std(regs,R3(regs->iir),1);
+		break;
+
+	case OPCODE_LDCD_I:
+	case OPCODE_LDCW_I:
+	case OPCODE_LDCD_S:
+	case OPCODE_LDCW_S:
+		ret = ERR_NOTHANDLED;	/* "undefined", but lets kill them. */
+		break;
+	}
+#ifdef CONFIG_PA20
+	switch (regs->iir & OPCODE2_MASK)
+	{
+	case OPCODE_FLDD_L:
+		flop=1;
+		ret = emulate_ldd(regs,R2(regs->iir),1);
+		break;
+	case OPCODE_FSTD_L:
+		flop=1;
+		ret = emulate_std(regs, R2(regs->iir),1);
+		break;
+	case OPCODE_LDD_L:
+		ret = emulate_ldd(regs, R2(regs->iir),0);
+		break;
+	case OPCODE_STD_L:
+		ret = emulate_std(regs, R2(regs->iir),0);
+		break;
+	}
+#endif
+	switch (regs->iir & OPCODE3_MASK)
+	{
+	case OPCODE_FLDW_L:
+		flop=1;
+		ret = emulate_ldw(regs, R2(regs->iir),0);
+		break;
+	case OPCODE_LDW_M:
+		ret = emulate_ldw(regs, R2(regs->iir),1);
+		break;
+
+	case OPCODE_FSTW_L:
+		flop=1;
+		ret = emulate_stw(regs, R2(regs->iir),1);
+		break;
+	case OPCODE_STW_M:
+		ret = emulate_stw(regs, R2(regs->iir),0);
+		break;
+	}
+	switch (regs->iir & OPCODE4_MASK)
+	{
+	case OPCODE_LDH_L:
+		ret = emulate_ldh(regs, R2(regs->iir));
+		break;
+	case OPCODE_LDW_L:
+	case OPCODE_LDWM:
+		ret = emulate_ldw(regs, R2(regs->iir),0);
+		break;
+	case OPCODE_STH_L:
+		ret = emulate_sth(regs, R2(regs->iir));
+		break;
+	case OPCODE_STW_L:
+	case OPCODE_STWM:
+		ret = emulate_stw(regs, R2(regs->iir),0);
+		break;
+	}
+
+	if (ret == 0 && modify && R1(regs->iir))
+		regs->gr[R1(regs->iir)] = newbase;
+
+
+	if (ret == ERR_NOTHANDLED)
+		printk(KERN_CRIT "Not-handled unaligned insn 0x%08lx\n", regs->iir);
+
+	DPRINTF("ret = %d\n", ret);
+
+	if (ret)
+	{
+		/*
+		 * The unaligned handler failed.
+		 * If we were called by __get_user() or __put_user() jump
+		 * to it's exception fixup handler instead of crashing.
+		 */
+		if (!user_mode(regs) && fixup_exception(regs))
+			return;
+
+		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
+		die_if_kernel("Unaligned data reference", regs, 28);
+
+		if (ret == ERR_PAGEFAULT)
+		{
+			force_sig_fault(SIGSEGV, SEGV_MAPERR,
+					(void __user *)regs->ior, current);
+		}
+		else
+		{
+force_sigbus:
+			/* couldn't handle it ... */
+			force_sig_fault(SIGBUS, BUS_ADRALN,
+					(void __user *)regs->ior, current);
+		}
+		
+		return;
+	}
+
+	/* else we handled it, let life go on. */
+	regs->gr[0]|=PSW_N;
+}
+
+/*
+ * NB: check_unaligned() is only used for PCXS processors right
+ * now, so we only check for PA1.1 encodings at this point.
+ */
+
+int
+check_unaligned(struct pt_regs *regs)
+{
+	unsigned long align_mask;
+
+	/* Get alignment mask */
+
+	align_mask = 0UL;
+	switch (regs->iir & OPCODE1_MASK) {
+
+	case OPCODE_LDH_I:
+	case OPCODE_LDH_S:
+	case OPCODE_STH:
+		align_mask = 1UL;
+		break;
+
+	case OPCODE_LDW_I:
+	case OPCODE_LDWA_I:
+	case OPCODE_LDW_S:
+	case OPCODE_LDWA_S:
+	case OPCODE_STW:
+	case OPCODE_STWA:
+		align_mask = 3UL;
+		break;
+
+	default:
+		switch (regs->iir & OPCODE4_MASK) {
+		case OPCODE_LDH_L:
+		case OPCODE_STH_L:
+			align_mask = 1UL;
+			break;
+		case OPCODE_LDW_L:
+		case OPCODE_LDWM:
+		case OPCODE_STW_L:
+		case OPCODE_STWM:
+			align_mask = 3UL;
+			break;
+		}
+		break;
+	}
+
+	return (int)(regs->ior & align_mask);
+}
+
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
new file mode 100644
index 0000000..2d14f17
--- /dev/null
+++ b/arch/parisc/kernel/unwind.c
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kernel unwinding support
+ *
+ * (c) 2002-2004 Randolph Chung <tausq@debian.org>
+ *
+ * Derived partially from the IA64 implementation. The PA-RISC
+ * Runtime Architecture Document is also a useful reference to
+ * understand what is happening here
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+
+#include <linux/uaccess.h>
+#include <asm/assembly.h>
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+
+#include <asm/unwind.h>
+
+/* #define DEBUG 1 */
+#ifdef DEBUG
+#define dbg(x...) pr_debug(x)
+#else
+#define dbg(x...)
+#endif
+
+#define KERNEL_START (KERNEL_BINARY_TEXT_START)
+
+extern struct unwind_table_entry __start___unwind[];
+extern struct unwind_table_entry __stop___unwind[];
+
+static DEFINE_SPINLOCK(unwind_lock);
+/*
+ * the kernel unwind block is not dynamically allocated so that
+ * we can call unwind_init as early in the bootup process as 
+ * possible (before the slab allocator is initialized)
+ */
+static struct unwind_table kernel_unwind_table __read_mostly;
+static LIST_HEAD(unwind_tables);
+
+static inline const struct unwind_table_entry *
+find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
+{
+	const struct unwind_table_entry *e = NULL;
+	unsigned long lo, hi, mid;
+
+	lo = 0; 
+	hi = table->length - 1; 
+	
+	while (lo <= hi) {
+		mid = (hi - lo) / 2 + lo;
+		e = &table->table[mid];
+		if (addr < e->region_start)
+			hi = mid - 1;
+		else if (addr > e->region_end)
+			lo = mid + 1;
+		else
+			return e;
+	}
+
+	return NULL;
+}
+
+static const struct unwind_table_entry *
+find_unwind_entry(unsigned long addr)
+{
+	struct unwind_table *table;
+	const struct unwind_table_entry *e = NULL;
+
+	if (addr >= kernel_unwind_table.start && 
+	    addr <= kernel_unwind_table.end)
+		e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
+	else {
+		unsigned long flags;
+
+		spin_lock_irqsave(&unwind_lock, flags);
+		list_for_each_entry(table, &unwind_tables, list) {
+			if (addr >= table->start && 
+			    addr <= table->end)
+				e = find_unwind_entry_in_table(table, addr);
+			if (e) {
+				/* Move-to-front to exploit common traces */
+				list_move(&table->list, &unwind_tables);
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&unwind_lock, flags);
+	}
+
+	return e;
+}
+
+static void
+unwind_table_init(struct unwind_table *table, const char *name,
+		  unsigned long base_addr, unsigned long gp,
+		  void *table_start, void *table_end)
+{
+	struct unwind_table_entry *start = table_start;
+	struct unwind_table_entry *end = 
+		(struct unwind_table_entry *)table_end - 1;
+
+	table->name = name;
+	table->base_addr = base_addr;
+	table->gp = gp;
+	table->start = base_addr + start->region_start;
+	table->end = base_addr + end->region_end;
+	table->table = (struct unwind_table_entry *)table_start;
+	table->length = end - start + 1;
+	INIT_LIST_HEAD(&table->list);
+
+	for (; start <= end; start++) {
+		if (start < end && 
+		    start->region_end > (start+1)->region_start) {
+			pr_warn("Out of order unwind entry! %px and %px\n",
+				start, start+1);
+		}
+
+		start->region_start += base_addr;
+		start->region_end += base_addr;
+	}
+}
+
+static int cmp_unwind_table_entry(const void *a, const void *b)
+{
+	return ((const struct unwind_table_entry *)a)->region_start
+	     - ((const struct unwind_table_entry *)b)->region_start;
+}
+
+static void
+unwind_table_sort(struct unwind_table_entry *start,
+		  struct unwind_table_entry *finish)
+{
+	sort(start, finish - start, sizeof(struct unwind_table_entry),
+	     cmp_unwind_table_entry, NULL);
+}
+
+struct unwind_table *
+unwind_table_add(const char *name, unsigned long base_addr, 
+		 unsigned long gp,
+                 void *start, void *end)
+{
+	struct unwind_table *table;
+	unsigned long flags;
+	struct unwind_table_entry *s = (struct unwind_table_entry *)start;
+	struct unwind_table_entry *e = (struct unwind_table_entry *)end;
+
+	unwind_table_sort(s, e);
+
+	table = kmalloc(sizeof(struct unwind_table), GFP_USER);
+	if (table == NULL)
+		return NULL;
+	unwind_table_init(table, name, base_addr, gp, start, end);
+	spin_lock_irqsave(&unwind_lock, flags);
+	list_add_tail(&table->list, &unwind_tables);
+	spin_unlock_irqrestore(&unwind_lock, flags);
+
+	return table;
+}
+
+void unwind_table_remove(struct unwind_table *table)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&unwind_lock, flags);
+	list_del(&table->list);
+	spin_unlock_irqrestore(&unwind_lock, flags);
+
+	kfree(table);
+}
+
+/* Called from setup_arch to import the kernel unwind info */
+int __init unwind_init(void)
+{
+	long start, stop;
+	register unsigned long gp __asm__ ("r27");
+
+	start = (long)&__start___unwind[0];
+	stop = (long)&__stop___unwind[0];
+
+	dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
+	    start, stop,
+	    (stop - start) / sizeof(struct unwind_table_entry));
+
+	unwind_table_init(&kernel_unwind_table, "kernel", KERNEL_START,
+			  gp, 
+			  &__start___unwind[0], &__stop___unwind[0]);
+#if 0
+	{
+		int i;
+		for (i = 0; i < 10; i++)
+		{
+			printk("region 0x%x-0x%x\n", 
+				__start___unwind[i].region_start, 
+				__start___unwind[i].region_end);
+		}
+	}
+#endif
+	return 0;
+}
+
+static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
+{
+	/*
+	 * We have to use void * instead of a function pointer, because
+	 * function pointers aren't a pointer to the function on 64-bit.
+	 * Make them const so the compiler knows they live in .text
+	 * Note: We could use dereference_kernel_function_descriptor()
+	 * instead but we want to keep it simple here.
+	 */
+	extern void * const handle_interruption;
+	extern void * const ret_from_kernel_thread;
+	extern void * const syscall_exit;
+	extern void * const intr_return;
+	extern void * const _switch_to_ret;
+#ifdef CONFIG_IRQSTACKS
+	extern void * const _call_on_stack;
+#endif /* CONFIG_IRQSTACKS */
+
+	if (pc == (unsigned long) &handle_interruption) {
+		struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
+		dbg("Unwinding through handle_interruption()\n");
+		info->prev_sp = regs->gr[30];
+		info->prev_ip = regs->iaoq[0];
+		return 1;
+	}
+
+	if (pc == (unsigned long) &ret_from_kernel_thread ||
+	    pc == (unsigned long) &syscall_exit) {
+		info->prev_sp = info->prev_ip = 0;
+		return 1;
+	}
+
+	if (pc == (unsigned long) &intr_return) {
+		struct pt_regs *regs;
+
+		dbg("Found intr_return()\n");
+		regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN);
+		info->prev_sp = regs->gr[30];
+		info->prev_ip = regs->iaoq[0];
+		info->rp = regs->gr[2];
+		return 1;
+	}
+
+	if (pc == (unsigned long) &_switch_to_ret) {
+		info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
+		info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
+		return 1;
+	}
+
+#ifdef CONFIG_IRQSTACKS
+	if (pc == (unsigned long) &_call_on_stack) {
+		info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
+		info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
+		return 1;
+	}
+#endif
+
+	return 0;
+}
+
+static void unwind_frame_regs(struct unwind_frame_info *info)
+{
+	const struct unwind_table_entry *e;
+	unsigned long npc;
+	unsigned int insn;
+	long frame_size = 0;
+	int looking_for_rp, rpoffset = 0;
+
+	e = find_unwind_entry(info->ip);
+	if (e == NULL) {
+		unsigned long sp;
+
+		dbg("Cannot find unwind entry for %pS; forced unwinding\n",
+			(void *) info->ip);
+
+		/* Since we are doing the unwinding blind, we don't know if
+		   we are adjusting the stack correctly or extracting the rp
+		   correctly. The rp is checked to see if it belongs to the
+		   kernel text section, if not we assume we don't have a 
+		   correct stack frame and we continue to unwind the stack.
+		   This is not quite correct, and will fail for loadable
+		   modules. */
+		sp = info->sp & ~63;
+		do {
+			unsigned long tmp;
+
+			info->prev_sp = sp - 64;
+			info->prev_ip = 0;
+
+			/* The stack is at the end inside the thread_union
+			 * struct. If we reach data, we have reached the
+			 * beginning of the stack and should stop unwinding. */
+			if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
+			    info->prev_sp < ((unsigned long) task_thread_info(info->t)
+						+ THREAD_SZ_ALGN)) {
+				info->prev_sp = 0;
+				break;
+			}
+
+			if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) 
+				break;
+			info->prev_ip = tmp;
+			sp = info->prev_sp;
+		} while (!kernel_text_address(info->prev_ip));
+
+		info->rp = 0;
+
+		dbg("analyzing func @ %lx with no unwind info, setting "
+		    "prev_sp=%lx prev_ip=%lx\n", info->ip, 
+		    info->prev_sp, info->prev_ip);
+	} else {
+		dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, "
+		    "Save_RP = %d, Millicode = %d size = %u\n", 
+		    e->region_start, e->region_end, e->Save_SP, e->Save_RP, 
+		    e->Millicode, e->Total_frame_size);
+
+		looking_for_rp = e->Save_RP;
+
+		for (npc = e->region_start; 
+		     (frame_size < (e->Total_frame_size << 3) || 
+		      looking_for_rp) && 
+		     npc < info->ip; 
+		     npc += 4) {
+
+			insn = *(unsigned int *)npc;
+
+			if ((insn & 0xffffc001) == 0x37de0000 ||
+			    (insn & 0xffe00001) == 0x6fc00000) {
+				/* ldo X(sp), sp, or stwm X,D(sp) */
+				frame_size += (insn & 0x3fff) >> 1;
+				dbg("analyzing func @ %lx, insn=%08x @ "
+				    "%lx, frame_size = %ld\n", info->ip,
+				    insn, npc, frame_size);
+			} else if ((insn & 0xffe00009) == 0x73c00008) {
+				/* std,ma X,D(sp) */
+				frame_size += ((insn >> 4) & 0x3ff) << 3;
+				dbg("analyzing func @ %lx, insn=%08x @ "
+				    "%lx, frame_size = %ld\n", info->ip,
+				    insn, npc, frame_size);
+			} else if (insn == 0x6bc23fd9) { 
+				/* stw rp,-20(sp) */
+				rpoffset = 20;
+				looking_for_rp = 0;
+				dbg("analyzing func @ %lx, insn=stw rp,"
+				    "-20(sp) @ %lx\n", info->ip, npc);
+			} else if (insn == 0x0fc212c1) {
+				/* std rp,-16(sr0,sp) */
+				rpoffset = 16;
+				looking_for_rp = 0;
+				dbg("analyzing func @ %lx, insn=std rp,"
+				    "-16(sp) @ %lx\n", info->ip, npc);
+			}
+		}
+
+		if (frame_size > e->Total_frame_size << 3)
+			frame_size = e->Total_frame_size << 3;
+
+		if (!unwind_special(info, e->region_start, frame_size)) {
+			info->prev_sp = info->sp - frame_size;
+			if (e->Millicode)
+				info->rp = info->r31;
+			else if (rpoffset)
+				info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
+			info->prev_ip = info->rp;
+			info->rp = 0;
+		}
+
+		dbg("analyzing func @ %lx, setting prev_sp=%lx "
+		    "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp, 
+		    info->prev_ip, npc);
+	}
+}
+
+void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, 
+		       struct pt_regs *regs)
+{
+	memset(info, 0, sizeof(struct unwind_frame_info));
+	info->t = t;
+	info->sp = regs->gr[30];
+	info->ip = regs->iaoq[0];
+	info->rp = regs->gr[2];
+	info->r31 = regs->gr[31];
+
+	dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n", 
+	    t ? (int)t->pid : -1, info->sp, info->ip);
+}
+
+void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
+{
+	struct pt_regs *r = &t->thread.regs;
+	struct pt_regs *r2;
+
+	r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC);
+	if (!r2)
+		return;
+	*r2 = *r;
+	r2->gr[30] = r->ksp;
+	r2->iaoq[0] = r->kpc;
+	unwind_frame_init(info, t, r2);
+	kfree(r2);
+}
+
+#define get_parisc_stackpointer() ({ \
+	unsigned long sp; \
+	__asm__("copy %%r30, %0" : "=r"(sp)); \
+	(sp); \
+})
+
+void unwind_frame_init_task(struct unwind_frame_info *info,
+	struct task_struct *task, struct pt_regs *regs)
+{
+	task = task ? task : current;
+
+	if (task == current) {
+		struct pt_regs r;
+
+		if (!regs) {
+			memset(&r, 0, sizeof(r));
+			r.iaoq[0] =  _THIS_IP_;
+			r.gr[2] = _RET_IP_;
+			r.gr[30] = get_parisc_stackpointer();
+			regs = &r;
+		}
+		unwind_frame_init(info, task, regs);
+	} else {
+		unwind_frame_init_from_blocked_task(info, task);
+	}
+}
+
+int unwind_once(struct unwind_frame_info *next_frame)
+{
+	unwind_frame_regs(next_frame);
+
+	if (next_frame->prev_sp == 0 ||
+	    next_frame->prev_ip == 0)
+		return -1;
+
+	next_frame->sp = next_frame->prev_sp;
+	next_frame->ip = next_frame->prev_ip;
+	next_frame->prev_sp = 0;
+	next_frame->prev_ip = 0;
+
+	dbg("(%d) Continue unwind to sp=%08lx ip=%08lx\n", 
+	    next_frame->t ? (int)next_frame->t->pid : -1, 
+	    next_frame->sp, next_frame->ip);
+
+	return 0;
+}
+
+int unwind_to_user(struct unwind_frame_info *info)
+{
+	int ret;
+	
+	do {
+		ret = unwind_once(info);
+	} while (!ret && !(info->ip & 3));
+
+	return ret;
+}
+
+unsigned long return_address(unsigned int level)
+{
+	struct unwind_frame_info info;
+
+	/* initialize unwind info */
+	unwind_frame_init_task(&info, current, NULL);
+
+	/* unwind stack */
+	level += 2;
+	do {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			return 0;
+		if (!kernel_text_address(info.ip))
+			return 0;
+	} while (info.ip && level--);
+
+	return info.ip;
+}
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..da2e311
--- /dev/null
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*    Kernel link layout for various "sections"
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
+ *    Copyright (C) 2006-2013 Helge Deller <deller@gmx.de>
+ */
+
+/*
+ * Put page table entries (swapper_pg_dir) as the first thing in .bss. This
+ * will ensure that it has .bss alignment (PAGE_SIZE).
+ */
+#define BSS_FIRST_SECTIONS	*(.data..vm0.pmd) \
+				*(.data..vm0.pgd) \
+				*(.data..vm0.pte)
+
+#include <asm-generic/vmlinux.lds.h>
+
+/* needed for the processor specific cache alignment size */	
+#include <asm/cache.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+	
+/* ld script to make hppa Linux kernel */
+#ifndef CONFIG_64BIT
+OUTPUT_FORMAT("elf32-hppa-linux")
+OUTPUT_ARCH(hppa)
+#else
+OUTPUT_FORMAT("elf64-hppa-linux")
+OUTPUT_ARCH(hppa:hppa2.0w)
+#endif
+
+ENTRY(parisc_kernel_start)
+#ifndef CONFIG_64BIT
+jiffies = jiffies_64 + 4;
+#else
+jiffies = jiffies_64;
+#endif
+SECTIONS
+{
+	. = KERNEL_BINARY_TEXT_START;
+
+	__init_begin = .;
+	HEAD_TEXT_SECTION
+	INIT_TEXT_SECTION(8)
+
+	. = ALIGN(PAGE_SIZE);
+	INIT_DATA_SECTION(PAGE_SIZE)
+	/* we have to discard exit text and such at runtime, not link time */
+	.exit.text :
+	{
+		EXIT_TEXT
+	}
+	.exit.data :
+	{
+		EXIT_DATA
+	}
+	PERCPU_SECTION(8)
+	. = ALIGN(HUGEPAGE_SIZE);
+	__init_end = .;
+	/* freed after init ends here */
+
+	_text = .;		/* Text and read-only data */
+	_stext = .;
+	.text ALIGN(PAGE_SIZE) : {
+		TEXT_TEXT
+		SCHED_TEXT
+		CPUIDLE_TEXT
+		LOCK_TEXT
+		KPROBES_TEXT
+		IRQENTRY_TEXT
+		SOFTIRQENTRY_TEXT
+		*(.text.do_softirq)
+		*(.text.sys_exit)
+		*(.text.do_sigaltstack)
+		*(.text.do_fork)
+		*(.text.div)
+		*($$*)			/* millicode routines */
+		*(.text.*)
+		*(.fixup)
+		*(.lock.text)		/* out-of-line lock text */
+		*(.gnu.warning)
+	}
+	. = ALIGN(PAGE_SIZE);
+	_etext = .;
+	/* End of text section */
+
+	/* Start of data section */
+	_sdata = .;
+
+	/* Architecturally we need to keep __gp below 0x1000000 and thus
+	 * in front of RO_DATA_SECTION() which stores lots of tracepoint
+	 * and ftrace symbols. */
+#ifdef CONFIG_64BIT
+	. = ALIGN(16);
+	/* Linkage tables */
+	.opd : {
+		__start_opd = .;
+		*(.opd)
+		__end_opd = .;
+	} PROVIDE (__gp = .);
+	.plt : {
+		*(.plt)
+	}
+	.dlt : {
+		*(.dlt)
+	}
+#endif
+
+	RO_DATA_SECTION(8)
+
+	/* RO because of BUILDTIME_EXTABLE_SORT */
+	EXCEPTION_TABLE(8)
+	NOTES
+
+	/* unwind info */
+	.PARISC.unwind : {
+		__start___unwind = .;
+		*(.PARISC.unwind)
+		__stop___unwind = .;
+	}
+
+	/* writeable */
+	/* Make sure this is page aligned so
+	 * that we can properly leave these
+	 * as writable
+	 */
+	. = ALIGN(HUGEPAGE_SIZE);
+	data_start = .;
+
+	/* Data */
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, PAGE_SIZE)
+
+	/* PA-RISC locks requires 16-byte alignment */
+	. = ALIGN(16);
+	.data..lock_aligned : {
+		*(.data..lock_aligned)
+	}
+
+	/* End of data section */
+	_edata = .;
+
+	/* BSS */
+	BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE)
+
+	. = ALIGN(HUGEPAGE_SIZE);
+	_end = . ;
+
+	STABS_DEBUG
+	.note 0 : { *(.note) }
+
+	/* Sections to be discarded */
+	DISCARDS
+	/DISCARD/ : {
+#ifdef CONFIG_64BIT
+		/* temporary hack until binutils is fixed to not emit these
+	 	 * for static binaries
+		 */
+		*(.interp)
+		*(.dynsym)
+		*(.dynstr)
+		*(.dynamic)
+		*(.hash)
+		*(.gnu.hash)
+#endif
+	}
+}