Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 10 Nov 2005 18:17:11 +0000 (10:17 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 10 Nov 2005 18:17:11 +0000 (10:17 -0800)
173 files changed:
arch/powerpc/Kconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cpu_setup_power4.S [new file with mode: 0644]
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/firmware.c [new file with mode: 0644]
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/ioctl32.c [new file with mode: 0644]
arch/powerpc/kernel/irq.c [new file with mode: 0644]
arch/powerpc/kernel/lparcfg.c [new file with mode: 0644]
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/paca.c [new file with mode: 0644]
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/proc_ppc64.c [new file with mode: 0644]
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/rtas-proc.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_pci.c [new file with mode: 0644]
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup.h [new file with mode: 0644]
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/sysfs.c [new file with mode: 0644]
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/lib/bitops.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/stab.c
arch/powerpc/oprofile/op_model_power4.c
arch/powerpc/platforms/chrp/setup.c
arch/powerpc/platforms/iseries/irq.c
arch/powerpc/platforms/iseries/misc.S
arch/powerpc/platforms/iseries/setup.c
arch/powerpc/platforms/maple/pci.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/eeh.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/eeh_event.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/pci.c
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/rtasd.c
arch/powerpc/platforms/pseries/scanlog.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/u3_iommu.c
arch/powerpc/xmon/Makefile
arch/powerpc/xmon/nonstdio.c [new file with mode: 0644]
arch/powerpc/xmon/nonstdio.h
arch/powerpc/xmon/setjmp.S
arch/powerpc/xmon/start_32.c
arch/powerpc/xmon/start_64.c
arch/powerpc/xmon/start_8xx.c
arch/powerpc/xmon/subr_prf.c [deleted file]
arch/powerpc/xmon/xmon.c
arch/ppc/boot/include/of1275.h
arch/ppc/boot/of1275/Makefile
arch/ppc/boot/of1275/call_prom.c [new file with mode: 0644]
arch/ppc/boot/of1275/claim.c
arch/ppc/boot/of1275/finddevice.c
arch/ppc/boot/openfirmware/Makefile
arch/ppc/kernel/Makefile
arch/ppc/kernel/head_booke.h
arch/ppc/kernel/irq.c [deleted file]
arch/ppc/kernel/misc.S
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/setup.c
arch/ppc/platforms/pmac_pic.c
arch/ppc/platforms/prep_setup.c
arch/ppc64/Kconfig
arch/ppc64/boot/addRamDisk.c
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/asm-offsets.c
arch/ppc64/kernel/cpu_setup_power4.S [deleted file]
arch/ppc64/kernel/eeh.c [deleted file]
arch/ppc64/kernel/firmware.c [deleted file]
arch/ppc64/kernel/head.S
arch/ppc64/kernel/idle.c
arch/ppc64/kernel/ioctl32.c [deleted file]
arch/ppc64/kernel/irq.c [deleted file]
arch/ppc64/kernel/lparcfg.c [deleted file]
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/nvram.c
arch/ppc64/kernel/pacaData.c [deleted file]
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci_dn.c
arch/ppc64/kernel/proc_ppc64.c [deleted file]
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/prom_init.c
arch/ppc64/kernel/rtas_pci.c [deleted file]
arch/ppc64/kernel/scanlog.c [deleted file]
arch/ppc64/kernel/sysfs.c [deleted file]
arch/ppc64/kernel/vdso.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/au1000_db1x00.c
drivers/pcmcia/au1000_generic.h
drivers/pcmcia/au1000_pb1x00.c
drivers/pcmcia/au1000_xxs1500.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m8xx_pcmcia.c
include/asm-powerpc/abs_addr.h [new file with mode: 0644]
include/asm-powerpc/asm-compat.h [new file with mode: 0644]
include/asm-powerpc/atomic.h
include/asm-powerpc/bitops.h
include/asm-powerpc/bug.h
include/asm-powerpc/cache.h [new file with mode: 0644]
include/asm-powerpc/cacheflush.h [new file with mode: 0644]
include/asm-powerpc/compat.h [new file with mode: 0644]
include/asm-powerpc/cputable.h
include/asm-powerpc/current.h [new file with mode: 0644]
include/asm-powerpc/eeh_event.h [new file with mode: 0644]
include/asm-powerpc/firmware.h
include/asm-powerpc/futex.h
include/asm-powerpc/hvcall.h [new file with mode: 0644]
include/asm-powerpc/hw_irq.h
include/asm-powerpc/irq.h
include/asm-powerpc/lppaca.h [new file with mode: 0644]
include/asm-powerpc/paca.h [new file with mode: 0644]
include/asm-powerpc/ppc-pci.h
include/asm-powerpc/ppc_asm.h
include/asm-powerpc/processor.h
include/asm-powerpc/reg.h
include/asm-powerpc/reg_8xx.h [new file with mode: 0644]
include/asm-powerpc/signal.h [new file with mode: 0644]
include/asm-powerpc/sparsemem.h
include/asm-powerpc/system.h
include/asm-powerpc/systemcfg.h [new file with mode: 0644]
include/asm-powerpc/tce.h [new file with mode: 0644]
include/asm-powerpc/uaccess.h
include/asm-powerpc/xmon.h
include/asm-ppc/cache.h [deleted file]
include/asm-ppc/cacheflush.h [deleted file]
include/asm-ppc/current.h [deleted file]
include/asm-ppc/signal.h [deleted file]
include/asm-ppc64/abs_addr.h [deleted file]
include/asm-ppc64/cache.h [deleted file]
include/asm-ppc64/cacheflush.h [deleted file]
include/asm-ppc64/compat.h [deleted file]
include/asm-ppc64/current.h [deleted file]
include/asm-ppc64/eeh.h
include/asm-ppc64/hvcall.h [deleted file]
include/asm-ppc64/lppaca.h [deleted file]
include/asm-ppc64/mmu.h
include/asm-ppc64/mmzone.h
include/asm-ppc64/paca.h [deleted file]
include/asm-ppc64/page.h
include/asm-ppc64/pci-bridge.h
include/asm-ppc64/pgalloc.h
include/asm-ppc64/prom.h
include/asm-ppc64/signal.h [deleted file]
include/asm-ppc64/system.h
include/asm-ppc64/systemcfg.h [deleted file]
include/asm-ppc64/tce.h [deleted file]
kernel/signal.c

index 1493c7896fe35f3af26a866e56f4c1b5aed5a2b5..ed31062029f7231e7434d436e628d3eed68fc774 100644 (file)
@@ -599,6 +599,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
        def_bool y
        depends on NEED_MULTIPLE_NODES
 
+config ARCH_MEMORY_PROBE
+       def_bool y
+       depends on MEMORY_HOTPLUG
+
 # Some NUMA nodes have memory ranges that span
 # other nodes.  Even though a pfn is valid and
 # between a node's start and end pfns, it may not
index b3ae2993efb88b97036642595b85479d5d3c0b87..c04bbd320594e6c032ecf75a814a5325908e05f5 100644 (file)
@@ -4,6 +4,7 @@
 
 ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS   += -mno-minimal-toc
+CFLAGS_ioctl32.o += -Ifs/
 endif
 ifeq ($(CONFIG_PPC32),y)
 CFLAGS_prom_init.o      += -fPIC
@@ -11,15 +12,21 @@ CFLAGS_btext.o              += -fPIC
 endif
 
 obj-y                          := semaphore.o cputable.o ptrace.o syscalls.o \
-                                  signal_32.o pmc.o
+                                  irq.o signal_32.o pmc.o
 obj-$(CONFIG_PPC64)            += setup_64.o binfmt_elf32.o sys_ppc32.o \
-                                  signal_64.o ptrace32.o systbl.o
+                                  signal_64.o ptrace32.o systbl.o \
+                                  paca.o ioctl32.o cpu_setup_power4.o \
+                                  firmware.o sysfs.o
 obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
 obj-$(CONFIG_POWER4)           += idle_power4.o
 obj-$(CONFIG_PPC_OF)           += of_device.o
-obj-$(CONFIG_PPC_RTAS)         += rtas.o
+procfs-$(CONFIG_PPC64)         := proc_ppc64.o
+obj-$(CONFIG_PROC_FS)          += $(procfs-y)
+rtaspci-$(CONFIG_PPC64)                := rtas_pci.o
+obj-$(CONFIG_PPC_RTAS)         += rtas.o $(rtaspci-y)
 obj-$(CONFIG_RTAS_FLASH)       += rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)                += rtas-proc.o
+obj-$(CONFIG_LPARCFG)          += lparcfg.o
 obj-$(CONFIG_IBMVIO)           += vio.o
 obj-$(CONFIG_GENERIC_TBSYNC)   += smp-tbsync.o
 
index b75757251994ec925617658e0eb7d3e3415b3f99..8793102711a8faa7f24ac5ad2c31468e6d46e5de 100644 (file)
@@ -106,7 +106,6 @@ int main(void)
        DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
-       DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
        DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
 
        /* paca */
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S
new file mode 100644 (file)
index 0000000..cca942f
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * This file contains low level CPU setup functions.
+ *    Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.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.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+
+_GLOBAL(__970_cpu_preinit)
+       /*
+        * Do nothing if not running in HV mode
+        */
+       mfmsr   r0
+       rldicl. r0,r0,4,63
+       beqlr
+
+       /*
+        * Deal only with PPC970 and PPC970FX.
+        */
+       mfspr   r0,SPRN_PVR
+       srwi    r0,r0,16
+       cmpwi   r0,0x39
+       beq     1f
+       cmpwi   r0,0x3c
+       beq     1f
+       cmpwi   r0,0x44
+       bnelr
+1:
+
+       /* Make sure HID4:rm_ci is off before MMU is turned off, that large
+        * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
+        * HID5:DCBZ32_ill
+        */
+       li      r0,0
+       mfspr   r3,SPRN_HID4
+       rldimi  r3,r0,40,23     /* clear bit 23 (rm_ci) */
+       rldimi  r3,r0,2,61      /* clear bit 61 (lg_pg_en) */
+       sync
+       mtspr   SPRN_HID4,r3
+       isync
+       sync
+       mfspr   r3,SPRN_HID5
+       rldimi  r3,r0,6,56      /* clear bits 56 & 57 (DCBZ*) */
+       sync
+       mtspr   SPRN_HID5,r3
+       isync
+       sync
+
+       /* Setup some basic HID1 features */
+       mfspr   r0,SPRN_HID1
+       li      r3,0x1200               /* enable i-fetch cacheability */
+       sldi    r3,r3,44                /* and prefetch */
+       or      r0,r0,r3
+       mtspr   SPRN_HID1,r0
+       mtspr   SPRN_HID1,r0
+       isync
+
+       /* Clear HIOR */
+       li      r0,0
+       sync
+       mtspr   SPRN_HIOR,0             /* Clear interrupt prefix */
+       isync
+       blr
+
+_GLOBAL(__setup_cpu_power4)
+       blr
+
+_GLOBAL(__setup_cpu_be)
+        /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
+        addi    r3, 0,  0
+        ori     r3, r3, HID6_LB
+        sldi    r3, r3, 32
+        nor     r3, r3, r3
+        mfspr   r4, SPRN_HID6
+        and     r4, r4, r3
+        addi    r3, 0, 0x02000
+        sldi    r3, r3, 32
+        or      r4, r4, r3
+        mtspr   SPRN_HID6, r4
+       blr
+
+_GLOBAL(__setup_cpu_ppc970)
+       mfspr   r0,SPRN_HID0
+       li      r11,5                   /* clear DOZE and SLEEP */
+       rldimi  r0,r11,52,8             /* set NAP and DPM */
+       mtspr   SPRN_HID0,r0
+       mfspr   r0,SPRN_HID0
+       mfspr   r0,SPRN_HID0
+       mfspr   r0,SPRN_HID0
+       mfspr   r0,SPRN_HID0
+       mfspr   r0,SPRN_HID0
+       mfspr   r0,SPRN_HID0
+       sync
+       isync
+       blr
+
+/* Definitions for the table use to save CPU states */
+#define CS_HID0                0
+#define CS_HID1                8
+#define        CS_HID4         16
+#define CS_HID5                24
+#define CS_SIZE                32
+
+       .data
+       .balign L1_CACHE_BYTES,0
+cpu_state_storage:
+       .space  CS_SIZE
+       .balign L1_CACHE_BYTES,0
+       .text
+
+/* Called in normal context to backup CPU 0 state. This
+ * does not include cache settings. This function is also
+ * called for machine sleep. This does not include the MMU
+ * setup, BATs, etc... but rather the "special" registers
+ * like HID0, HID1, HID4, etc...
+ */
+_GLOBAL(__save_cpu_setup)
+       /* Some CR fields are volatile, we back it up all */
+       mfcr    r7
+
+       /* Get storage ptr */
+       LOADADDR(r5,cpu_state_storage)
+
+       /* We only deal with 970 for now */
+       mfspr   r0,SPRN_PVR
+       srwi    r0,r0,16
+       cmpwi   r0,0x39
+       beq     1f
+       cmpwi   r0,0x3c
+       beq     1f
+       cmpwi   r0,0x44
+       bne     2f
+
+1:     /* Save HID0,1,4 and 5 */
+       mfspr   r3,SPRN_HID0
+       std     r3,CS_HID0(r5)
+       mfspr   r3,SPRN_HID1
+       std     r3,CS_HID1(r5)
+       mfspr   r3,SPRN_HID4
+       std     r3,CS_HID4(r5)
+       mfspr   r3,SPRN_HID5
+       std     r3,CS_HID5(r5)
+
+2:
+       mtcr    r7
+       blr
+
+/* Called with no MMU context (typically MSR:IR/DR off) to
+ * restore CPU state as backed up by the previous
+ * function. This does not include cache setting
+ */
+_GLOBAL(__restore_cpu_setup)
+       /* Get storage ptr (FIXME when using anton reloc as we
+        * are running with translation disabled here
+        */
+       LOADADDR(r5,cpu_state_storage)
+
+       /* We only deal with 970 for now */
+       mfspr   r0,SPRN_PVR
+       srwi    r0,r0,16
+       cmpwi   r0,0x39
+       beq     1f
+       cmpwi   r0,0x3c
+       beq     1f
+       cmpwi   r0,0x44
+       bnelr
+
+1:     /* Before accessing memory, we make sure rm_ci is clear */
+       li      r0,0
+       mfspr   r3,SPRN_HID4
+       rldimi  r3,r0,40,23     /* clear bit 23 (rm_ci) */
+       sync
+       mtspr   SPRN_HID4,r3
+       isync
+       sync
+
+       /* Clear interrupt prefix */
+       li      r0,0
+       sync
+       mtspr   SPRN_HIOR,0
+       isync
+
+       /* Restore HID0 */
+       ld      r3,CS_HID0(r5)
+       sync
+       isync
+       mtspr   SPRN_HID0,r3
+       mfspr   r3,SPRN_HID0
+       mfspr   r3,SPRN_HID0
+       mfspr   r3,SPRN_HID0
+       mfspr   r3,SPRN_HID0
+       mfspr   r3,SPRN_HID0
+       mfspr   r3,SPRN_HID0
+       sync
+       isync
+
+       /* Restore HID1 */
+       ld      r3,CS_HID1(r5)
+       sync
+       isync
+       mtspr   SPRN_HID1,r3
+       mtspr   SPRN_HID1,r3
+       sync
+       isync
+
+       /* Restore HID4 */
+       ld      r3,CS_HID4(r5)
+       sync
+       isync
+       mtspr   SPRN_HID4,r3
+       sync
+       isync
+
+       /* Restore HID5 */
+       ld      r3,CS_HID5(r5)
+       sync
+       isync
+       mtspr   SPRN_HID5,r3
+       sync
+       isync
+       blr
+
index cc4e9eb1c13f98041ca53467659c0f3b024cee28..1d85cedbbb7b740d4ed9d14db828e469f2942244 100644 (file)
@@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 #define COMMON_USER            (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
                                 PPC_FEATURE_HAS_MMU)
 #define COMMON_USER_PPC64      (COMMON_USER | PPC_FEATURE_64)
+#define COMMON_USER_POWER4     (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
+#define COMMON_USER_POWER5     (COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
+#define COMMON_USER_POWER5_PLUS        (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
 
 
 /* We only set the spe features if the kernel was compiled with
@@ -160,7 +163,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00350000,
                .cpu_name               = "POWER4 (gp)",
                .cpu_features           = CPU_FTRS_POWER4,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_POWER4,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
@@ -175,7 +178,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00380000,
                .cpu_name               = "POWER4+ (gq)",
                .cpu_features           = CPU_FTRS_POWER4,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_POWER4,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
@@ -190,7 +193,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00390000,
                .cpu_name               = "PPC970",
                .cpu_features           = CPU_FTRS_PPC970,
-               .cpu_user_features      = COMMON_USER_PPC64 |
+               .cpu_user_features      = COMMON_USER_POWER4 |
                        PPC_FEATURE_HAS_ALTIVEC_COMP,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
@@ -212,7 +215,7 @@ struct cpu_spec     cpu_specs[] = {
 #else
                .cpu_features           = CPU_FTRS_PPC970,
 #endif
-               .cpu_user_features      = COMMON_USER_PPC64 |
+               .cpu_user_features      = COMMON_USER_POWER4 |
                        PPC_FEATURE_HAS_ALTIVEC_COMP,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
@@ -230,7 +233,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00440000,
                .cpu_name               = "PPC970MP",
                .cpu_features           = CPU_FTRS_PPC970,
-               .cpu_user_features      = COMMON_USER_PPC64 |
+               .cpu_user_features      = COMMON_USER_POWER4 |
                        PPC_FEATURE_HAS_ALTIVEC_COMP,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
@@ -245,7 +248,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x003a0000,
                .cpu_name               = "POWER5 (gr)",
                .cpu_features           = CPU_FTRS_POWER5,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_POWER5,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
@@ -260,7 +263,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x003b0000,
                .cpu_name               = "POWER5 (gs)",
                .cpu_features           = CPU_FTRS_POWER5,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_POWER5_PLUS,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
@@ -276,7 +279,7 @@ struct cpu_spec     cpu_specs[] = {
                .cpu_name               = "Cell Broadband Engine",
                .cpu_features           = CPU_FTRS_CELL,
                .cpu_user_features      = COMMON_USER_PPC64 |
-                       PPC_FEATURE_HAS_ALTIVEC_COMP,
+                       PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .cpu_setup              = __setup_cpu_be,
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
new file mode 100644 (file)
index 0000000..65eae75
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Extracted from cputable.c
+ *
+ *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ *
+ *  Modifications for ppc64:
+ *      Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ *  Copyright (C) 2005 Stephen Rothwell, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+
+#include <asm/firmware.h>
+
+unsigned long ppc64_firmware_features;
+
+#ifdef CONFIG_PPC_PSERIES
+firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
+       {FW_FEATURE_PFT,                "hcall-pft"},
+       {FW_FEATURE_TCE,                "hcall-tce"},
+       {FW_FEATURE_SPRG0,              "hcall-sprg0"},
+       {FW_FEATURE_DABR,               "hcall-dabr"},
+       {FW_FEATURE_COPY,               "hcall-copy"},
+       {FW_FEATURE_ASR,                "hcall-asr"},
+       {FW_FEATURE_DEBUG,              "hcall-debug"},
+       {FW_FEATURE_PERF,               "hcall-perf"},
+       {FW_FEATURE_DUMP,               "hcall-dump"},
+       {FW_FEATURE_INTERRUPT,          "hcall-interrupt"},
+       {FW_FEATURE_MIGRATE,            "hcall-migrate"},
+       {FW_FEATURE_PERFMON,            "hcall-perfmon"},
+       {FW_FEATURE_CRQ,                "hcall-crq"},
+       {FW_FEATURE_VIO,                "hcall-vio"},
+       {FW_FEATURE_RDMA,               "hcall-rdma"},
+       {FW_FEATURE_LLAN,               "hcall-lLAN"},
+       {FW_FEATURE_BULK,               "hcall-bulk"},
+       {FW_FEATURE_XDABR,              "hcall-xdabr"},
+       {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
+       {FW_FEATURE_SPLPAR,             "hcall-splpar"},
+};
+#endif
index 4d6001fa1cf269db574ab37e8521a8d1093bbfa9..b780b42c95fc0f57c42dbb4b12ed58876742e4d3 100644 (file)
@@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu)
 #ifndef CONFIG_SMP
        LOADBASE(r3, last_task_used_math)
        toreal(r3)
-       LDL     r4,OFF(last_task_used_math)(r3)
-       CMPI    0,r4,0
+       PPC_LL  r4,OFF(last_task_used_math)(r3)
+       PPC_LCMPI       0,r4,0
        beq     1f
        toreal(r4)
        addi    r4,r4,THREAD            /* want last_task_used_math->thread */
        SAVE_32FPRS(0, r4)
        mffs    fr0
        stfd    fr0,THREAD_FPSCR(r4)
-       LDL     r5,PT_REGS(r4)
+       PPC_LL  r5,PT_REGS(r4)
        toreal(r5)
-       LDL     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
        li      r10,MSR_FP|MSR_FE0|MSR_FE1
        andc    r4,r4,r10               /* disable FP for previous task */
-       STL     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 #endif /* CONFIG_SMP */
        /* enable use of FP after return */
@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
 #ifndef CONFIG_SMP
        subi    r4,r5,THREAD
        fromreal(r4)
-       STL     r4,OFF(last_task_used_math)(r3)
+       PPC_STL r4,OFF(last_task_used_math)(r3)
 #endif /* CONFIG_SMP */
        /* restore registers and return */
        /* we haven't used ctr or xer or lr */
@@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu)
        MTMSRD(r5)                      /* enable use of fpu now */
        SYNC_601
        isync
-       CMPI    0,r3,0
+       PPC_LCMPI       0,r3,0
        beqlr-                          /* if no previous owner, done */
        addi    r3,r3,THREAD            /* want THREAD of task */
-       LDL     r5,PT_REGS(r3)
-       CMPI    0,r5,0
+       PPC_LL  r5,PT_REGS(r3)
+       PPC_LCMPI       0,r5,0
        SAVE_32FPRS(0, r3)
        mffs    fr0
        stfd    fr0,THREAD_FPSCR(r3)
        beq     1f
-       LDL     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
        li      r3,MSR_FP|MSR_FE0|MSR_FE1
        andc    r4,r4,r3                /* disable FP for previous task */
-       STL     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 #ifndef CONFIG_SMP
        li      r5,0
        LOADBASE(r4,last_task_used_math)
-       STL     r5,OFF(last_task_used_math)(r4)
+       PPC_STL r5,OFF(last_task_used_math)(r4)
 #endif /* CONFIG_SMP */
        blr
 
index 16ab40daa73852b1f8665888edc882cd69d6997b..8a8bf79ef0449605fa6ea36152f927d6de854e57 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/reg.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/systemcfg.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/bug.h>
@@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start)
  *   SPRG3 = paca virtual address
  */
 _GLOBAL(__secondary_start)
+       /* Set thread priority to MEDIUM */
+       HMT_MEDIUM
 
-       HMT_MEDIUM                      /* Set thread priority to MEDIUM */
-
+       /* Load TOC */
        ld      r2,PACATOC(r13)
-       li      r6,0
-       stb     r6,PACAPROCENABLED(r13)
-
-#ifndef CONFIG_PPC_ISERIES
-       /* Initialize the page table pointer register. */
-       LOADADDR(r6,_SDR1)
-       ld      r6,0(r6)                /* get the value of _SDR1        */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location         */
-#endif
-       /* Initialize the first segment table (or SLB) entry             */
-       ld      r3,PACASTABVIRT(r13)    /* get addr of segment table     */
-BEGIN_FTR_SECTION
-       bl      .stab_initialize
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-       bl      .slb_initialize
+
+       /* Do early setup for that CPU (stab, slb, hash table pointer) */
+       bl      .early_setup_secondary
 
        /* Initialize the kernel stack.  Just a repeat for iSeries.      */
        LOADADDR(r3,current_set)
@@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
        std     r1,PACAKSAVE(r13)
 
-       ld      r3,PACASTABREAL(r13)    /* get raddr of segment table    */
-       ori     r4,r3,1                 /* turn on valid bit             */
-
-#ifdef CONFIG_PPC_ISERIES
-       li      r0,-1                   /* hypervisor call */
-       li      r3,1
-       sldi    r3,r3,63                /* 0x8000000000000000 */
-       ori     r3,r3,4                 /* 0x8000000000000004 */
-       sc                              /* HvCall_setASR */
-#else
-       /* set the ASR */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg         */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags           */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar  */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star)  */
-       mtasr   r4                      /* set the stab location         */
-99:
-#endif
+       /* Clear backchain so we get nice backtraces */
        li      r7,0
        mtlr    r7
 
@@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog)
        li      r3,0
        std     r3,0(r1)                /* Zero the stack frame pointer */
        bl      .start_secondary
+       b       .
 #endif
 
 /*
@@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform)
        mr      r3,r31
        bl      .early_setup
 
-       /* set the ASR */
-       ld      r3,PACASTABREAL(r13)
-       ori     r4,r3,1                 /* turn on valid bit             */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star) */
-       mtasr   r4                      /* set the stab location        */
-99:
-       /* Set SDR1 (hash table pointer) */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       /* Test if bit 0 is set (LPAR bit) */
-       andi.   r3,r3,PLATFORM_LPAR
-       bne     98f                     /* branch if result is !0  */
-       LOADADDR(r6,_SDR1)              /* Only if NOT LPAR */
-       add     r6,r6,r26
-       ld      r6,0(r6)                /* get the value of _SDR1 */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location  */
-98: 
        LOADADDR(r3,.start_here_common)
        SET_REG_TO_CONST(r4, MSR_KERNEL)
        mtspr   SPRN_SRR0,r3
diff --git a/arch/powerpc/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c
new file mode 100644 (file)
index 0000000..3fa6a93
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ *
+ * Based on sparc64 ioctl32.c by:
+ *
+ * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * ppc64 changes:
+ *
+ * Copyright (C) 2000  Ken Aaker (kdaaker@rchland.vnet.ibm.com)
+ * Copyright (C) 2001  Anton Blanchard (antonb@au.ibm.com)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * ioctls.
+ *
+ * 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.
+ */
+
+#define INCLUDES
+#include "compat_ioctl.c"
+#include <linux/syscalls.h>
+
+#define CODE
+#include "compat_ioctl.c"
+
+#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
+#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
+
+#define IOCTL_TABLE_START \
+       struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END \
+       };
+
+IOCTL_TABLE_START
+#include <linux/compat_ioctl.h>
+#define DECLARES
+#include "compat_ioctl.c"
+
+/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+
+IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
new file mode 100644 (file)
index 0000000..4b79406
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ *  arch/ppc/kernel/irq.c
+ *
+ *  Derived from arch/i386/kernel/irq.c
+ *    Copyright (C) 1992 Linus Torvalds
+ *  Adapted from arch/i386 by Gary Thomas
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ *    Copyright (C) 1996-2001 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * 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 file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * The MPC8xx has an interrupt mask in the SIU.  If a bit is set, the
+ * interrupt is _enabled_.  As expected, IRQ0 is bit 0 in the 32-bit
+ * mask register (of which only 16 are defined), hence the weird shifting
+ * and complement of the cached_irq_mask.  I want to be able to stuff
+ * this right into the SIU SMASK register.
+ * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
+ * to reduce code space and undefined function references.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+#include <linux/seq_file.h>
+#include <linux/cpumask.h>
+#include <linux/profile.h>
+#include <linux/bitops.h>
+#ifdef CONFIG_PPC64
+#include <linux/kallsyms.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/cache.h>
+#include <asm/prom.h>
+#include <asm/ptrace.h>
+#include <asm/machdep.h>
+#ifdef CONFIG_PPC64
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/paca.h>
+#endif
+
+static int ppc_spurious_interrupts;
+
+#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
+extern void iSeries_smp_message_recv(struct pt_regs *);
+#endif
+
+#ifdef CONFIG_PPC32
+#define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
+
+unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+atomic_t ppc_n_lost_interrupts;
+
+#ifdef CONFIG_TAU_INT
+extern int tau_initialized;
+extern int tau_interrupts(int);
+#endif
+
+#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
+extern atomic_t ipi_recv;
+extern atomic_t ipi_sent;
+#endif
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(irq_desc);
+
+int distribute_irqs = 1;
+int __irq_offset_value;
+u64 ppc64_interrupt_controller;
+#endif /* CONFIG_PPC64 */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+       int i = *(loff_t *)v, j;
+       struct irqaction *action;
+       irq_desc_t *desc;
+       unsigned long flags;
+
+       if (i == 0) {
+               seq_puts(p, "           ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "CPU%d       ", j);
+               seq_putc(p, '\n');
+       }
+
+       if (i < NR_IRQS) {
+               desc = get_irq_desc(i);
+               spin_lock_irqsave(&desc->lock, flags);
+               action = desc->action;
+               if (!action || !action->handler)
+                       goto skip;
+               seq_printf(p, "%3d: ", i);
+#ifdef CONFIG_SMP
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#else
+               seq_printf(p, "%10u ", kstat_irqs(i));
+#endif /* CONFIG_SMP */
+               if (desc->handler)
+                       seq_printf(p, " %s ", desc->handler->typename);
+               else
+                       seq_puts(p, "  None      ");
+               seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
+               seq_printf(p, "    %s", action->name);
+               for (action = action->next; action; action = action->next)
+                       seq_printf(p, ", %s", action->name);
+               seq_putc(p, '\n');
+skip:
+               spin_unlock_irqrestore(&desc->lock, flags);
+       } else if (i == NR_IRQS) {
+#ifdef CONFIG_PPC32
+#ifdef CONFIG_TAU_INT
+               if (tau_initialized){
+                       seq_puts(p, "TAU: ");
+                       for (j = 0; j < NR_CPUS; j++)
+                               if (cpu_online(j))
+                                       seq_printf(p, "%10u ", tau_interrupts(j));
+                       seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
+               }
+#endif
+#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
+               /* should this be per processor send/receive? */
+               seq_printf(p, "IPI (recv/sent): %10u/%u\n",
+                               atomic_read(&ipi_recv), atomic_read(&ipi_sent));
+#endif
+#endif /* CONFIG_PPC32 */
+               seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void fixup_irqs(cpumask_t map)
+{
+       unsigned int irq;
+       static int warned;
+
+       for_each_irq(irq) {
+               cpumask_t mask;
+
+               if (irq_desc[irq].status & IRQ_PER_CPU)
+                       continue;
+
+               cpus_and(mask, irq_affinity[irq], map);
+               if (any_online_cpu(mask) == NR_CPUS) {
+                       printk("Breaking affinity for irq %i\n", irq);
+                       mask = map;
+               }
+               if (irq_desc[irq].handler->set_affinity)
+                       irq_desc[irq].handler->set_affinity(irq, mask);
+               else if (irq_desc[irq].action && !(warned++))
+                       printk("Cannot set affinity for irq %i\n", irq);
+       }
+
+       local_irq_enable();
+       mdelay(1);
+       local_irq_disable();
+}
+#endif
+
+#ifdef CONFIG_PPC_ISERIES
+void do_IRQ(struct pt_regs *regs)
+{
+       struct paca_struct *lpaca;
+
+       irq_enter();
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       /* Debugging check for stack overflow: is there less than 2KB free? */
+       {
+               long sp;
+
+               sp = __get_SP() & (THREAD_SIZE-1);
+
+               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
+                       printk("do_IRQ: stack overflow: %ld\n",
+                               sp - sizeof(struct thread_info));
+                       dump_stack();
+               }
+       }
+#endif
+
+       lpaca = get_paca();
+#ifdef CONFIG_SMP
+       if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
+               lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
+               iSeries_smp_message_recv(regs);
+       }
+#endif /* CONFIG_SMP */
+       if (hvlpevent_is_pending())
+               process_hvlpevents(regs);
+
+       irq_exit();
+
+       if (lpaca->lppaca.int_dword.fields.decr_int) {
+               lpaca->lppaca.int_dword.fields.decr_int = 0;
+               /* Signal a fake decrementer interrupt */
+               timer_interrupt(regs);
+       }
+}
+
+#else  /* CONFIG_PPC_ISERIES */
+
+void do_IRQ(struct pt_regs *regs)
+{
+       int irq;
+#ifdef CONFIG_IRQSTACKS
+       struct thread_info *curtp, *irqtp;
+#endif
+
+        irq_enter();
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       /* Debugging check for stack overflow: is there less than 2KB free? */
+       {
+               long sp;
+
+               sp = __get_SP() & (THREAD_SIZE-1);
+
+               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
+                       printk("do_IRQ: stack overflow: %ld\n",
+                               sp - sizeof(struct thread_info));
+                       dump_stack();
+               }
+       }
+#endif
+
+       /*
+        * Every platform is required to implement ppc_md.get_irq.
+        * This function will either return an irq number or -1 to
+        * indicate there are no more pending.
+        * The value -2 is for buggy hardware and means that this IRQ
+        * has already been handled. -- Tom
+        */
+       irq = ppc_md.get_irq(regs);
+
+       if (irq >= 0) {
+#ifdef CONFIG_IRQSTACKS
+               /* Switch to the irq stack to handle this */
+               curtp = current_thread_info();
+               irqtp = hardirq_ctx[smp_processor_id()];
+               if (curtp != irqtp) {
+                       irqtp->task = curtp->task;
+                       irqtp->flags = 0;
+                       call___do_IRQ(irq, regs, irqtp);
+                       irqtp->task = NULL;
+                       if (irqtp->flags)
+                               set_bits(irqtp->flags, &curtp->flags);
+               } else
+#endif
+                       __do_IRQ(irq, regs);
+       } else
+#ifdef CONFIG_PPC32
+               if (irq != -2)
+#endif
+                       /* That's not SMP safe ... but who cares ? */
+                       ppc_spurious_interrupts++;
+        irq_exit();
+}
+
+#endif /* CONFIG_PPC_ISERIES */
+
+void __init init_IRQ(void)
+{
+#ifdef CONFIG_PPC64
+       static int once = 0;
+
+       if (once)
+               return;
+
+       once++;
+
+#endif
+       ppc_md.init_IRQ();
+#ifdef CONFIG_PPC64
+       irq_ctx_init();
+#endif
+}
+
+#ifdef CONFIG_PPC64
+#ifndef CONFIG_PPC_ISERIES
+/*
+ * Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
+ */
+
+#define UNDEFINED_IRQ 0xffffffff
+unsigned int virt_irq_to_real_map[NR_IRQS];
+
+/*
+ * Don't use virtual irqs 0, 1, 2 for devices.
+ * The pcnet32 driver considers interrupt numbers < 2 to be invalid,
+ * and 2 is the XICS IPI interrupt.
+ * We limit virtual irqs to 17 less than NR_IRQS so that when we
+ * offset them by 16 (to reserve the first 16 for ISA interrupts)
+ * we don't end up with an interrupt number >= NR_IRQS.
+ */
+#define MIN_VIRT_IRQ   3
+#define MAX_VIRT_IRQ   (NR_IRQS - NUM_ISA_INTERRUPTS - 1)
+#define NR_VIRT_IRQS   (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1)
+
+void
+virt_irq_init(void)
+{
+       int i;
+       for (i = 0; i < NR_IRQS; i++)
+               virt_irq_to_real_map[i] = UNDEFINED_IRQ;
+}
+
+/* Create a mapping for a real_irq if it doesn't already exist.
+ * Return the virtual irq as a convenience.
+ */
+int virt_irq_create_mapping(unsigned int real_irq)
+{
+       unsigned int virq, first_virq;
+       static int warned;
+
+       if (ppc64_interrupt_controller == IC_OPEN_PIC)
+               return real_irq;        /* no mapping for openpic (for now) */
+
+       if (ppc64_interrupt_controller == IC_CELL_PIC)
+               return real_irq;        /* no mapping for iic either */
+
+       /* don't map interrupts < MIN_VIRT_IRQ */
+       if (real_irq < MIN_VIRT_IRQ) {
+               virt_irq_to_real_map[real_irq] = real_irq;
+               return real_irq;
+       }
+
+       /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */
+       virq = real_irq;
+       if (virq > MAX_VIRT_IRQ)
+               virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
+
+       /* search for this number or a free slot */
+       first_virq = virq;
+       while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) {
+               if (virt_irq_to_real_map[virq] == real_irq)
+                       return virq;
+               if (++virq > MAX_VIRT_IRQ)
+                       virq = MIN_VIRT_IRQ;
+               if (virq == first_virq)
+                       goto nospace;   /* oops, no free slots */
+       }
+
+       virt_irq_to_real_map[virq] = real_irq;
+       return virq;
+
+ nospace:
+       if (!warned) {
+               printk(KERN_CRIT "Interrupt table is full\n");
+               printk(KERN_CRIT "Increase NR_IRQS (currently %d) "
+                      "in your kernel sources and rebuild.\n", NR_IRQS);
+               warned = 1;
+       }
+       return NO_IRQ;
+}
+
+/*
+ * In most cases will get a hit on the very first slot checked in the
+ * virt_irq_to_real_map.  Only when there are a large number of
+ * IRQs will this be expensive.
+ */
+unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
+{
+       unsigned int virq;
+       unsigned int first_virq;
+
+       virq = real_irq;
+
+       if (virq > MAX_VIRT_IRQ)
+               virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
+
+       first_virq = virq;
+
+       do {
+               if (virt_irq_to_real_map[virq] == real_irq)
+                       return virq;
+
+               virq++;
+
+               if (virq >= MAX_VIRT_IRQ)
+                       virq = 0;
+
+       } while (first_virq != virq);
+
+       return NO_IRQ;
+
+}
+
+#endif /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_IRQSTACKS
+struct thread_info *softirq_ctx[NR_CPUS];
+struct thread_info *hardirq_ctx[NR_CPUS];
+
+void irq_ctx_init(void)
+{
+       struct thread_info *tp;
+       int i;
+
+       for_each_cpu(i) {
+               memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
+               tp = softirq_ctx[i];
+               tp->cpu = i;
+               tp->preempt_count = SOFTIRQ_OFFSET;
+
+               memset((void *)hardirq_ctx[i], 0, THREAD_SIZE);
+               tp = hardirq_ctx[i];
+               tp->cpu = i;
+               tp->preempt_count = HARDIRQ_OFFSET;
+       }
+}
+
+void do_softirq(void)
+{
+       unsigned long flags;
+       struct thread_info *curtp, *irqtp;
+
+       if (in_interrupt())
+               return;
+
+       local_irq_save(flags);
+
+       if (local_softirq_pending()) {
+               curtp = current_thread_info();
+               irqtp = softirq_ctx[smp_processor_id()];
+               irqtp->task = curtp->task;
+               call_do_softirq(irqtp);
+               irqtp->task = NULL;
+       }
+
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(do_softirq);
+
+#endif /* CONFIG_IRQSTACKS */
+
+static int __init setup_noirqdistrib(char *str)
+{
+       distribute_irqs = 0;
+       return 1;
+}
+
+__setup("noirqdistrib", setup_noirqdistrib);
+#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
new file mode 100644 (file)
index 0000000..5e954fa
--- /dev/null
@@ -0,0 +1,612 @@
+/*
+ * PowerPC64 LPAR Configuration Information Driver
+ *
+ * Dave Engebretsen engebret@us.ibm.com
+ *    Copyright (c) 2003 Dave Engebretsen
+ * Will Schmidt willschm@us.ibm.com
+ *    SPLPAR updates, Copyright (c) 2003 Will Schmidt IBM Corporation.
+ *    seq_file updates, Copyright (c) 2004 Will Schmidt IBM Corporation.
+ * Nathan Lynch nathanl@austin.ibm.com
+ *    Added lparcfg_write, Copyright (C) 2004 Nathan Lynch IBM Corporation.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ * This driver creates a proc file at /proc/ppc64/lparcfg which contains
+ * keyword - value pairs that specify the configuration of the partition.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/lppaca.h>
+#include <asm/hvcall.h>
+#include <asm/firmware.h>
+#include <asm/rtas.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
+#include <asm/prom.h>
+#include <asm/systemcfg.h>
+
+#define MODULE_VERS "1.6"
+#define MODULE_NAME "lparcfg"
+
+/* #define LPARCFG_DEBUG */
+
+/* find a better place for this function... */
+void log_plpar_hcall_return(unsigned long rc, char *tag)
+{
+       if (rc == 0)            /* success, return */
+               return;
+/* check for null tag ? */
+       if (rc == H_Hardware)
+               printk(KERN_INFO
+                      "plpar-hcall (%s) failed with hardware fault\n", tag);
+       else if (rc == H_Function)
+               printk(KERN_INFO
+                      "plpar-hcall (%s) failed; function not allowed\n", tag);
+       else if (rc == H_Authority)
+               printk(KERN_INFO
+                      "plpar-hcall (%s) failed; not authorized to this function\n",
+                      tag);
+       else if (rc == H_Parameter)
+               printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
+                      tag);
+       else
+               printk(KERN_INFO
+                      "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
+                      tag, rc);
+
+}
+
+static struct proc_dir_entry *proc_ppc64_lparcfg;
+#define LPARCFG_BUFF_SIZE 4096
+
+#ifdef CONFIG_PPC_ISERIES
+
+/*
+ * For iSeries legacy systems, the PPA purr function is available from the
+ * emulated_time_base field in the paca.
+ */
+static unsigned long get_purr(void)
+{
+       unsigned long sum_purr = 0;
+       int cpu;
+       struct paca_struct *lpaca;
+
+       for_each_cpu(cpu) {
+               lpaca = paca + cpu;
+               sum_purr += lpaca->lppaca.emulated_time_base;
+
+#ifdef PURR_DEBUG
+               printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
+                       cpu, lpaca->lppaca.emulated_time_base);
+#endif
+       }
+       return sum_purr;
+}
+
+#define lparcfg_write NULL
+
+/*
+ * Methods used to fetch LPAR data when running on an iSeries platform.
+ */
+static int lparcfg_data(struct seq_file *m, void *v)
+{
+       unsigned long pool_id, lp_index;
+       int shared, entitled_capacity, max_entitled_capacity;
+       int processors, max_processors;
+       struct paca_struct *lpaca = get_paca();
+       unsigned long purr = get_purr();
+
+       seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+
+       shared = (int)(lpaca->lppaca_ptr->shared_proc);
+       seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
+                  e2a(xItExtVpdPanel.mfgID[2]),
+                  e2a(xItExtVpdPanel.mfgID[3]),
+                  e2a(xItExtVpdPanel.systemSerial[1]),
+                  e2a(xItExtVpdPanel.systemSerial[2]),
+                  e2a(xItExtVpdPanel.systemSerial[3]),
+                  e2a(xItExtVpdPanel.systemSerial[4]),
+                  e2a(xItExtVpdPanel.systemSerial[5]));
+
+       seq_printf(m, "system_type=%c%c%c%c\n",
+                  e2a(xItExtVpdPanel.machineType[0]),
+                  e2a(xItExtVpdPanel.machineType[1]),
+                  e2a(xItExtVpdPanel.machineType[2]),
+                  e2a(xItExtVpdPanel.machineType[3]));
+
+       lp_index = HvLpConfig_getLpIndex();
+       seq_printf(m, "partition_id=%d\n", (int)lp_index);
+
+       seq_printf(m, "system_active_processors=%d\n",
+                  (int)HvLpConfig_getSystemPhysicalProcessors());
+
+       seq_printf(m, "system_potential_processors=%d\n",
+                  (int)HvLpConfig_getSystemPhysicalProcessors());
+
+       processors = (int)HvLpConfig_getPhysicalProcessors();
+       seq_printf(m, "partition_active_processors=%d\n", processors);
+
+       max_processors = (int)HvLpConfig_getMaxPhysicalProcessors();
+       seq_printf(m, "partition_potential_processors=%d\n", max_processors);
+
+       if (shared) {
+               entitled_capacity = HvLpConfig_getSharedProcUnits();
+               max_entitled_capacity = HvLpConfig_getMaxSharedProcUnits();
+       } else {
+               entitled_capacity = processors * 100;
+               max_entitled_capacity = max_processors * 100;
+       }
+       seq_printf(m, "partition_entitled_capacity=%d\n", entitled_capacity);
+
+       seq_printf(m, "partition_max_entitled_capacity=%d\n",
+                  max_entitled_capacity);
+
+       if (shared) {
+               pool_id = HvLpConfig_getSharedPoolIndex();
+               seq_printf(m, "pool=%d\n", (int)pool_id);
+               seq_printf(m, "pool_capacity=%d\n",
+                          (int)(HvLpConfig_getNumProcsInSharedPool(pool_id) *
+                                100));
+               seq_printf(m, "purr=%ld\n", purr);
+       }
+
+       seq_printf(m, "shared_processor_mode=%d\n", shared);
+
+       return 0;
+}
+#endif                         /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Methods used to fetch LPAR data when running on a pSeries platform.
+ */
+
+/*
+ * H_GET_PPP hcall returns info in 4 parms.
+ *  entitled_capacity,unallocated_capacity,
+ *  aggregation, resource_capability).
+ *
+ *  R4 = Entitled Processor Capacity Percentage.
+ *  R5 = Unallocated Processor Capacity Percentage.
+ *  R6 (AABBCCDDEEFFGGHH).
+ *      XXXX - reserved (0)
+ *          XXXX - reserved (0)
+ *              XXXX - Group Number
+ *                  XXXX - Pool Number.
+ *  R7 (IIJJKKLLMMNNOOPP).
+ *      XX - reserved. (0)
+ *        XX - bit 0-6 reserved (0).   bit 7 is Capped indicator.
+ *          XX - variable processor Capacity Weight
+ *            XX - Unallocated Variable Processor Capacity Weight.
+ *              XXXX - Active processors in Physical Processor Pool.
+ *                  XXXX  - Processors active on platform.
+ */
+static unsigned int h_get_ppp(unsigned long *entitled,
+                             unsigned long *unallocated,
+                             unsigned long *aggregation,
+                             unsigned long *resource)
+{
+       unsigned long rc;
+       rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated,
+                             aggregation, resource);
+
+       log_plpar_hcall_return(rc, "H_GET_PPP");
+
+       return rc;
+}
+
+static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
+{
+       unsigned long rc;
+       unsigned long dummy;
+       rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy);
+
+       log_plpar_hcall_return(rc, "H_PIC");
+}
+
+static unsigned long get_purr(void);
+
+/* Track sum of all purrs across all processors. This is used to further */
+/* calculate usage values by different applications                       */
+
+static unsigned long get_purr(void)
+{
+       unsigned long sum_purr = 0;
+       int cpu;
+       struct cpu_usage *cu;
+
+       for_each_cpu(cpu) {
+               cu = &per_cpu(cpu_usage_array, cpu);
+               sum_purr += cu->current_tb;
+       }
+       return sum_purr;
+}
+
+#define SPLPAR_CHARACTERISTICS_TOKEN 20
+#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
+
+/*
+ * parse_system_parameter_string()
+ * Retrieve the potential_processors, max_entitled_capacity and friends
+ * through the get-system-parameter rtas call.  Replace keyword strings as
+ * necessary.
+ */
+static void parse_system_parameter_string(struct seq_file *m)
+{
+       int call_status;
+
+       char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
+       if (!local_buffer) {
+               printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+                      __FILE__, __FUNCTION__, __LINE__);
+               return;
+       }
+
+       spin_lock(&rtas_data_buf_lock);
+       memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
+       call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+                               NULL,
+                               SPLPAR_CHARACTERISTICS_TOKEN,
+                               __pa(rtas_data_buf));
+       memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
+       spin_unlock(&rtas_data_buf_lock);
+
+       if (call_status != 0) {
+               printk(KERN_INFO
+                      "%s %s Error calling get-system-parameter (0x%x)\n",
+                      __FILE__, __FUNCTION__, call_status);
+       } else {
+               int splpar_strlen;
+               int idx, w_idx;
+               char *workbuffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
+               if (!workbuffer) {
+                       printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+                              __FILE__, __FUNCTION__, __LINE__);
+                       kfree(local_buffer);
+                       return;
+               }
+#ifdef LPARCFG_DEBUG
+               printk(KERN_INFO "success calling get-system-parameter \n");
+#endif
+               splpar_strlen = local_buffer[0] * 16 + local_buffer[1];
+               local_buffer += 2;      /* step over strlen value */
+
+               memset(workbuffer, 0, SPLPAR_MAXLENGTH);
+               w_idx = 0;
+               idx = 0;
+               while ((*local_buffer) && (idx < splpar_strlen)) {
+                       workbuffer[w_idx++] = local_buffer[idx++];
+                       if ((local_buffer[idx] == ',')
+                           || (local_buffer[idx] == '\0')) {
+                               workbuffer[w_idx] = '\0';
+                               if (w_idx) {
+                                       /* avoid the empty string */
+                                       seq_printf(m, "%s\n", workbuffer);
+                               }
+                               memset(workbuffer, 0, SPLPAR_MAXLENGTH);
+                               idx++;  /* skip the comma */
+                               w_idx = 0;
+                       } else if (local_buffer[idx] == '=') {
+                               /* code here to replace workbuffer contents
+                                  with different keyword strings */
+                               if (0 == strcmp(workbuffer, "MaxEntCap")) {
+                                       strcpy(workbuffer,
+                                              "partition_max_entitled_capacity");
+                                       w_idx = strlen(workbuffer);
+                               }
+                               if (0 == strcmp(workbuffer, "MaxPlatProcs")) {
+                                       strcpy(workbuffer,
+                                              "system_potential_processors");
+                                       w_idx = strlen(workbuffer);
+                               }
+                       }
+               }
+               kfree(workbuffer);
+               local_buffer -= 2;      /* back up over strlen value */
+       }
+       kfree(local_buffer);
+}
+
+static int lparcfg_count_active_processors(void);
+
+/* Return the number of processors in the system.
+ * This function reads through the device tree and counts
+ * the virtual processors, this does not include threads.
+ */
+static int lparcfg_count_active_processors(void)
+{
+       struct device_node *cpus_dn = NULL;
+       int count = 0;
+
+       while ((cpus_dn = of_find_node_by_type(cpus_dn, "cpu"))) {
+#ifdef LPARCFG_DEBUG
+               printk(KERN_ERR "cpus_dn %p \n", cpus_dn);
+#endif
+               count++;
+       }
+       return count;
+}
+
+static int lparcfg_data(struct seq_file *m, void *v)
+{
+       int partition_potential_processors;
+       int partition_active_processors;
+       struct device_node *rootdn;
+       const char *model = "";
+       const char *system_id = "";
+       unsigned int *lp_index_ptr, lp_index = 0;
+       struct device_node *rtas_node;
+       int *lrdrp;
+
+       rootdn = find_path_device("/");
+       if (rootdn) {
+               model = get_property(rootdn, "model", NULL);
+               system_id = get_property(rootdn, "system-id", NULL);
+               lp_index_ptr = (unsigned int *)
+                   get_property(rootdn, "ibm,partition-no", NULL);
+               if (lp_index_ptr)
+                       lp_index = *lp_index_ptr;
+       }
+
+       seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+
+       seq_printf(m, "serial_number=%s\n", system_id);
+
+       seq_printf(m, "system_type=%s\n", model);
+
+       seq_printf(m, "partition_id=%d\n", (int)lp_index);
+
+       rtas_node = find_path_device("/rtas");
+       lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
+
+       if (lrdrp == NULL) {
+               partition_potential_processors = _systemcfg->processorCount;
+       } else {
+               partition_potential_processors = *(lrdrp + 4);
+       }
+
+       partition_active_processors = lparcfg_count_active_processors();
+
+       if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+               unsigned long h_entitled, h_unallocated;
+               unsigned long h_aggregation, h_resource;
+               unsigned long pool_idle_time, pool_procs;
+               unsigned long purr;
+
+               h_get_ppp(&h_entitled, &h_unallocated, &h_aggregation,
+                         &h_resource);
+
+               seq_printf(m, "R4=0x%lx\n", h_entitled);
+               seq_printf(m, "R5=0x%lx\n", h_unallocated);
+               seq_printf(m, "R6=0x%lx\n", h_aggregation);
+               seq_printf(m, "R7=0x%lx\n", h_resource);
+
+               purr = get_purr();
+
+               /* this call handles the ibm,get-system-parameter contents */
+               parse_system_parameter_string(m);
+
+               seq_printf(m, "partition_entitled_capacity=%ld\n", h_entitled);
+
+               seq_printf(m, "group=%ld\n", (h_aggregation >> 2 * 8) & 0xffff);
+
+               seq_printf(m, "system_active_processors=%ld\n",
+                          (h_resource >> 0 * 8) & 0xffff);
+
+               /* pool related entries are apropriate for shared configs */
+               if (paca[0].lppaca.shared_proc) {
+
+                       h_pic(&pool_idle_time, &pool_procs);
+
+                       seq_printf(m, "pool=%ld\n",
+                                  (h_aggregation >> 0 * 8) & 0xffff);
+
+                       /* report pool_capacity in percentage */
+                       seq_printf(m, "pool_capacity=%ld\n",
+                                  ((h_resource >> 2 * 8) & 0xffff) * 100);
+
+                       seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
+
+                       seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
+               }
+
+               seq_printf(m, "unallocated_capacity_weight=%ld\n",
+                          (h_resource >> 4 * 8) & 0xFF);
+
+               seq_printf(m, "capacity_weight=%ld\n",
+                          (h_resource >> 5 * 8) & 0xFF);
+
+               seq_printf(m, "capped=%ld\n", (h_resource >> 6 * 8) & 0x01);
+
+               seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated);
+
+               seq_printf(m, "purr=%ld\n", purr);
+
+       } else {                /* non SPLPAR case */
+
+               seq_printf(m, "system_active_processors=%d\n",
+                          partition_potential_processors);
+
+               seq_printf(m, "system_potential_processors=%d\n",
+                          partition_potential_processors);
+
+               seq_printf(m, "partition_max_entitled_capacity=%d\n",
+                          partition_potential_processors * 100);
+
+               seq_printf(m, "partition_entitled_capacity=%d\n",
+                          partition_active_processors * 100);
+       }
+
+       seq_printf(m, "partition_active_processors=%d\n",
+                  partition_active_processors);
+
+       seq_printf(m, "partition_potential_processors=%d\n",
+                  partition_potential_processors);
+
+       seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc);
+
+       return 0;
+}
+
+/*
+ * Interface for changing system parameters (variable capacity weight
+ * and entitled capacity).  Format of input is "param_name=value";
+ * anything after value is ignored.  Valid parameters at this time are
+ * "partition_entitled_capacity" and "capacity_weight".  We use
+ * H_SET_PPP to alter parameters.
+ *
+ * This function should be invoked only on systems with
+ * FW_FEATURE_SPLPAR.
+ */
+static ssize_t lparcfg_write(struct file *file, const char __user * buf,
+                            size_t count, loff_t * off)
+{
+       char *kbuf;
+       char *tmp;
+       u64 new_entitled, *new_entitled_ptr = &new_entitled;
+       u8 new_weight, *new_weight_ptr = &new_weight;
+
+       unsigned long current_entitled; /* parameters for h_get_ppp */
+       unsigned long dummy;
+       unsigned long resource;
+       u8 current_weight;
+
+       ssize_t retval = -ENOMEM;
+
+       kbuf = kmalloc(count, GFP_KERNEL);
+       if (!kbuf)
+               goto out;
+
+       retval = -EFAULT;
+       if (copy_from_user(kbuf, buf, count))
+               goto out;
+
+       retval = -EINVAL;
+       kbuf[count - 1] = '\0';
+       tmp = strchr(kbuf, '=');
+       if (!tmp)
+               goto out;
+
+       *tmp++ = '\0';
+
+       if (!strcmp(kbuf, "partition_entitled_capacity")) {
+               char *endp;
+               *new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
+               if (endp == tmp)
+                       goto out;
+               new_weight_ptr = &current_weight;
+       } else if (!strcmp(kbuf, "capacity_weight")) {
+               char *endp;
+               *new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
+               if (endp == tmp)
+                       goto out;
+               new_entitled_ptr = &current_entitled;
+       } else
+               goto out;
+
+       /* Get our current parameters */
+       retval = h_get_ppp(&current_entitled, &dummy, &dummy, &resource);
+       if (retval) {
+               retval = -EIO;
+               goto out;
+       }
+
+       current_weight = (resource >> 5 * 8) & 0xFF;
+
+       pr_debug("%s: current_entitled = %lu, current_weight = %lu\n",
+                __FUNCTION__, current_entitled, current_weight);
+
+       pr_debug("%s: new_entitled = %lu, new_weight = %lu\n",
+                __FUNCTION__, *new_entitled_ptr, *new_weight_ptr);
+
+       retval = plpar_hcall_norets(H_SET_PPP, *new_entitled_ptr,
+                                   *new_weight_ptr);
+
+       if (retval == H_Success || retval == H_Constrained) {
+               retval = count;
+       } else if (retval == H_Busy) {
+               retval = -EBUSY;
+       } else if (retval == H_Hardware) {
+               retval = -EIO;
+       } else if (retval == H_Parameter) {
+               retval = -EINVAL;
+       } else {
+               printk(KERN_WARNING "%s: received unknown hv return code %ld",
+                      __FUNCTION__, retval);
+               retval = -EIO;
+       }
+
+      out:
+       kfree(kbuf);
+       return retval;
+}
+
+#endif                         /* CONFIG_PPC_PSERIES */
+
+static int lparcfg_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, lparcfg_data, NULL);
+}
+
+struct file_operations lparcfg_fops = {
+      .owner   = THIS_MODULE,
+      .read    = seq_read,
+      .open    = lparcfg_open,
+      .release = single_release,
+};
+
+int __init lparcfg_init(void)
+{
+       struct proc_dir_entry *ent;
+       mode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
+
+       /* Allow writing if we have FW_FEATURE_SPLPAR */
+       if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+               lparcfg_fops.write = lparcfg_write;
+               mode |= S_IWUSR;
+       }
+
+       ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
+       if (ent) {
+               ent->proc_fops = &lparcfg_fops;
+               ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL);
+               if (!ent->data) {
+                       printk(KERN_ERR
+                              "Failed to allocate buffer for lparcfg\n");
+                       remove_proc_entry("lparcfg", ent->parent);
+                       return -ENOMEM;
+               }
+       } else {
+               printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
+               return -EIO;
+       }
+
+       proc_ppc64_lparcfg = ent;
+       return 0;
+}
+
+void __exit lparcfg_cleanup(void)
+{
+       if (proc_ppc64_lparcfg) {
+               kfree(proc_ppc64_lparcfg->data);
+               remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
+       }
+}
+
+module_init(lparcfg_init);
+module_exit(lparcfg_cleanup);
+MODULE_DESCRIPTION("Interface for LPAR configuration data");
+MODULE_AUTHOR("Dave Engebretsen");
+MODULE_LICENSE("GPL");
index 3bedb532aed92c271c6cdd6b1698071d3ed5e30e..f6d84a75ed266bbc2042da47f0c887f59796604b 100644 (file)
@@ -519,7 +519,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  *
  * flush_icache_range(unsigned long start, unsigned long stop)
  */
-_GLOBAL(flush_icache_range)
+_GLOBAL(__flush_icache_range)
 BEGIN_FTR_SECTION
        blr                             /* for 601, do nothing */
 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
@@ -607,27 +607,6 @@ _GLOBAL(invalidate_dcache_range)
        sync                            /* wait for dcbi's to get to ram */
        blr
 
-#ifdef CONFIG_NOT_COHERENT_CACHE
-/*
- * 40x cores have 8K or 16K dcache and 32 byte line size.
- * 44x has a 32K dcache and 32 byte line size.
- * 8xx has 1, 2, 4, 8K variants.
- * For now, cover the worst case of the 44x.
- * Must be called with external interrupts disabled.
- */
-#define CACHE_NWAYS    64
-#define CACHE_NLINES   16
-
-_GLOBAL(flush_dcache_all)
-       li      r4, (2 * CACHE_NWAYS * CACHE_NLINES)
-       mtctr   r4
-       lis     r5, KERNELBASE@h
-1:     lwz     r3, 0(r5)               /* Load one word from every line */
-       addi    r5, r5, L1_CACHE_BYTES
-       bdnz    1b
-       blr
-#endif /* CONFIG_NOT_COHERENT_CACHE */
-
 /*
  * Flush a particular page from the data cache to RAM.
  * Note: this is necessary because the instruction cache does *not*
index ae1433da09b27ea4cd76f0013616a35d38560855..ae48a002f81ad1bf94f54b411b7d1e27356a44d2 100644 (file)
@@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq)
        mtlr    r0
        blr
 
-_GLOBAL(call_handle_IRQ_event)
+_GLOBAL(call___do_IRQ)
        mflr    r0
        std     r0,16(r1)
-       stdu    r1,THREAD_SIZE-112(r6)
-       mr      r1,r6
-       bl      .handle_IRQ_event
+       stdu    r1,THREAD_SIZE-112(r5)
+       mr      r1,r5
+       bl      .__do_IRQ
        ld      r1,0(r1)
        ld      r0,16(r1)
        mtlr    r0
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
new file mode 100644 (file)
index 0000000..3cf2517
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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/config.h>
+#include <linux/types.h>
+#include <linux/threads.h>
+#include <linux/module.h>
+
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/systemcfg.h>
+#include <asm/lppaca.h>
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/paca.h>
+
+static union {
+       struct systemcfg        data;
+       u8                      page[PAGE_SIZE];
+} systemcfg_store __attribute__((__section__(".data.page.aligned")));
+struct systemcfg *_systemcfg = &systemcfg_store.data;
+
+
+/* This symbol is provided by the linker - let it fill in the paca
+ * field correctly */
+extern unsigned long __toc_start;
+
+/* The Paca is an array with one entry per processor.  Each contains an
+ * lppaca, which contains the information shared between the
+ * hypervisor and Linux.  Each also contains an ItLpRegSave area which
+ * is used by the hypervisor to save registers.
+ * On systems with hardware multi-threading, there are two threads
+ * per processor.  The Paca array must contain an entry for each thread.
+ * The VPD Areas will give a max logical processors = 2 * max physical
+ * processors.  The processor VPD array needs one entry per physical
+ * processor (not thread).
+ */
+#define PACA_INIT_COMMON(number, start, asrr, asrv)                        \
+       .lock_token = 0x8000,                                               \
+       .paca_index = (number),         /* Paca Index */                    \
+       .default_decr = 0x00ff0000,     /* Initial Decr */                  \
+       .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,             \
+       .stab_real = (asrr),            /* Real pointer to segment table */ \
+       .stab_addr = (asrv),            /* Virt pointer to segment table */ \
+       .cpu_start = (start),           /* Processor start */               \
+       .hw_cpu_id = 0xffff,                                                \
+       .lppaca = {                                                         \
+               .desc = 0xd397d781,     /* "LpPa" */                        \
+               .size = sizeof(struct lppaca),                              \
+               .dyn_proc_status = 2,                                       \
+               .decr_val = 0x00ff0000,                                     \
+               .fpregs_in_use = 1,                                         \
+               .end_of_quantum = 0xfffffffffffffffful,                     \
+               .slb_count = 64,                                            \
+               .vmxregs_in_use = 0,                                        \
+       },                                                                  \
+
+#ifdef CONFIG_PPC_ISERIES
+#define PACA_INIT_ISERIES(number)                                          \
+       .lppaca_ptr = &paca[number].lppaca,                                 \
+       .reg_save_ptr = &paca[number].reg_save,                             \
+       .reg_save = {                                                       \
+               .xDesc = 0xd397d9e2,    /* "LpRS" */                        \
+               .xSize = sizeof(struct ItLpRegSave)                         \
+       }
+
+#define PACA_INIT(number)                                                  \
+{                                                                          \
+       PACA_INIT_COMMON(number, 0, 0, 0)                                   \
+       PACA_INIT_ISERIES(number)                                           \
+}
+
+#define BOOTCPU_PACA_INIT(number)                                          \
+{                                                                          \
+       PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab)                  \
+       PACA_INIT_ISERIES(number)                                           \
+}
+
+#else
+#define PACA_INIT(number)                                                  \
+{                                                                          \
+       PACA_INIT_COMMON(number, 0, 0, 0)                                   \
+}
+
+#define BOOTCPU_PACA_INIT(number)                                          \
+{                                                                          \
+       PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab)    \
+}
+#endif
+
+struct paca_struct paca[] = {
+       BOOTCPU_PACA_INIT(0),
+#if NR_CPUS > 1
+       PACA_INIT(  1), PACA_INIT(  2), PACA_INIT(  3),
+#if NR_CPUS > 4
+       PACA_INIT(  4), PACA_INIT(  5), PACA_INIT(  6), PACA_INIT(  7),
+#if NR_CPUS > 8
+       PACA_INIT(  8), PACA_INIT(  9), PACA_INIT( 10), PACA_INIT( 11),
+       PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15),
+       PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19),
+       PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23),
+       PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27),
+       PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31),
+#if NR_CPUS > 32
+       PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35),
+       PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39),
+       PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43),
+       PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47),
+       PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51),
+       PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55),
+       PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59),
+       PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63),
+#if NR_CPUS > 64
+       PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67),
+       PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71),
+       PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75),
+       PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79),
+       PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83),
+       PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87),
+       PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91),
+       PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95),
+       PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99),
+       PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103),
+       PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107),
+       PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111),
+       PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115),
+       PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119),
+       PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123),
+       PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127),
+#endif
+#endif
+#endif
+#endif
+#endif
+};
+EXPORT_SYMBOL(paca);
index 47d6f7e2ea9faab8887beb46e69dc2e317b1b758..5dcf4ba05ee8aa25922e444f070b264fc861e422 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/cputable.h>
 #include <asm/btext.h>
 #include <asm/div64.h>
+#include <asm/signal.h>
 
 #ifdef  CONFIG_8xx
 #include <asm/commproc.h>
@@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
 extern void alignment_exception(struct pt_regs *regs);
 extern void program_check_exception(struct pt_regs *regs);
 extern void single_step_exception(struct pt_regs *regs);
-extern int do_signal(sigset_t *, struct pt_regs *);
 extern int pmac_newworld;
 extern int sys_sigreturn(struct pt_regs *regs);
 
@@ -188,9 +188,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
 EXPORT_SYMBOL(cuda_request);
 EXPORT_SYMBOL(cuda_poll);
 #endif /* CONFIG_ADB_CUDA */
-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
-EXPORT_SYMBOL(_machine);
-#endif
 #ifdef CONFIG_PPC_PMAC
 EXPORT_SYMBOL(sys_ctrler);
 #endif
diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
new file mode 100644 (file)
index 0000000..a1c1950
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+
+#include <asm/systemcfg.h>
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+
+static loff_t  page_map_seek( struct file *file, loff_t off, int whence);
+static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
+                             loff_t *ppos);
+static int     page_map_mmap( struct file *file, struct vm_area_struct *vma );
+
+static struct file_operations page_map_fops = {
+       .llseek = page_map_seek,
+       .read   = page_map_read,
+       .mmap   = page_map_mmap
+};
+
+/*
+ * Create the ppc64 and ppc64/rtas directories early. This allows us to
+ * assume that they have been previously created in drivers.
+ */
+static int __init proc_ppc64_create(void)
+{
+       struct proc_dir_entry *root;
+
+       root = proc_mkdir("ppc64", NULL);
+       if (!root)
+               return 1;
+
+       if (!(platform_is_pseries() || _machine == PLATFORM_CELL))
+               return 0;
+
+       if (!proc_mkdir("rtas", root))
+               return 1;
+
+       if (!proc_symlink("rtas", NULL, "ppc64/rtas"))
+               return 1;
+
+       return 0;
+}
+core_initcall(proc_ppc64_create);
+
+static int __init proc_ppc64_init(void)
+{
+       struct proc_dir_entry *pde;
+
+       pde = create_proc_entry("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL);
+       if (!pde)
+               return 1;
+       pde->nlink = 1;
+       pde->data = _systemcfg;
+       pde->size = PAGE_SIZE;
+       pde->proc_fops = &page_map_fops;
+
+       return 0;
+}
+__initcall(proc_ppc64_init);
+
+static loff_t page_map_seek( struct file *file, loff_t off, int whence)
+{
+       loff_t new;
+       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+
+       switch(whence) {
+       case 0:
+               new = off;
+               break;
+       case 1:
+               new = file->f_pos + off;
+               break;
+       case 2:
+               new = dp->size + off;
+               break;
+       default:
+               return -EINVAL;
+       }
+       if ( new < 0 || new > dp->size )
+               return -EINVAL;
+       return (file->f_pos = new);
+}
+
+static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
+                             loff_t *ppos)
+{
+       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+       return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
+}
+
+static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
+{
+       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+
+       vma->vm_flags |= VM_SHM | VM_LOCKED;
+
+       if ((vma->vm_end - vma->vm_start) > dp->size)
+               return -EINVAL;
+
+       remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
+                                               dp->size, vma->vm_page_prot);
+       return 0;
+}
+
index f645adb57534be04a39a2ed7718362b06359e812..6a5b468edb4d2e8021d6fc07807e3a4a6cb8fbb6 100644 (file)
@@ -48,9 +48,6 @@
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
 #include <asm/pci-bridge.h>
-#ifdef CONFIG_PPC64
-#include <asm/systemcfg.h>
-#endif
 
 #ifdef DEBUG
 #define DBG(fmt...) printk(KERN_ERR fmt)
@@ -74,10 +71,6 @@ struct isa_reg_property {
 typedef int interpret_func(struct device_node *, unsigned long *,
                           int, int, int);
 
-extern struct rtas_t rtas;
-extern struct lmb lmb;
-extern unsigned long klimit;
-
 static int __initdata dt_root_addr_cells;
 static int __initdata dt_root_size_cells;
 
@@ -391,7 +384,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
 
 #ifdef CONFIG_PPC64
                /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
-               if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
+               if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
                        char *name = get_property(ic->parent, "name", NULL);
                        if (name && !strcmp(name, "u3"))
                                np->intrs[intrcount].line += 128;
@@ -1087,9 +1080,9 @@ void __init unflatten_device_tree(void)
 static int __init early_init_dt_scan_cpus(unsigned long node,
                                          const char *uname, int depth, void *data)
 {
-       char *type = of_get_flat_dt_prop(node, "device_type", NULL);
        u32 *prop;
-       unsigned long size = 0;
+       unsigned long size;
+       char *type = of_get_flat_dt_prop(node, "device_type", &size);
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
@@ -1115,7 +1108,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 
 #ifdef CONFIG_ALTIVEC
        /* Check if we have a VMX and eventually update CPU features */
-       prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", &size);
+       prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
        if (prop && (*prop) > 0) {
                cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
                cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
@@ -1161,13 +1154,9 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
        prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
        if (prop == NULL)
                return 0;
-#ifdef CONFIG_PPC64
-       systemcfg->platform = *prop;
-#else
 #ifdef CONFIG_PPC_MULTIPLATFORM
        _machine = *prop;
 #endif
-#endif
 
 #ifdef CONFIG_PPC64
        /* check if iommu is forced on or off */
@@ -1264,7 +1253,14 @@ static int __init early_init_dt_scan_memory(unsigned long node,
        unsigned long l;
 
        /* We are scanning "memory" nodes only */
-       if (type == NULL || strcmp(type, "memory") != 0)
+       if (type == NULL) {
+               /*
+                * The longtrail doesn't have a device_type on the
+                * /memory node, so look for the node called /memory@0.
+                */
+               if (depth != 1 || strcmp(uname, "memory@0") != 0)
+                       return 0;
+       } else if (strcmp(type, "memory") != 0)
                return 0;
 
        reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
@@ -1339,9 +1335,6 @@ void __init early_init_devtree(void *params)
        of_scan_flat_dt(early_init_dt_scan_memory, NULL);
        lmb_enforce_memory_limit(memory_limit);
        lmb_analyze();
-#ifdef CONFIG_PPC64
-       systemcfg->physicalMemorySize = lmb_phys_mem_size();
-#endif
        lmb_reserve(0, __pa(klimit));
 
        DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
@@ -1908,7 +1901,7 @@ static int of_finish_dynamic_node(struct device_node *node,
        /* We don't support that function on PowerMac, at least
         * not yet
         */
-       if (systemcfg->platform == PLATFORM_POWERMAC)
+       if (_machine == PLATFORM_POWERMAC)
                return -ENODEV;
 
        /* fix up new node's linux_phandle field */
@@ -1992,9 +1985,11 @@ int prom_add_property(struct device_node* np, struct property* prop)
        *next = prop;
        write_unlock(&devtree_lock);
 
+#ifdef CONFIG_PROC_DEVICETREE
        /* try to add to proc as well if it was initialized */
        if (np->pde)
                proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
 
        return 0;
 }
index 6dc33d19fc2abcfcf1c6ce3726c5cbf4adcf49a6..4ce0105c308ea04b7be7fd88524b4c8b25fdef73 100644 (file)
@@ -94,11 +94,17 @@ extern const struct linux_logo logo_linux_clut224;
 #ifdef CONFIG_PPC64
 #define RELOC(x)        (*PTRRELOC(&(x)))
 #define ADDR(x)                (u32) add_reloc_offset((unsigned long)(x))
+#define OF_WORKAROUNDS 0
 #else
 #define RELOC(x)       (x)
 #define ADDR(x)                (u32) (x)
+#define OF_WORKAROUNDS of_workarounds
+int of_workarounds;
 #endif
 
+#define OF_WA_CLAIM    1       /* do phys/virt claim separately, then map */
+#define OF_WA_LONGTRAIL        2       /* work around longtrail bugs */
+
 #define PROM_BUG() do {                                                \
         prom_printf("kernel BUG at %s line 0x%x!\n",           \
                    RELOC(__FILE__), __LINE__);                 \
@@ -111,11 +117,6 @@ extern const struct linux_logo logo_linux_clut224;
 #define prom_debug(x...)
 #endif
 
-#ifdef CONFIG_PPC32
-#define PLATFORM_POWERMAC      _MACH_Pmac
-#define PLATFORM_CHRP          _MACH_chrp
-#endif
-
 
 typedef u32 prom_arg_t;
 
@@ -128,10 +129,11 @@ struct prom_args {
 
 struct prom_t {
        ihandle root;
-       ihandle chosen;
+       phandle chosen;
        int cpu;
        ihandle stdout;
        ihandle mmumap;
+       ihandle memory;
 };
 
 struct mem_map_entry {
@@ -360,16 +362,36 @@ static void __init prom_printf(const char *format, ...)
 static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
                                unsigned long align)
 {
-       int ret;
        struct prom_t *_prom = &RELOC(prom);
 
-       ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
-                       (prom_arg_t)align);
-       if (ret != -1 && _prom->mmumap != 0)
-               /* old pmacs need us to map as well */
+       if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
+               /*
+                * Old OF requires we claim physical and virtual separately
+                * and then map explicitly (assuming virtual mode)
+                */
+               int ret;
+               prom_arg_t result;
+
+               ret = call_prom_ret("call-method", 5, 2, &result,
+                                   ADDR("claim"), _prom->memory,
+                                   align, size, virt);
+               if (ret != 0 || result == -1)
+                       return -1;
+               ret = call_prom_ret("call-method", 5, 2, &result,
+                                   ADDR("claim"), _prom->mmumap,
+                                   align, size, virt);
+               if (ret != 0) {
+                       call_prom("call-method", 4, 1, ADDR("release"),
+                                 _prom->memory, size, virt);
+                       return -1;
+               }
+               /* the 0x12 is M (coherence) + PP == read/write */
                call_prom("call-method", 6, 1,
-                         ADDR("map"), _prom->mmumap, 0, size, virt, virt);
-       return ret;
+                         ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
+               return virt;
+       }
+       return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
+                        (prom_arg_t)align);
 }
 
 static void __init __attribute__((noreturn)) prom_panic(const char *reason)
@@ -415,11 +437,52 @@ static int inline prom_getproplen(phandle node, const char *pname)
        return call_prom("getproplen", 2, 1, node, ADDR(pname));
 }
 
-static int inline prom_setprop(phandle node, const char *pname,
-                              void *value, size_t valuelen)
+static void add_string(char **str, const char *q)
 {
-       return call_prom("setprop", 4, 1, node, ADDR(pname),
-                        (u32)(unsigned long) value, (u32) valuelen);
+       char *p = *str;
+
+       while (*q)
+               *p++ = *q++;
+       *p++ = ' ';
+       *str = p;
+}
+
+static char *tohex(unsigned int x)
+{
+       static char digits[] = "0123456789abcdef";
+       static char result[9];
+       int i;
+
+       result[8] = 0;
+       i = 8;
+       do {
+               --i;
+               result[i] = digits[x & 0xf];
+               x >>= 4;
+       } while (x != 0 && i > 0);
+       return &result[i];
+}
+
+static int __init prom_setprop(phandle node, const char *nodename,
+                              const char *pname, void *value, size_t valuelen)
+{
+       char cmd[256], *p;
+
+       if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
+               return call_prom("setprop", 4, 1, node, ADDR(pname),
+                                (u32)(unsigned long) value, (u32) valuelen);
+
+       /* gah... setprop doesn't work on longtrail, have to use interpret */
+       p = cmd;
+       add_string(&p, "dev");
+       add_string(&p, nodename);
+       add_string(&p, tohex((u32)(unsigned long) value));
+       add_string(&p, tohex(valuelen));
+       add_string(&p, tohex(ADDR(pname)));
+       add_string(&p, tohex(strlen(RELOC(pname))));
+       add_string(&p, "property");
+       *p = 0;
+       return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
 }
 
 /* We can't use the standard versions because of RELOC headaches. */
@@ -980,7 +1043,7 @@ static void __init prom_instantiate_rtas(void)
 
        rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
        if (!IHANDLE_VALID(rtas_inst)) {
-               prom_printf("opening rtas package failed");
+               prom_printf("opening rtas package failed (%x)\n", rtas_inst);
                return;
        }
 
@@ -988,7 +1051,7 @@ static void __init prom_instantiate_rtas(void)
 
        if (call_prom_ret("call-method", 3, 2, &entry,
                          ADDR("instantiate-rtas"),
-                         rtas_inst, base) == PROM_ERROR
+                         rtas_inst, base) != 0
            || entry == 0) {
                prom_printf(" failed\n");
                return;
@@ -997,8 +1060,10 @@ static void __init prom_instantiate_rtas(void)
 
        reserve_mem(base, size);
 
-       prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
-       prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
+       prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
+                    &base, sizeof(base));
+       prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
+                    &entry, sizeof(entry));
 
        prom_debug("rtas base     = 0x%x\n", base);
        prom_debug("rtas entry    = 0x%x\n", entry);
@@ -1089,10 +1154,6 @@ static void __init prom_initialize_tce_table(void)
                if (base < local_alloc_bottom)
                        local_alloc_bottom = base;
 
-               /* Save away the TCE table attributes for later use. */
-               prom_setprop(node, "linux,tce-base", &base, sizeof(base));
-               prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
-
                /* It seems OF doesn't null-terminate the path :-( */
                memset(path, 0, sizeof(path));
                /* Call OF to setup the TCE hardware */
@@ -1101,6 +1162,10 @@ static void __init prom_initialize_tce_table(void)
                        prom_printf("package-to-path failed\n");
                }
 
+               /* Save away the TCE table attributes for later use. */
+               prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
+               prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
+
                prom_debug("TCE table: %s\n", path);
                prom_debug("\tnode = 0x%x\n", node);
                prom_debug("\tbase = 0x%x\n", base);
@@ -1342,6 +1407,7 @@ static void __init prom_init_client_services(unsigned long pp)
 /*
  * For really old powermacs, we need to map things we claim.
  * For that, we need the ihandle of the mmu.
+ * Also, on the longtrail, we need to work around other bugs.
  */
 static void __init prom_find_mmu(void)
 {
@@ -1355,12 +1421,19 @@ static void __init prom_find_mmu(void)
        if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
                return;
        version[sizeof(version) - 1] = 0;
-       prom_printf("OF version is '%s'\n", version);
        /* XXX might need to add other versions here */
-       if (strcmp(version, "Open Firmware, 1.0.5") != 0)
+       if (strcmp(version, "Open Firmware, 1.0.5") == 0)
+               of_workarounds = OF_WA_CLAIM;
+       else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
+               of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
+               call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
+       } else
                return;
+       _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
        prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
                     sizeof(_prom->mmumap));
+       if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
+               of_workarounds &= ~OF_WA_CLAIM;         /* hmmm */
 }
 #else
 #define prom_find_mmu()
@@ -1382,16 +1455,17 @@ static void __init prom_init_stdout(void)
        memset(path, 0, 256);
        call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
        val = call_prom("instance-to-package", 1, 1, _prom->stdout);
-       prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
+       prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
+                    &val, sizeof(val));
        prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
-       prom_setprop(_prom->chosen, "linux,stdout-path",
-                    RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
+       prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
+                    path, strlen(path) + 1);
 
        /* If it's a display, note it */
        memset(type, 0, sizeof(type));
        prom_getprop(val, "device_type", type, sizeof(type));
        if (strcmp(type, RELOC("display")) == 0)
-               prom_setprop(val, "linux,boot-display", NULL, 0);
+               prom_setprop(val, path, "linux,boot-display", NULL, 0);
 }
 
 static void __init prom_close_stdin(void)
@@ -1514,7 +1588,7 @@ static void __init prom_check_displays(void)
 
                /* Success */
                prom_printf("done\n");
-               prom_setprop(node, "linux,opened", NULL, 0);
+               prom_setprop(node, path, "linux,opened", NULL, 0);
 
                /* Setup a usable color table when the appropriate
                 * method is available. Should update this to set-colors */
@@ -1884,9 +1958,11 @@ static void __init fixup_device_tree(void)
        /* interrupt on this revision of u3 is number 0 and level */
        interrupts[0] = 0;
        interrupts[1] = 1;
-       prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
+       prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
+                    &interrupts, sizeof(interrupts));
        parent = (u32)mpic;
-       prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
+       prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
+                    &parent, sizeof(parent));
 #endif
 }
 
@@ -1922,11 +1998,11 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
                RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
 
                val = RELOC(prom_initrd_start);
-               prom_setprop(_prom->chosen, "linux,initrd-start", &val,
-                            sizeof(val));
+               prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
+                            &val, sizeof(val));
                val = RELOC(prom_initrd_end);
-               prom_setprop(_prom->chosen, "linux,initrd-end", &val,
-                            sizeof(val));
+               prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
+                            &val, sizeof(val));
 
                reserve_mem(RELOC(prom_initrd_start),
                            RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
@@ -1969,14 +2045,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        prom_init_client_services(pp);
 
        /*
-        * Init prom stdout device
+        * See if this OF is old enough that we need to do explicit maps
+        * and other workarounds
         */
-       prom_init_stdout();
+       prom_find_mmu();
 
        /*
-        * See if this OF is old enough that we need to do explicit maps
+        * Init prom stdout device
         */
-       prom_find_mmu();
+       prom_init_stdout();
 
        /*
         * Check for an initrd
@@ -1989,14 +2066,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        RELOC(of_platform) = prom_find_machine_type();
        getprop_rval = RELOC(of_platform);
-       prom_setprop(_prom->chosen, "linux,platform",
+       prom_setprop(_prom->chosen, "/chosen", "linux,platform",
                     &getprop_rval, sizeof(getprop_rval));
 
 #ifdef CONFIG_PPC_PSERIES
        /*
         * On pSeries, inform the firmware about our capabilities
         */
-       if (RELOC(of_platform) & PLATFORM_PSERIES)
+       if (RELOC(of_platform) == PLATFORM_PSERIES ||
+           RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
                prom_send_capabilities();
 #endif
 
@@ -2050,21 +2128,23 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         * Fill in some infos for use by the kernel later on
         */
        if (RELOC(prom_memory_limit))
-               prom_setprop(_prom->chosen, "linux,memory-limit",
+               prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
                             &RELOC(prom_memory_limit),
                             sizeof(prom_memory_limit));
 #ifdef CONFIG_PPC64
        if (RELOC(ppc64_iommu_off))
-               prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
+               prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
+                            NULL, 0);
 
        if (RELOC(iommu_force_on))
-               prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
+               prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
+                            NULL, 0);
 
        if (RELOC(prom_tce_alloc_start)) {
-               prom_setprop(_prom->chosen, "linux,tce-alloc-start",
+               prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
                             &RELOC(prom_tce_alloc_start),
                             sizeof(prom_tce_alloc_start));
-               prom_setprop(_prom->chosen, "linux,tce-alloc-end",
+               prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
                             &RELOC(prom_tce_alloc_end),
                             sizeof(prom_tce_alloc_end));
        }
@@ -2081,8 +2161,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        prom_printf("copying OF device tree ...\n");
        flatten_device_tree();
 
-       /* in case stdin is USB and still active on IBM machines... */
-       prom_close_stdin();
+       /*
+        * in case stdin is USB and still active on IBM machines...
+        * Unfortunately quiesce crashes on some powermacs if we have
+        * closed stdin already (in particular the powerbook 101).
+        */
+       if (RELOC(of_platform) != PLATFORM_POWERMAC)
+               prom_close_stdin();
 
        /*
         * Call OF "quiesce" method to shut down pending DMA's from
index 5bdd5b079d966359a0be76a8ff928abc0069a5f6..ae1a36449ccdd0b9e8039b1d8b73b8f92695988f 100644 (file)
@@ -259,7 +259,7 @@ static int __init proc_rtas_init(void)
 {
        struct proc_dir_entry *entry;
 
-       if (!(systemcfg->platform & PLATFORM_PSERIES))
+       if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR)
                return 1;
 
        rtas_node = of_find_node_by_name(NULL, "rtas");
index 9d4e07f6f1ecb5e061fa6619df534fde1491cef3..4283fa33f784f930a09c9f3cb993f519bd35de67 100644 (file)
@@ -29,9 +29,6 @@
 #include <asm/delay.h>
 #include <asm/uaccess.h>
 #include <asm/lmb.h>
-#ifdef CONFIG_PPC64
-#include <asm/systemcfg.h>
-#endif
 
 struct rtas_t rtas = {
        .lock = SPIN_LOCK_UNLOCKED
@@ -671,7 +668,7 @@ void __init rtas_initialize(void)
         * the stop-self token if any
         */
 #ifdef CONFIG_PPC64
-       if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+       if (_machine == PLATFORM_PSERIES_LPAR)
                rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
 #endif
        rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
new file mode 100644 (file)
index 0000000..0e5a8e1
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * arch/ppc64/kernel/rtas_pci.c
+ *
+ * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * RTAS specific routines for PCI.
+ *
+ * Based on code from pci.c, chrp_pci.c and pSeries_pci.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.
+ *
+ * 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/kernel.h>
+#include <linux/threads.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/rtas.h>
+#include <asm/mpic.h>
+#include <asm/ppc-pci.h>
+
+/* RTAS tokens */
+static int read_pci_config;
+static int write_pci_config;
+static int ibm_read_pci_config;
+static int ibm_write_pci_config;
+
+static inline int config_access_valid(struct pci_dn *dn, int where)
+{
+       if (where < 256)
+               return 1;
+       if (where < 4096 && dn->pci_ext_config_space)
+               return 1;
+
+       return 0;
+}
+
+static int of_device_available(struct device_node * dn)
+{
+        char * status;
+
+        status = get_property(dn, "status", NULL);
+
+        if (!status)
+                return 1;
+
+        if (!strcmp(status, "okay"))
+                return 1;
+
+        return 0;
+}
+
+static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+{
+       int returnval = -1;
+       unsigned long buid, addr;
+       int ret;
+
+       if (!pdn)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (!config_access_valid(pdn, where))
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+
+       addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+               (pdn->devfn << 8) | (where & 0xff);
+       buid = pdn->phb->buid;
+       if (buid) {
+               ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
+                               addr, BUID_HI(buid), BUID_LO(buid), size);
+       } else {
+               ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
+       }
+       *val = returnval;
+
+       if (ret)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (returnval == EEH_IO_ERROR_VALUE(size) &&
+           eeh_dn_check_failure (pdn->node, NULL))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int rtas_pci_read_config(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where, int size, u32 *val)
+{
+       struct device_node *busdn, *dn;
+
+       if (bus->self)
+               busdn = pci_device_to_OF_node(bus->self);
+       else
+               busdn = bus->sysdata;   /* must be a phb */
+
+       /* Search only direct children of the bus */
+       for (dn = busdn->child; dn; dn = dn->sibling) {
+               struct pci_dn *pdn = PCI_DN(dn);
+               if (pdn && pdn->devfn == devfn
+                   && of_device_available(dn))
+                       return rtas_read_config(pdn, where, size, val);
+       }
+
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
+{
+       unsigned long buid, addr;
+       int ret;
+
+       if (!pdn)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (!config_access_valid(pdn, where))
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+
+       addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+               (pdn->devfn << 8) | (where & 0xff);
+       buid = pdn->phb->buid;
+       if (buid) {
+               ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
+                       BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
+       } else {
+               ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
+       }
+
+       if (ret)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int rtas_pci_write_config(struct pci_bus *bus,
+                                unsigned int devfn,
+                                int where, int size, u32 val)
+{
+       struct device_node *busdn, *dn;
+
+       if (bus->self)
+               busdn = pci_device_to_OF_node(bus->self);
+       else
+               busdn = bus->sysdata;   /* must be a phb */
+
+       /* Search only direct children of the bus */
+       for (dn = busdn->child; dn; dn = dn->sibling) {
+               struct pci_dn *pdn = PCI_DN(dn);
+               if (pdn && pdn->devfn == devfn
+                   && of_device_available(dn))
+                       return rtas_write_config(pdn, where, size, val);
+       }
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+struct pci_ops rtas_pci_ops = {
+       rtas_pci_read_config,
+       rtas_pci_write_config
+};
+
+int is_python(struct device_node *dev)
+{
+       char *model = (char *)get_property(dev, "model", NULL);
+
+       if (model && strstr(model, "Python"))
+               return 1;
+
+       return 0;
+}
+
+static int get_phb_reg_prop(struct device_node *dev,
+                           unsigned int addr_size_words,
+                           struct reg_property64 *reg)
+{
+       unsigned int *ui_ptr = NULL, len;
+
+       /* Found a PHB, now figure out where his registers are mapped. */
+       ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
+       if (ui_ptr == NULL)
+               return 1;
+
+       if (addr_size_words == 1) {
+               reg->address = ((struct reg_property32 *)ui_ptr)->address;
+               reg->size    = ((struct reg_property32 *)ui_ptr)->size;
+       } else {
+               *reg = *((struct reg_property64 *)ui_ptr);
+       }
+
+       return 0;
+}
+
+static void python_countermeasures(struct device_node *dev,
+                                  unsigned int addr_size_words)
+{
+       struct reg_property64 reg_struct;
+       void __iomem *chip_regs;
+       volatile u32 val;
+
+       if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
+               return;
+
+       /* Python's register file is 1 MB in size. */
+       chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
+
+       /*
+        * Firmware doesn't always clear this bit which is critical
+        * for good performance - Anton
+        */
+
+#define PRG_CL_RESET_VALID 0x00010000
+
+       val = in_be32(chip_regs + 0xf6030);
+       if (val & PRG_CL_RESET_VALID) {
+               printk(KERN_INFO "Python workaround: ");
+               val &= ~PRG_CL_RESET_VALID;
+               out_be32(chip_regs + 0xf6030, val);
+               /*
+                * We must read it back for changes to
+                * take effect
+                */
+               val = in_be32(chip_regs + 0xf6030);
+               printk("reg0: %x\n", val);
+       }
+
+       iounmap(chip_regs);
+}
+
+void __init init_pci_config_tokens (void)
+{
+       read_pci_config = rtas_token("read-pci-config");
+       write_pci_config = rtas_token("write-pci-config");
+       ibm_read_pci_config = rtas_token("ibm,read-pci-config");
+       ibm_write_pci_config = rtas_token("ibm,write-pci-config");
+}
+
+unsigned long __devinit get_phb_buid (struct device_node *phb)
+{
+       int addr_cells;
+       unsigned int *buid_vals;
+       unsigned int len;
+       unsigned long buid;
+
+       if (ibm_read_pci_config == -1) return 0;
+
+       /* PHB's will always be children of the root node,
+        * or so it is promised by the current firmware. */
+       if (phb->parent == NULL)
+               return 0;
+       if (phb->parent->parent)
+               return 0;
+
+       buid_vals = (unsigned int *) get_property(phb, "reg", &len);
+       if (buid_vals == NULL)
+               return 0;
+
+       addr_cells = prom_n_addr_cells(phb);
+       if (addr_cells == 1) {
+               buid = (unsigned long) buid_vals[0];
+       } else {
+               buid = (((unsigned long)buid_vals[0]) << 32UL) |
+                       (((unsigned long)buid_vals[1]) & 0xffffffff);
+       }
+       return buid;
+}
+
+static int phb_set_bus_ranges(struct device_node *dev,
+                             struct pci_controller *phb)
+{
+       int *bus_range;
+       unsigned int len;
+
+       bus_range = (int *) get_property(dev, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               return 1;
+       }
+
+       phb->first_busno =  bus_range[0];
+       phb->last_busno  =  bus_range[1];
+
+       return 0;
+}
+
+static int __devinit setup_phb(struct device_node *dev,
+                              struct pci_controller *phb,
+                              unsigned int addr_size_words)
+{
+       pci_setup_pci_controller(phb);
+
+       if (is_python(dev))
+               python_countermeasures(dev, addr_size_words);
+
+       if (phb_set_bus_ranges(dev, phb))
+               return 1;
+
+       phb->arch_data = dev;
+       phb->ops = &rtas_pci_ops;
+       phb->buid = get_phb_buid(dev);
+
+       return 0;
+}
+
+static void __devinit add_linux_pci_domain(struct device_node *dev,
+                                          struct pci_controller *phb,
+                                          struct property *of_prop)
+{
+       memset(of_prop, 0, sizeof(struct property));
+       of_prop->name = "linux,pci-domain";
+       of_prop->length = sizeof(phb->global_number);
+       of_prop->value = (unsigned char *)&of_prop[1];
+       memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
+       prom_add_property(dev, of_prop);
+}
+
+static struct pci_controller * __init alloc_phb(struct device_node *dev,
+                                               unsigned int addr_size_words)
+{
+       struct pci_controller *phb;
+       struct property *of_prop;
+
+       phb = alloc_bootmem(sizeof(struct pci_controller));
+       if (phb == NULL)
+               return NULL;
+
+       of_prop = alloc_bootmem(sizeof(struct property) +
+                               sizeof(phb->global_number));
+       if (!of_prop)
+               return NULL;
+
+       if (setup_phb(dev, phb, addr_size_words))
+               return NULL;
+
+       add_linux_pci_domain(dev, phb, of_prop);
+
+       return phb;
+}
+
+static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
+{
+       struct pci_controller *phb;
+
+       phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
+                                              GFP_KERNEL);
+       if (phb == NULL)
+               return NULL;
+
+       if (setup_phb(dev, phb, addr_size_words))
+               return NULL;
+
+       phb->is_dynamic = 1;
+
+       /* TODO: linux,pci-domain? */
+
+       return phb;
+}
+
+unsigned long __init find_and_init_phbs(void)
+{
+       struct device_node *node;
+       struct pci_controller *phb;
+       unsigned int root_size_cells = 0;
+       unsigned int index;
+       unsigned int *opprop = NULL;
+       struct device_node *root = of_find_node_by_path("/");
+
+       if (ppc64_interrupt_controller == IC_OPEN_PIC) {
+               opprop = (unsigned int *)get_property(root,
+                               "platform-open-pic", NULL);
+       }
+
+       root_size_cells = prom_n_size_cells(root);
+
+       index = 0;
+
+       for (node = of_get_next_child(root, NULL);
+            node != NULL;
+            node = of_get_next_child(root, node)) {
+               if (node->type == NULL || strcmp(node->type, "pci") != 0)
+                       continue;
+
+               phb = alloc_phb(node, root_size_cells);
+               if (!phb)
+                       continue;
+
+               pci_process_bridge_OF_ranges(phb, node, 0);
+               pci_setup_phb_io(phb, index == 0);
+#ifdef CONFIG_PPC_PSERIES
+               if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
+                       int addr = root_size_cells * (index + 2) - 1;
+                       mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
+               }
+#endif
+               index++;
+       }
+
+       of_node_put(root);
+       pci_devs_phb_init();
+
+       /*
+        * pci_probe_only and pci_assign_all_buses can be set via properties
+        * in chosen.
+        */
+       if (of_chosen) {
+               int *prop;
+
+               prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
+                                          NULL);
+               if (prop)
+                       pci_probe_only = *prop;
+
+               prop = (int *)get_property(of_chosen,
+                                          "linux,pci-assign-all-buses", NULL);
+               if (prop)
+                       pci_assign_all_buses = *prop;
+       }
+
+       return 0;
+}
+
+struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
+{
+       struct device_node *root = of_find_node_by_path("/");
+       unsigned int root_size_cells = 0;
+       struct pci_controller *phb;
+       int primary;
+
+       root_size_cells = prom_n_size_cells(root);
+
+       primary = list_empty(&hose_list);
+       phb = alloc_phb_dynamic(dn, root_size_cells);
+       if (!phb)
+               return NULL;
+
+       pci_process_bridge_OF_ranges(phb, dn, primary);
+
+       pci_setup_phb_io_dynamic(phb, primary);
+       of_node_put(root);
+
+       pci_devs_phb_init_dynamic(phb);
+       scan_phb(phb);
+
+       return phb;
+}
+EXPORT_SYMBOL(init_phb_dynamic);
+
+/* RPA-specific bits for removing PHBs */
+int pcibios_remove_root_bus(struct pci_controller *phb)
+{
+       struct pci_bus *b = phb->bus;
+       struct resource *res;
+       int rc, i;
+
+       res = b->resource[0];
+       if (!res->flags) {
+               printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
+                               b->name);
+               return 1;
+       }
+
+       rc = unmap_bus_range(b);
+       if (rc) {
+               printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
+                       __FUNCTION__, b->name);
+               return 1;
+       }
+
+       if (release_resource(res)) {
+               printk(KERN_ERR "%s: failed to release IO on bus %s\n",
+                               __FUNCTION__, b->name);
+               return 1;
+       }
+
+       for (i = 1; i < 3; ++i) {
+               res = b->resource[i];
+               if (!res->flags && i == 0) {
+                       printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
+                               __FUNCTION__, b->name);
+                       return 1;
+               }
+               if (res->flags && release_resource(res)) {
+                       printk(KERN_ERR
+                              "%s: failed to release IO %d on bus %s\n",
+                               __FUNCTION__, i, b->name);
+                       return 1;
+               }
+       }
+
+       list_del(&phb->list_node);
+       if (phb->is_dynamic)
+               kfree(phb);
+
+       return 0;
+}
+EXPORT_SYMBOL(pcibios_remove_root_bus);
index e22856ecb5a0396f1000cae57289a24107a168dd..bae4bff138f1ebe3e1fdb02924026713b0399b80 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
+#include <asm/systemcfg.h>
 #include <asm/pgtable.h>
 #include <asm/smp.h>
 #include <asm/elf.h>
@@ -51,6 +52,9 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/lmb.h>
+#include <asm/xmon.h>
+
+#include "setup.h"
 
 #undef DEBUG
 
 #define DBG(fmt...)
 #endif
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
+int _machine = 0;
+EXPORT_SYMBOL(_machine);
+#endif
+
+unsigned long klimit = (unsigned long) _end;
+
 /*
  * This still seems to be needed... -- paulus
  */ 
@@ -510,8 +521,8 @@ void __init smp_setup_cpu_maps(void)
         * On pSeries LPAR, we need to know how many cpus
         * could possibly be added to this partition.
         */
-       if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
-                               (dn = of_find_node_by_path("/rtas"))) {
+       if (_machine == PLATFORM_PSERIES_LPAR &&
+           (dn = of_find_node_by_path("/rtas"))) {
                int num_addr_cell, num_size_cell, maxcpus;
                unsigned int *ireg;
 
@@ -555,7 +566,27 @@ void __init smp_setup_cpu_maps(void)
                        cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
        }
 
-       systemcfg->processorCount = num_present_cpus();
+       _systemcfg->processorCount = num_present_cpus();
 #endif /* CONFIG_PPC64 */
 }
 #endif /* CONFIG_SMP */
+
+#ifdef CONFIG_XMON
+static int __init early_xmon(char *p)
+{
+       /* ensure xmon is enabled */
+       if (p) {
+               if (strncmp(p, "on", 2) == 0)
+                       xmon_init(1);
+               if (strncmp(p, "off", 3) == 0)
+                       xmon_init(0);
+               if (strncmp(p, "early", 5) != 0)
+                       return 0;
+       }
+       xmon_init(1);
+       debugger(NULL);
+
+       return 0;
+}
+early_param("xmon", early_xmon);
+#endif
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
new file mode 100644 (file)
index 0000000..2ebba75
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _POWERPC_KERNEL_SETUP_H
+#define _POWERPC_KERNEL_SETUP_H
+
+void check_for_initrd(void);
+
+#endif /* _POWERPC_KERNEL_SETUP_H */
index 3af2631e3fab07f0ce0a4406bd897319a783d6a5..c98cfcc9cd9a9183f5dbe9f3b7fe4c527642ace1 100644 (file)
@@ -40,6 +40,8 @@
 #include <asm/xmon.h>
 #include <asm/time.h>
 
+#include "setup.h"
+
 #define DBG(fmt...)
 
 #if defined CONFIG_KGDB
@@ -70,8 +72,6 @@ unsigned int DMA_MODE_WRITE;
 int have_of = 1;
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-int _machine = 0;
-
 extern void prep_init(void);
 extern void pmac_init(void);
 extern void chrp_init(void);
@@ -279,7 +279,6 @@ arch_initcall(ppc_init);
 /* Warning, IO base is not yet inited */
 void __init setup_arch(char **cmdline_p)
 {
-       extern char *klimit;
        extern void do_init_bootmem(void);
 
        /* so udelay does something sensible, assume <= 1000 bogomips */
@@ -303,14 +302,9 @@ void __init setup_arch(char **cmdline_p)
                pmac_feature_init();    /* New cool way */
 #endif
 
-#ifdef CONFIG_XMON
-       xmon_map_scc();
-       if (strstr(cmd_line, "xmon")) {
-               xmon_init(1);
-               debugger(NULL);
-       }
-#endif /* CONFIG_XMON */
-       if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
+#ifdef CONFIG_XMON_DEFAULT
+       xmon_init(1);
+#endif
 
 #if defined(CONFIG_KGDB)
        if (ppc_md.kgdb_map_scc)
@@ -343,7 +337,7 @@ void __init setup_arch(char **cmdline_p)
        init_mm.start_code = PAGE_OFFSET;
        init_mm.end_code = (unsigned long) _etext;
        init_mm.end_data = (unsigned long) _edata;
-       init_mm.brk = (unsigned long) klimit;
+       init_mm.brk = klimit;
 
        /* Save unparsed command line copy for /proc/cmdline */
        strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
index 0471e843b6c53961f515a6e46a8e594cbc26a946..6791668213e75997ba229544d7b421a5cfe1bc6f 100644 (file)
@@ -61,6 +61,8 @@
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 
+#include "setup.h"
+
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
 #else
@@ -94,15 +96,6 @@ extern void udbg_init_maple_realmode(void);
        do { udbg_putc = call_rtas_display_status_delay; } while(0)
 #endif
 
-/* extern void *stab; */
-extern unsigned long klimit;
-
-extern void mm_init_ppc64(void);
-extern void stab_initialize(unsigned long stab);
-extern void htab_initialize(void);
-extern void early_init_devtree(void *flat_dt);
-extern void unflatten_device_tree(void);
-
 int have_of = 1;
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
@@ -254,11 +247,10 @@ void __init early_setup(unsigned long dt_ptr)
         * Iterate all ppc_md structures until we find the proper
         * one for the current machine type
         */
-       DBG("Probing machine type for platform %x...\n",
-           systemcfg->platform);
+       DBG("Probing machine type for platform %x...\n", _machine);
 
        for (mach = machines; *mach; mach++) {
-               if ((*mach)->probe(systemcfg->platform))
+               if ((*mach)->probe(_machine))
                        break;
        }
        /* What can we do if we didn't find ? */
@@ -290,6 +282,28 @@ void __init early_setup(unsigned long dt_ptr)
        DBG(" <- early_setup()\n");
 }
 
+#ifdef CONFIG_SMP
+void early_setup_secondary(void)
+{
+       struct paca_struct *lpaca = get_paca();
+
+       /* Mark enabled in PACA */
+       lpaca->proc_enabled = 0;
+
+       /* Initialize hash table for that CPU */
+       htab_initialize_secondary();
+
+       /* Initialize STAB/SLB. We use a virtual address as it works
+        * in real mode on pSeries and we want a virutal address on
+        * iSeries anyway
+        */
+       if (cpu_has_feature(CPU_FTR_SLB))
+               slb_initialize();
+       else
+               stab_initialize(lpaca->stab_addr);
+}
+
+#endif /* CONFIG_SMP */
 
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
 void smp_release_cpus(void)
@@ -315,7 +329,8 @@ void smp_release_cpus(void)
 #endif /* CONFIG_SMP || CONFIG_KEXEC */
 
 /*
- * Initialize some remaining members of the ppc64_caches and systemcfg structures
+ * Initialize some remaining members of the ppc64_caches and systemcfg
+ * structures
  * (at least until we get rid of them completely). This is mostly some
  * cache informations about the CPU that will be used by cache flush
  * routines and/or provided to userland
@@ -340,7 +355,7 @@ static void __init initialize_cache_info(void)
                        const char *dc, *ic;
 
                        /* Then read cache informations */
-                       if (systemcfg->platform == PLATFORM_POWERMAC) {
+                       if (_machine == PLATFORM_POWERMAC) {
                                dc = "d-cache-block-size";
                                ic = "i-cache-block-size";
                        } else {
@@ -360,8 +375,8 @@ static void __init initialize_cache_info(void)
                                DBG("Argh, can't find dcache properties ! "
                                    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-                       systemcfg->dcache_size = ppc64_caches.dsize = size;
-                       systemcfg->dcache_line_size =
+                       _systemcfg->dcache_size = ppc64_caches.dsize = size;
+                       _systemcfg->dcache_line_size =
                                ppc64_caches.dline_size = lsize;
                        ppc64_caches.log_dline_size = __ilog2(lsize);
                        ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
@@ -378,8 +393,8 @@ static void __init initialize_cache_info(void)
                                DBG("Argh, can't find icache properties ! "
                                    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-                       systemcfg->icache_size = ppc64_caches.isize = size;
-                       systemcfg->icache_line_size =
+                       _systemcfg->icache_size = ppc64_caches.isize = size;
+                       _systemcfg->icache_line_size =
                                ppc64_caches.iline_size = lsize;
                        ppc64_caches.log_iline_size = __ilog2(lsize);
                        ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
@@ -387,10 +402,12 @@ static void __init initialize_cache_info(void)
        }
 
        /* Add an eye catcher and the systemcfg layout version number */
-       strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
-       systemcfg->version.major = SYSTEMCFG_MAJOR;
-       systemcfg->version.minor = SYSTEMCFG_MINOR;
-       systemcfg->processor = mfspr(SPRN_PVR);
+       strcpy(_systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+       _systemcfg->version.major = SYSTEMCFG_MAJOR;
+       _systemcfg->version.minor = SYSTEMCFG_MINOR;
+       _systemcfg->processor = mfspr(SPRN_PVR);
+       _systemcfg->platform = _machine;
+       _systemcfg->physicalMemorySize = lmb_phys_mem_size();
 
        DBG(" <- initialize_cache_info()\n");
 }
@@ -479,10 +496,10 @@ void __init setup_system(void)
        printk("-----------------------------------------------------\n");
        printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
        printk("ppc64_interrupt_controller    = 0x%ld\n", ppc64_interrupt_controller);
-       printk("systemcfg                     = 0x%p\n", systemcfg);
-       printk("systemcfg->platform           = 0x%x\n", systemcfg->platform);
-       printk("systemcfg->processorCount     = 0x%lx\n", systemcfg->processorCount);
-       printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
+       printk("systemcfg                     = 0x%p\n", _systemcfg);
+       printk("systemcfg->platform           = 0x%x\n", _systemcfg->platform);
+       printk("systemcfg->processorCount     = 0x%lx\n", _systemcfg->processorCount);
+       printk("systemcfg->physicalMemorySize = 0x%lx\n", _systemcfg->physicalMemorySize);
        printk("ppc64_caches.dcache_line_size = 0x%x\n",
                        ppc64_caches.dline_size);
        printk("ppc64_caches.icache_line_size = 0x%x\n",
@@ -564,12 +581,12 @@ void __init setup_syscall_map(void)
        for (i = 0; i < __NR_syscalls; i++) {
                if (sys_call_table[i*2] != sys_ni_syscall) {
                        count64++;
-                       systemcfg->syscall_map_64[i >> 5] |=
+                       _systemcfg->syscall_map_64[i >> 5] |=
                                0x80000000UL >> (i & 0x1f);
                }
                if (sys_call_table[i*2+1] != sys_ni_syscall) {
                        count32++;
-                       systemcfg->syscall_map_32[i >> 5] |=
+                       _systemcfg->syscall_map_32[i >> 5] |=
                                0x80000000UL >> (i & 0x1f);
                }
        }
@@ -858,26 +875,6 @@ int check_legacy_ioport(unsigned long base_port)
 }
 EXPORT_SYMBOL(check_legacy_ioport);
 
-#ifdef CONFIG_XMON
-static int __init early_xmon(char *p)
-{
-       /* ensure xmon is enabled */
-       if (p) {
-               if (strncmp(p, "on", 2) == 0)
-                       xmon_init(1);
-               if (strncmp(p, "off", 3) == 0)
-                       xmon_init(0);
-               if (strncmp(p, "early", 5) != 0)
-                       return 0;
-       }
-       xmon_init(1);
-       debugger(NULL);
-
-       return 0;
-}
-early_param("xmon", early_xmon);
-#endif
-
 void cpu_die(void)
 {
        if (ppc_md.cpu_die)
index 081d931eae481e34671818eab5b21a208cb18012..a7c4515f320fc30b968e70118c6f6bb63db45b95 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/sigcontext.h>
 #ifdef CONFIG_PPC64
 #include "ppc32.h"
 #include <asm/unistd.h>
index 36d67a8d7cbbb1b1d2c798dc0958f4f5d792e756..e28a139c29d04322f34f19ecfd0e419890a236c3 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/cputable.h>
 #include <asm/system.h>
 #include <asm/mpic.h>
+#include <asm/systemcfg.h>
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #endif
@@ -368,9 +369,11 @@ int generic_cpu_disable(void)
        if (cpu == boot_cpuid)
                return -EBUSY;
 
-       systemcfg->processorCount--;
        cpu_clear(cpu, cpu_online_map);
+#ifdef CONFIG_PPC64
+       _systemcfg->processorCount--;
        fixup_irqs(cpu_online_map);
+#endif
        return 0;
 }
 
@@ -388,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
        while (!cpu_online(cpu))
                cpu_relax();
 
+#ifdef CONFIG_PPC64
        fixup_irqs(cpu_online_map);
        /* counter the irq disable in fixup_irqs */
        local_irq_enable();
+#endif
        return 0;
 }
 
@@ -419,7 +424,9 @@ void generic_mach_cpu_die(void)
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
                cpu_relax();
 
+#ifdef CONFIG_PPC64
        flush_tlb_pending();
+#endif
        cpu_set(cpu, cpu_online_map);
        local_irq_enable();
 }
index a8210ed5c686ae0e0771c3b77821fb96a4fdeeb2..9c921d1c4084484b186249eed4ab7daa2e9ce550 100644 (file)
@@ -52,7 +52,6 @@
 #include <asm/semaphore.h>
 #include <asm/time.h>
 #include <asm/mmu_context.h>
-#include <asm/systemcfg.h>
 #include <asm/ppc-pci.h>
 
 /* readdir & getdents */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
new file mode 100644 (file)
index 0000000..850af19
--- /dev/null
@@ -0,0 +1,384 @@
+#include <linux/config.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/cpumask.h>
+#include <linux/notifier.h>
+
+#include <asm/current.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/prom.h>
+#include <asm/systemcfg.h>
+#include <asm/paca.h>
+#include <asm/lppaca.h>
+#include <asm/machdep.h>
+#include <asm/smp.h>
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+/* SMT stuff */
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/* default to snooze disabled */
+DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
+
+static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
+                                     size_t count)
+{
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
+       ssize_t ret;
+       unsigned long snooze;
+
+       ret = sscanf(buf, "%lu", &snooze);
+       if (ret != 1)
+               return -EINVAL;
+
+       per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze;
+
+       return count;
+}
+
+static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf)
+{
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
+
+       return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id));
+}
+
+static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
+                  store_smt_snooze_delay);
+
+/* Only parse OF options if the matching cmdline option was not specified */
+static int smt_snooze_cmdline;
+
+static int __init smt_setup(void)
+{
+       struct device_node *options;
+       unsigned int *val;
+       unsigned int cpu;
+
+       if (!cpu_has_feature(CPU_FTR_SMT))
+               return 1;
+
+       options = find_path_device("/options");
+       if (!options)
+               return 1;
+
+       val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
+                                          NULL);
+       if (!smt_snooze_cmdline && val) {
+               for_each_cpu(cpu)
+                       per_cpu(smt_snooze_delay, cpu) = *val;
+       }
+
+       return 1;
+}
+__initcall(smt_setup);
+
+static int __init setup_smt_snooze_delay(char *str)
+{
+       unsigned int cpu;
+       int snooze;
+
+       if (!cpu_has_feature(CPU_FTR_SMT))
+               return 1;
+
+       smt_snooze_cmdline = 1;
+
+       if (get_option(&str, &snooze)) {
+               for_each_cpu(cpu)
+                       per_cpu(smt_snooze_delay, cpu) = snooze;
+       }
+
+       return 1;
+}
+__setup("smt-snooze-delay=", setup_smt_snooze_delay);
+
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+/*
+ * Enabling PMCs will slow partition context switch times so we only do
+ * it the first time we write to the PMCs.
+ */
+
+static DEFINE_PER_CPU(char, pmcs_enabled);
+
+void ppc64_enable_pmcs(void)
+{
+       /* Only need to enable them once */
+       if (__get_cpu_var(pmcs_enabled))
+               return;
+
+       __get_cpu_var(pmcs_enabled) = 1;
+
+       if (ppc_md.enable_pmcs)
+               ppc_md.enable_pmcs();
+}
+EXPORT_SYMBOL(ppc64_enable_pmcs);
+
+/* XXX convert to rusty's on_one_cpu */
+static unsigned long run_on_cpu(unsigned long cpu,
+                               unsigned long (*func)(unsigned long),
+                               unsigned long arg)
+{
+       cpumask_t old_affinity = current->cpus_allowed;
+       unsigned long ret;
+
+       /* should return -EINVAL to userspace */
+       if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+               return 0;
+
+       ret = func(arg);
+
+       set_cpus_allowed(current, old_affinity);
+
+       return ret;
+}
+
+#define SYSFS_PMCSETUP(NAME, ADDRESS) \
+static unsigned long read_##NAME(unsigned long junk) \
+{ \
+       return mfspr(ADDRESS); \
+} \
+static unsigned long write_##NAME(unsigned long val) \
+{ \
+       ppc64_enable_pmcs(); \
+       mtspr(ADDRESS, val); \
+       return 0; \
+} \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
+       unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
+       return sprintf(buf, "%lx\n", val); \
+} \
+static ssize_t __attribute_used__ \
+       store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
+{ \
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
+       unsigned long val; \
+       int ret = sscanf(buf, "%lx", &val); \
+       if (ret != 1) \
+               return -EINVAL; \
+       run_on_cpu(cpu->sysdev.id, write_##NAME, val); \
+       return count; \
+}
+
+SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0);
+SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1);
+SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
+SYSFS_PMCSETUP(pmc1, SPRN_PMC1);
+SYSFS_PMCSETUP(pmc2, SPRN_PMC2);
+SYSFS_PMCSETUP(pmc3, SPRN_PMC3);
+SYSFS_PMCSETUP(pmc4, SPRN_PMC4);
+SYSFS_PMCSETUP(pmc5, SPRN_PMC5);
+SYSFS_PMCSETUP(pmc6, SPRN_PMC6);
+SYSFS_PMCSETUP(pmc7, SPRN_PMC7);
+SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
+SYSFS_PMCSETUP(purr, SPRN_PURR);
+
+static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0);
+static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1);
+static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
+static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1);
+static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2);
+static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3);
+static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4);
+static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5);
+static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6);
+static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7);
+static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8);
+static SYSDEV_ATTR(purr, 0600, show_purr, NULL);
+
+static void register_cpu_online(unsigned int cpu)
+{
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
+       struct sys_device *s = &c->sysdev;
+
+#ifndef CONFIG_PPC_ISERIES
+       if (cpu_has_feature(CPU_FTR_SMT))
+               sysdev_create_file(s, &attr_smt_snooze_delay);
+#endif
+
+       /* PMC stuff */
+
+       sysdev_create_file(s, &attr_mmcr0);
+       sysdev_create_file(s, &attr_mmcr1);
+
+       if (cpu_has_feature(CPU_FTR_MMCRA))
+               sysdev_create_file(s, &attr_mmcra);
+
+       if (cur_cpu_spec->num_pmcs >= 1)
+               sysdev_create_file(s, &attr_pmc1);
+       if (cur_cpu_spec->num_pmcs >= 2)
+               sysdev_create_file(s, &attr_pmc2);
+       if (cur_cpu_spec->num_pmcs >= 3)
+               sysdev_create_file(s, &attr_pmc3);
+       if (cur_cpu_spec->num_pmcs >= 4)
+               sysdev_create_file(s, &attr_pmc4);
+       if (cur_cpu_spec->num_pmcs >= 5)
+               sysdev_create_file(s, &attr_pmc5);
+       if (cur_cpu_spec->num_pmcs >= 6)
+               sysdev_create_file(s, &attr_pmc6);
+       if (cur_cpu_spec->num_pmcs >= 7)
+               sysdev_create_file(s, &attr_pmc7);
+       if (cur_cpu_spec->num_pmcs >= 8)
+               sysdev_create_file(s, &attr_pmc8);
+
+       if (cpu_has_feature(CPU_FTR_SMT))
+               sysdev_create_file(s, &attr_purr);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_cpu_online(unsigned int cpu)
+{
+       struct cpu *c = &per_cpu(cpu_devices, cpu);
+       struct sys_device *s = &c->sysdev;
+
+       BUG_ON(c->no_control);
+
+#ifndef CONFIG_PPC_ISERIES
+       if (cpu_has_feature(CPU_FTR_SMT))
+               sysdev_remove_file(s, &attr_smt_snooze_delay);
+#endif
+
+       /* PMC stuff */
+
+       sysdev_remove_file(s, &attr_mmcr0);
+       sysdev_remove_file(s, &attr_mmcr1);
+
+       if (cpu_has_feature(CPU_FTR_MMCRA))
+               sysdev_remove_file(s, &attr_mmcra);
+
+       if (cur_cpu_spec->num_pmcs >= 1)
+               sysdev_remove_file(s, &attr_pmc1);
+       if (cur_cpu_spec->num_pmcs >= 2)
+               sysdev_remove_file(s, &attr_pmc2);
+       if (cur_cpu_spec->num_pmcs >= 3)
+               sysdev_remove_file(s, &attr_pmc3);
+       if (cur_cpu_spec->num_pmcs >= 4)
+               sysdev_remove_file(s, &attr_pmc4);
+       if (cur_cpu_spec->num_pmcs >= 5)
+               sysdev_remove_file(s, &attr_pmc5);
+       if (cur_cpu_spec->num_pmcs >= 6)
+               sysdev_remove_file(s, &attr_pmc6);
+       if (cur_cpu_spec->num_pmcs >= 7)
+               sysdev_remove_file(s, &attr_pmc7);
+       if (cur_cpu_spec->num_pmcs >= 8)
+               sysdev_remove_file(s, &attr_pmc8);
+
+       if (cpu_has_feature(CPU_FTR_SMT))
+               sysdev_remove_file(s, &attr_purr);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static int __devinit sysfs_cpu_notify(struct notifier_block *self,
+                                     unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned int)(long)hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+               register_cpu_online(cpu);
+               break;
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_DEAD:
+               unregister_cpu_online(cpu);
+               break;
+#endif
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __devinitdata sysfs_cpu_nb = {
+       .notifier_call  = sysfs_cpu_notify,
+};
+
+/* NUMA stuff */
+
+#ifdef CONFIG_NUMA
+static struct node node_devices[MAX_NUMNODES];
+
+static void register_nodes(void)
+{
+       int i;
+
+       for (i = 0; i < MAX_NUMNODES; i++) {
+               if (node_online(i)) {
+                       int p_node = parent_node(i);
+                       struct node *parent = NULL;
+
+                       if (p_node != i)
+                               parent = &node_devices[p_node];
+
+                       register_node(&node_devices[i], i, parent);
+               }
+       }
+}
+#else
+static void register_nodes(void)
+{
+       return;
+}
+#endif
+
+/* Only valid if CPU is present. */
+static ssize_t show_physical_id(struct sys_device *dev, char *buf)
+{
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
+
+       return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id));
+}
+static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL);
+
+static int __init topology_init(void)
+{
+       int cpu;
+       struct node *parent = NULL;
+
+       register_nodes();
+
+       register_cpu_notifier(&sysfs_cpu_nb);
+
+       for_each_cpu(cpu) {
+               struct cpu *c = &per_cpu(cpu_devices, cpu);
+
+#ifdef CONFIG_NUMA
+               /* The node to which a cpu belongs can't be known
+                * until the cpu is made present.
+                */
+               parent = NULL;
+               if (cpu_present(cpu))
+                       parent = &node_devices[cpu_to_node(cpu)];
+#endif
+               /*
+                * For now, we just see if the system supports making
+                * the RTAS calls for CPU hotplug.  But, there may be a
+                * more comprehensive way to do this for an individual
+                * CPU.  For instance, the boot cpu might never be valid
+                * for hotplugging.
+                */
+               if (!ppc_md.cpu_die)
+                       c->no_control = 1;
+
+               if (cpu_online(cpu) || (c->no_control == 0)) {
+                       register_cpu(c, cpu, parent);
+
+                       sysdev_create_file(&c->sysdev, &attr_physical_id);
+               }
+
+               if (cpu_online(cpu))
+                       register_cpu_online(cpu);
+       }
+
+       return 0;
+}
+__initcall(topology_init);
index a6282b625b440203aebb48f58e59c10fb4fa1ed5..260b6ecd26a9d61f72f7aa42a29455a11a3d6e61 100644 (file)
@@ -271,13 +271,13 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
         * tb_to_xs and stamp_xsec values are consistent.  If not, then it
         * loops back and reads them again until this criteria is met.
         */
-       ++(systemcfg->tb_update_count);
+       ++(_systemcfg->tb_update_count);
        smp_wmb();
-       systemcfg->tb_orig_stamp = new_tb_stamp;
-       systemcfg->stamp_xsec = new_stamp_xsec;
-       systemcfg->tb_to_xs = new_tb_to_xs;
+       _systemcfg->tb_orig_stamp = new_tb_stamp;
+       _systemcfg->stamp_xsec = new_stamp_xsec;
+       _systemcfg->tb_to_xs = new_tb_to_xs;
        smp_wmb();
-       ++(systemcfg->tb_update_count);
+       ++(_systemcfg->tb_update_count);
 #endif
 }
 
@@ -357,8 +357,9 @@ static void iSeries_tb_recal(void)
                                do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
                                tb_to_xs = divres.result_low;
                                do_gtod.varp->tb_to_xs = tb_to_xs;
-                               systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
-                               systemcfg->tb_to_xs = tb_to_xs;
+                               _systemcfg->tb_ticks_per_sec =
+                                       tb_ticks_per_sec;
+                               _systemcfg->tb_to_xs = tb_to_xs;
                        }
                        else {
                                printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
@@ -483,6 +484,8 @@ void __init smp_space_timers(unsigned int max_cpus)
        unsigned long offset = tb_ticks_per_jiffy / max_cpus;
        unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
 
+       /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
+       previous_tb -= tb_ticks_per_jiffy;
        for_each_cpu(i) {
                if (i != boot_cpuid) {
                        previous_tb += offset;
@@ -559,8 +562,8 @@ int do_settimeofday(struct timespec *tv)
        update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
 
 #ifdef CONFIG_PPC64
-       systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
-       systemcfg->tz_dsttime = sys_tz.tz_dsttime;
+       _systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
+       _systemcfg->tz_dsttime = sys_tz.tz_dsttime;
 #endif
 
        write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -711,11 +714,11 @@ void __init time_init(void)
        do_gtod.varp->tb_to_xs = tb_to_xs;
        do_gtod.tb_to_us = tb_to_us;
 #ifdef CONFIG_PPC64
-       systemcfg->tb_orig_stamp = tb_last_jiffy;
-       systemcfg->tb_update_count = 0;
-       systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
-       systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
-       systemcfg->tb_to_xs = tb_to_xs;
+       _systemcfg->tb_orig_stamp = tb_last_jiffy;
+       _systemcfg->tb_update_count = 0;
+       _systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
+       _systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+       _systemcfg->tb_to_xs = tb_to_xs;
 #endif
 
        time_freq = 0;
index 0578f838760301d2dd7c20c1294ba5459c07e4cd..2020bb7648fbc183f2f599ac6c834a2b4d7ed3f9 100644 (file)
@@ -129,7 +129,7 @@ int die(const char *str, struct pt_regs *regs, long err)
        nl = 1;
 #endif
 #ifdef CONFIG_PPC64
-       switch (systemcfg->platform) {
+       switch (_machine) {
        case PLATFORM_PSERIES:
                printk("PSERIES ");
                nl = 1;
index b67ce3004ebf535fec0881b55370ca98489e1c3e..f68ad71a018749523752b34ad65fed35520d4712 100644 (file)
@@ -41,7 +41,7 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
        tmp = *p;
 
 found_first:
-       tmp &= (~0UL >> (64 - size));
+       tmp &= (~0UL >> (BITS_PER_LONG - size));
        if (tmp == 0UL)         /* Are any bits set? */
                return result + size;   /* Nope. */
 found_middle:
index 22e474876133b334724d053a3e2434c06481acca..706e8a63ced93218334a227b62f5303595c27790 100644 (file)
 extern unsigned long dart_tablebase;
 #endif /* CONFIG_U3_DART */
 
+static unsigned long _SDR1;
+struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+
 hpte_t *htab_address;
 unsigned long htab_hash_mask;
-unsigned long _SDR1;
-struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
 int mmu_linear_psize = MMU_PAGE_4K;
 int mmu_virtual_psize = MMU_PAGE_4K;
 #ifdef CONFIG_HUGETLB_PAGE
@@ -165,7 +166,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                 * normal insert callback here.
                 */
 #ifdef CONFIG_PPC_ISERIES
-               if (systemcfg->platform == PLATFORM_ISERIES_LPAR)
+               if (_machine == PLATFORM_ISERIES_LPAR)
                        ret = iSeries_hpte_insert(hpteg, va,
                                                  virt_to_abs(paddr),
                                                  tmp_mode,
@@ -174,7 +175,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                else
 #endif
 #ifdef CONFIG_PPC_PSERIES
-               if (systemcfg->platform & PLATFORM_LPAR)
+               if (_machine & PLATFORM_LPAR)
                        ret = pSeries_lpar_hpte_insert(hpteg, va,
                                                       virt_to_abs(paddr),
                                                       tmp_mode,
@@ -293,7 +294,7 @@ static void __init htab_init_page_sizes(void)
         * Not in the device-tree, let's fallback on known size
         * list for 16M capable GP & GR
         */
-       if ((systemcfg->platform != PLATFORM_ISERIES_LPAR) &&
+       if ((_machine != PLATFORM_ISERIES_LPAR) &&
            cpu_has_feature(CPU_FTR_16M_PAGE))
                memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
                       sizeof(mmu_psize_defaults_gp));
@@ -364,7 +365,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
 
 static unsigned long __init htab_get_table_size(void)
 {
-       unsigned long rnd_mem_size, pteg_count;
+       unsigned long mem_size, rnd_mem_size, pteg_count;
 
        /* If hash size isn't already provided by the platform, we try to
         * retreive it from the device-tree. If it's not there neither, we
@@ -376,8 +377,9 @@ static unsigned long __init htab_get_table_size(void)
                return 1UL << ppc64_pft_size;
 
        /* round mem_size up to next power of 2 */
-       rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
-       if (rnd_mem_size < systemcfg->physicalMemorySize)
+       mem_size = lmb_phys_mem_size();
+       rnd_mem_size = 1UL << __ilog2(mem_size);
+       if (rnd_mem_size < mem_size)
                rnd_mem_size <<= 1;
 
        /* # pages / 2 */
@@ -386,6 +388,15 @@ static unsigned long __init htab_get_table_size(void)
        return pteg_count << 7;
 }
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+void create_section_mapping(unsigned long start, unsigned long end)
+{
+               BUG_ON(htab_bolt_mapping(start, end, start,
+                       _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
+                       mmu_linear_psize));
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
 void __init htab_initialize(void)
 {
        unsigned long table, htab_size_bytes;
@@ -410,7 +421,7 @@ void __init htab_initialize(void)
 
        htab_hash_mask = pteg_count - 1;
 
-       if (systemcfg->platform & PLATFORM_LPAR) {
+       if (platform_is_lpar()) {
                /* Using a hypervisor which owns the htab */
                htab_address = NULL;
                _SDR1 = 0; 
@@ -431,6 +442,9 @@ void __init htab_initialize(void)
 
                /* Initialize the HPT with no entries */
                memset((void *)table, 0, htab_size_bytes);
+
+               /* Set SDR1 */
+               mtspr(SPRN_SDR1, _SDR1);
        }
 
        mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
@@ -500,6 +514,12 @@ void __init htab_initialize(void)
 #undef KB
 #undef MB
 
+void __init htab_initialize_secondary(void)
+{
+       if (!platform_is_lpar())
+               mtspr(SPRN_SDR1, _SDR1);
+}
+
 /*
  * Called by asm hashtable.S for doing lazy icache flush
  */
index 4612a79dfb6e675058461d55a3bf048973961446..7d4b8b5f06063cdf41e1fe56c06fe207974d22a8 100644 (file)
@@ -84,9 +84,6 @@ void MMU_init(void);
 /* XXX should be in current.h  -- paulus */
 extern struct task_struct *current_set[NR_CPUS];
 
-char *klimit = _end;
-struct device_node *memory_node;
-
 extern int init_bootmem_done;
 
 /*
index ce974c83d88a6f1decd8341ccf92fbf253133c37..1134f70f231d43bc57d61cd208d791a34f0e4fbd 100644 (file)
@@ -20,6 +20,8 @@
  *
  */
 
+#undef DEBUG
+
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <asm/vdso.h>
 #include <asm/imalloc.h>
 
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
 #if PGTABLE_RANGE > USER_VSID_RANGE
 #warning Limited user VSID range means pagetable space is wasted
 #endif
@@ -72,8 +80,6 @@
 #warning TASK_SIZE is smaller than it needs to be.
 #endif
 
-unsigned long klimit = (unsigned long)_end;
-
 /* max amount of RAM to use */
 unsigned long __max_memory;
 
@@ -188,14 +194,14 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
 }
 
 #ifdef CONFIG_PPC_64K_PAGES
-static const int pgtable_cache_size[2] = {
-       PTE_TABLE_SIZE, PGD_TABLE_SIZE
+static const unsigned int pgtable_cache_size[3] = {
+       PTE_TABLE_SIZE, PMD_TABLE_SIZE, PGD_TABLE_SIZE
 };
 static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
-       "pte_pmd_cache", "pgd_cache",
+       "pte_pmd_cache", "pmd_cache", "pgd_cache",
 };
 #else
-static const int pgtable_cache_size[2] = {
+static const unsigned int pgtable_cache_size[2] = {
        PTE_TABLE_SIZE, PMD_TABLE_SIZE
 };
 static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
@@ -213,6 +219,8 @@ void pgtable_cache_init(void)
                int size = pgtable_cache_size[i];
                const char *name = pgtable_cache_name[i];
 
+               DBG("Allocating page table cache %s (#%d) "
+                   "for size: %08x...\n", name, i, size);
                pgtable_cache[i] = kmem_cache_create(name,
                                                     size, size,
                                                     SLAB_HWCACHE_ALIGN |
index 6f55efd9be957debe2c1522bda11ca50cb174a17..1dd3cc69a4901710d0514202dad224121619d9df 100644 (file)
@@ -110,6 +110,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
 void online_page(struct page *page)
 {
        ClearPageReserved(page);
+       set_page_count(page, 0);
        free_cold_page(page);
        totalram_pages++;
        num_physpages++;
@@ -127,6 +128,9 @@ int __devinit add_memory(u64 start, u64 size)
        unsigned long start_pfn = start >> PAGE_SHIFT;
        unsigned long nr_pages = size >> PAGE_SHIFT;
 
+       start += KERNELBASE;
+       create_section_mapping(start, start + size);
+
        /* this should work for most non-highmem platforms */
        zone = pgdata->node_zones;
 
index 900842451bd33a339676ffddfc540cc8e7f82646..c7f7bb6f30b3698769951d6ba63141de9ae82074 100644 (file)
@@ -122,8 +122,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
                 *
                 */
                if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
-                                     mmu_virtual_psize))
-                       panic("Can't map bolted IO mapping");
+                                     mmu_virtual_psize)) {
+                       printk(KERN_ERR "Failed to do bolted mapping IO "
+                              "memory at %016lx !\n", pa);
+                       return -ENOMEM;
+               }
        }
        return 0;
 }
index fa325dbf98fc2d14ac3be5774feafbcd3f4cd21c..cfbb4e1f966b3331e7e89dda329ae925841616d1 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/cputable.h>
 #include <asm/lmb.h>
 #include <asm/abs_addr.h>
+#include <asm/firmware.h>
 
 struct stab_entry {
        unsigned long esid_data;
@@ -256,7 +257,7 @@ void stabs_alloc(void)
 
                paca[cpu].stab_addr = newstab;
                paca[cpu].stab_real = virt_to_abs(newstab);
-               printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx "
+               printk(KERN_INFO "Segment table for CPU %d at 0x%lx "
                       "virtual, 0x%lx absolute\n",
                       cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
        }
@@ -270,10 +271,28 @@ void stabs_alloc(void)
 void stab_initialize(unsigned long stab)
 {
        unsigned long vsid = get_kernel_vsid(KERNELBASE);
+       unsigned long stabreal;
 
        asm volatile("isync; slbia; isync":::"memory");
        make_ste(stab, GET_ESID(KERNELBASE), vsid);
 
        /* Order update */
        asm volatile("sync":::"memory");
+
+       /* Set ASR */
+       stabreal = get_paca()->stab_real | 0x1ul;
+
+#ifdef CONFIG_PPC_ISERIES
+       if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+               HvCall1(HvCallBaseSetASR, stabreal);
+               return;
+       }
+#endif /* CONFIG_PPC_ISERIES */
+#ifdef CONFIG_PPC_PSERIES
+       if (platform_is_lpar()) {
+               plpar_hcall_norets(H_SET_ASR, stabreal);
+               return;
+       }
+#endif
+       mtspr(SPRN_ASR, stabreal);
 }
index c4ee5478427b4ae322a8e1b4dd18f3600a23ce9a..e3a024e324b62f846fb11eb37c2c1059ffc5967c 100644 (file)
@@ -233,8 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs)
        mmcra = mfspr(SPRN_MMCRA);
 
        /* Were we in the hypervisor? */
-       if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) &&
-           (mmcra & MMCRA_SIHV))
+       if (platform_is_lpar() && (mmcra & MMCRA_SIHV))
                /* function descriptor madness */
                return *((unsigned long *)hypervisor_bucket);
 
index ecd32d5d85f487e775fc3dcb455d2c409ca793af..4099ddab9205ce6b32ed61f47e950a047c5e76b9 100644 (file)
@@ -361,7 +361,9 @@ static void __init chrp_find_openpic(void)
        printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
 
        irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
-       prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4);
+       prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
+       /* i8259 cascade is always positive level */
+       init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
 
        iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
        if (iranges == NULL)
index a06603d84a451147d0cd646c40d18d9ef172bc94..01090e9ce0cfb74bc30eaa1068d7e0b883883786 100644 (file)
@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm,
                struct pt_regs *regsParm)
 {
        int irq;
+#ifdef CONFIG_IRQSTACKS
+       struct thread_info *curtp, *irqtp;
+#endif
 
        ++Pci_Interrupt_Count;
 
@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm,
        case XmPciLpEvent_SlotInterrupt:
                irq = eventParm->hvLpEvent.xCorrelationToken;
                /* Dispatch the interrupt handlers for this irq */
-               ppc_irq_dispatch_handler(regsParm, irq);
+#ifdef CONFIG_IRQSTACKS
+               /* Switch to the irq stack to handle this */
+               curtp = current_thread_info();
+               irqtp = hardirq_ctx[smp_processor_id()];
+               if (curtp != irqtp) {
+                       irqtp->task = curtp->task;
+                       irqtp->flags = 0;
+                       call___do_IRQ(irq, regsParm, irqtp);
+                       irqtp->task = NULL;
+                       if (irqtp->flags)
+                               set_bits(irqtp->flags, &curtp->flags);
+               } else
+#endif
+                       __do_IRQ(irq, regsParm);
                HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
                        eventParm->eventData.slotInterrupt.subBusNumber,
                        eventParm->eventData.slotInterrupt.deviceId);
@@ -310,10 +326,8 @@ static void iSeries_disable_IRQ(unsigned int irq)
 }
 
 /*
- * Need to define this so ppc_irq_dispatch_handler will NOT call
- * enable_IRQ at the end of interrupt handling.  However, this does
- * nothing because there is not enough information provided to do
- * the EOI HvCall.  This is done by XmPciLpEvent.c
+ * This does nothing because there is not enough information
+ * provided to do the EOI HvCall.  This is done by XmPciLpEvent.c
  */
 static void iSeries_end_IRQ(unsigned int irq)
 {
index 09f14522e176613338d47193f09af41bb5a7f641..dfe7aa1ba098facedbd1294dd6d1a26c8616ef1a 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <asm/processor.h>
 #include <asm/asm-offsets.h>
+#include <asm/ppc_asm.h>
 
        .text
 
index 7f8f0cda6a742ca7844c79259c6f5601c8d04b30..6a29f301436b305b8d11d850babc0eefc31952ec 100644 (file)
@@ -39,7 +39,8 @@
 #include <asm/sections.h>
 #include <asm/iommu.h>
 #include <asm/firmware.h>
-
+#include <asm/systemcfg.h>
+#include <asm/system.h>
 #include <asm/time.h>
 #include <asm/paca.h>
 #include <asm/cache.h>
@@ -71,7 +72,7 @@ extern void hvlog(char *fmt, ...);
 #endif
 
 /* Function Prototypes */
-static void build_iSeries_Memory_Map(void);
+static unsigned long build_iSeries_Memory_Map(void);
 static void iseries_shared_idle(void);
 static void iseries_dedicated_idle(void);
 #ifdef CONFIG_PCI
@@ -84,7 +85,6 @@ static void iSeries_pci_final_fixup(void) { }
 int piranha_simulator;
 
 extern int rd_size;            /* Defined in drivers/block/rd.c */
-extern unsigned long klimit;
 extern unsigned long embedded_sysmap_start;
 extern unsigned long embedded_sysmap_end;
 
@@ -403,9 +403,11 @@ void mschunks_alloc(unsigned long num_chunks)
  * a table used to translate Linux's physical addresses to these
  * absolute addresses.  Absolute addresses are needed when
  * communicating with the hypervisor (e.g. to build HPT entries)
+ *
+ * Returns the physical memory size
  */
 
-static void __init build_iSeries_Memory_Map(void)
+static unsigned long __init build_iSeries_Memory_Map(void)
 {
        u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
        u32 nextPhysChunk;
@@ -538,7 +540,7 @@ static void __init build_iSeries_Memory_Map(void)
         * which should be equal to
         *   nextPhysChunk
         */
-       systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
+       return chunk_to_addr(nextPhysChunk);
 }
 
 /*
@@ -564,8 +566,8 @@ static void __init iSeries_setup_arch(void)
        printk("Max physical processors = %d\n",
                        itVpdAreas.xSlicMaxPhysicalProcs);
 
-       systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
-       printk("Processor version = %x\n", systemcfg->processor);
+       _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
+       printk("Processor version = %x\n", _systemcfg->processor);
 }
 
 static void iSeries_show_cpuinfo(struct seq_file *m)
@@ -702,7 +704,6 @@ static void iseries_shared_idle(void)
 
 static void iseries_dedicated_idle(void)
 {
-       long oldval;
        set_thread_flag(TIF_POLLING_NRFLAG);
 
        while (1) {
@@ -929,7 +930,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
        dt_end_node(dt);
 }
 
-void build_flat_dt(struct iseries_flat_dt *dt)
+void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 {
        u64 tmp[2];
 
@@ -945,7 +946,7 @@ void build_flat_dt(struct iseries_flat_dt *dt)
        dt_prop_str(dt, "name", "memory");
        dt_prop_str(dt, "device_type", "memory");
        tmp[0] = 0;
-       tmp[1] = systemcfg->physicalMemorySize;
+       tmp[1] = phys_mem_size;
        dt_prop_u64_list(dt, "reg", tmp, 2);
        dt_end_node(dt);
 
@@ -965,13 +966,15 @@ void build_flat_dt(struct iseries_flat_dt *dt)
 
 void * __init iSeries_early_setup(void)
 {
+       unsigned long phys_mem_size;
+
        iSeries_fixup_klimit();
 
        /*
         * Initialize the table which translate Linux physical addresses to
         * AS/400 absolute addresses
         */
-       build_iSeries_Memory_Map();
+       phys_mem_size = build_iSeries_Memory_Map();
 
        iSeries_get_cmdline();
 
@@ -981,7 +984,7 @@ void * __init iSeries_early_setup(void)
        /* Parse early parameters, in particular mem=x */
        parse_early_param();
 
-       build_flat_dt(&iseries_dt);
+       build_flat_dt(&iseries_dt, phys_mem_size);
 
        return (void *) __pa(&iseries_dt);
 }
index 340c21caeae24cc03b1a12df50bda25a3fe9bc4a..895aeb3f75d0d73b6ddf94b370eaec93be0be604 100644 (file)
@@ -380,9 +380,6 @@ void __init maple_pcibios_fixup(void)
        for_each_pci_dev(dev)
                pci_read_irq_line(dev);
 
-       /* Do the mapping of the IO space */
-       phbs_remap_io();
-
        DBG(" <- maple_pcibios_fixup\n");
 }
 
index 8f818d092e2bbe20566cf0b049c98f086979651f..dfd41b9781a9a9df37dbeac71d3c8d18e5510404 100644 (file)
@@ -918,9 +918,6 @@ void __init pmac_pci_init(void)
                        PCI_DN(np)->busno = 0xf0;
        }
 
-       /* map in PCI I/O space */
-       phbs_remap_io();
-
        /* pmac_check_ht_link(); */
 
        /* Tell pci.c to not use the common resource allocation mechanism */
index 83a49e80ac2955e8f065f45e9662c99f066bc280..90040c49494d62ce94d900d7e2380a7be15979c3 100644 (file)
@@ -74,6 +74,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock);
 #define GATWICK_IRQ_POOL_SIZE        10
 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
 
+#define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
+static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
+
 /*
  * Mark an irq as "lost".  This is only used on the pmac
  * since it can lose interrupts (see pmac_set_irq_mask).
index e1f9443cc872ceb2726e1083953eca46964cba94..957b091034220553fc6d48545d88e256350a2ef7 100644 (file)
@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void)
        psurge_start = ioremap(PSURGE_START, 4);
        psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
 
-       /* this is not actually strictly necessary -- paulus. */
-       for (i = 1; i < ncpus; ++i)
-               smp_hw_index[i] = i;
+       /*
+        * This is necessary because OF doesn't know about the
+        * secondary cpu(s), and thus there aren't nodes in the
+        * device tree for them, and smp_setup_cpu_maps hasn't
+        * set their bits in cpu_possible_map and cpu_present_map.
+        */
+       if (ncpus > NR_CPUS)
+               ncpus = NR_CPUS;
+       for (i = 1; i < ncpus ; ++i) {
+               cpu_set(i, cpu_present_map);
+               cpu_set(i, cpu_possible_map);
+               set_hard_smp_processor_id(i, i);
+       }
 
        if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
 
@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
        int t;
 
        set_dec(tb_ticks_per_jiffy);
+       /* XXX fixme */
        set_tb(0, 0);
        last_jiffy_stamp(cpu_nr) = 0;
 
@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
 
        /* now interrupt the secondary, starting both TBs */
        psurge_set_ipi(1);
-
-       smp_tb_synchronized = 1;
 }
 
 static struct irqaction psurge_irqaction = {
@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void)
        for (t = 100000; t > 0 && sec_tb_reset; --t)
                udelay(10);
        if (sec_tb_reset)
+               /* XXX BUG_ON here? */
                printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
-       else
-               smp_tb_synchronized = 1;
 
        /* Now, restart the timebase by leaving the GPIO to an open collector */
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
@@ -810,19 +818,9 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
 }
 
 
-/* Core99 Macs (dual G4s and G5s) */
-struct smp_ops_t core99_smp_ops = {
-       .message_pass   = smp_mpic_message_pass,
-       .probe          = smp_core99_probe,
-       .kick_cpu       = smp_core99_kick_cpu,
-       .setup_cpu      = smp_core99_setup_cpu,
-       .give_timebase  = smp_core99_give_timebase,
-       .take_timebase  = smp_core99_take_timebase,
-};
-
 #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
 
-int __cpu_disable(void)
+int smp_core99_cpu_disable(void)
 {
        cpu_clear(smp_processor_id(), cpu_online_map);
 
@@ -846,7 +844,7 @@ void cpu_die(void)
        low_cpu_die();
 }
 
-void __cpu_die(unsigned int cpu)
+void smp_core99_cpu_die(unsigned int cpu)
 {
        int timeout;
 
@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu)
                }
                msleep(1);
        }
-       cpu_callin_map[cpu] = 0;
        cpu_dead[cpu] = 0;
 }
 
 #endif
+
+/* Core99 Macs (dual G4s and G5s) */
+struct smp_ops_t core99_smp_ops = {
+       .message_pass   = smp_mpic_message_pass,
+       .probe          = smp_core99_probe,
+       .kick_cpu       = smp_core99_kick_cpu,
+       .setup_cpu      = smp_core99_setup_cpu,
+       .give_timebase  = smp_core99_give_timebase,
+       .take_timebase  = smp_core99_take_timebase,
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+       .cpu_disable    = smp_core99_cpu_disable,
+       .cpu_die        = smp_core99_cpu_die,
+#endif
+};
index b9938fece781612e1f213a6368af23b124213f08..e7ca5b1f591e2977dd5d2162747086400b82a4f1 100644 (file)
@@ -3,3 +3,5 @@ obj-y                   := pci.o lpar.o hvCall.o nvram.o reconfig.o \
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_IBMVIO)   += vio.o
 obj-$(CONFIG_XICS)     += xics.o
+obj-$(CONFIG_SCANLOG)  += scanlog.o
+obj-$(CONFIG_EEH)    += eeh.o eeh_event.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
new file mode 100644 (file)
index 0000000..79de231
--- /dev/null
@@ -0,0 +1,1212 @@
+/*
+ * eeh.c
+ * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/rbtree.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/rtas.h>
+
+#undef DEBUG
+
+/** Overview:
+ *  EEH, or "Extended Error Handling" is a PCI bridge technology for
+ *  dealing with PCI bus errors that can't be dealt with within the
+ *  usual PCI framework, except by check-stopping the CPU.  Systems
+ *  that are designed for high-availability/reliability cannot afford
+ *  to crash due to a "mere" PCI error, thus the need for EEH.
+ *  An EEH-capable bridge operates by converting a detected error
+ *  into a "slot freeze", taking the PCI adapter off-line, making
+ *  the slot behave, from the OS'es point of view, as if the slot
+ *  were "empty": all reads return 0xff's and all writes are silently
+ *  ignored.  EEH slot isolation events can be triggered by parity
+ *  errors on the address or data busses (e.g. during posted writes),
+ *  which in turn might be caused by low voltage on the bus, dust,
+ *  vibration, humidity, radioactivity or plain-old failed hardware.
+ *
+ *  Note, however, that one of the leading causes of EEH slot
+ *  freeze events are buggy device drivers, buggy device microcode,
+ *  or buggy device hardware.  This is because any attempt by the
+ *  device to bus-master data to a memory address that is not
+ *  assigned to the device will trigger a slot freeze.   (The idea
+ *  is to prevent devices-gone-wild from corrupting system memory).
+ *  Buggy hardware/drivers will have a miserable time co-existing
+ *  with EEH.
+ *
+ *  Ideally, a PCI device driver, when suspecting that an isolation
+ *  event has occured (e.g. by reading 0xff's), will then ask EEH
+ *  whether this is the case, and then take appropriate steps to
+ *  reset the PCI slot, the PCI device, and then resume operations.
+ *  However, until that day,  the checking is done here, with the
+ *  eeh_check_failure() routine embedded in the MMIO macros.  If
+ *  the slot is found to be isolated, an "EEH Event" is synthesized
+ *  and sent out for processing.
+ */
+
+/* If a device driver keeps reading an MMIO register in an interrupt
+ * handler after a slot isolation event has occurred, we assume it
+ * is broken and panic.  This sets the threshold for how many read
+ * attempts we allow before panicking.
+ */
+#define EEH_MAX_FAILS  100000
+
+/* Misc forward declaraions */
+static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
+
+/* RTAS tokens */
+static int ibm_set_eeh_option;
+static int ibm_set_slot_reset;
+static int ibm_read_slot_reset_state;
+static int ibm_read_slot_reset_state2;
+static int ibm_slot_error_detail;
+
+static int eeh_subsystem_enabled;
+
+/* Lock to avoid races due to multiple reports of an error */
+static DEFINE_SPINLOCK(confirm_error_lock);
+
+/* Buffer for reporting slot-error-detail rtas calls */
+static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
+static DEFINE_SPINLOCK(slot_errbuf_lock);
+static int eeh_error_buf_size;
+
+/* System monitoring statistics */
+static DEFINE_PER_CPU(unsigned long, no_device);
+static DEFINE_PER_CPU(unsigned long, no_dn);
+static DEFINE_PER_CPU(unsigned long, no_cfg_addr);
+static DEFINE_PER_CPU(unsigned long, ignored_check);
+static DEFINE_PER_CPU(unsigned long, total_mmio_ffs);
+static DEFINE_PER_CPU(unsigned long, false_positives);
+static DEFINE_PER_CPU(unsigned long, ignored_failures);
+static DEFINE_PER_CPU(unsigned long, slot_resets);
+
+/**
+ * The pci address cache subsystem.  This subsystem places
+ * PCI device address resources into a red-black tree, sorted
+ * according to the address range, so that given only an i/o
+ * address, the corresponding PCI device can be **quickly**
+ * found. It is safe to perform an address lookup in an interrupt
+ * context; this ability is an important feature.
+ *
+ * Currently, the only customer of this code is the EEH subsystem;
+ * thus, this code has been somewhat tailored to suit EEH better.
+ * In particular, the cache does *not* hold the addresses of devices
+ * for which EEH is not enabled.
+ *
+ * (Implementation Note: The RB tree seems to be better/faster
+ * than any hash algo I could think of for this problem, even
+ * with the penalty of slow pointer chases for d-cache misses).
+ */
+struct pci_io_addr_range
+{
+       struct rb_node rb_node;
+       unsigned long addr_lo;
+       unsigned long addr_hi;
+       struct pci_dev *pcidev;
+       unsigned int flags;
+};
+
+static struct pci_io_addr_cache
+{
+       struct rb_root rb_root;
+       spinlock_t piar_lock;
+} pci_io_addr_cache_root;
+
+static inline struct pci_dev *__pci_get_device_by_addr(unsigned long addr)
+{
+       struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
+
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+               if (addr < piar->addr_lo) {
+                       n = n->rb_left;
+               } else {
+                       if (addr > piar->addr_hi) {
+                               n = n->rb_right;
+                       } else {
+                               pci_dev_get(piar->pcidev);
+                               return piar->pcidev;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+/**
+ * pci_get_device_by_addr - Get device, given only address
+ * @addr: mmio (PIO) phys address or i/o port number
+ *
+ * Given an mmio phys address, or a port number, find a pci device
+ * that implements this address.  Be sure to pci_dev_put the device
+ * when finished.  I/O port numbers are assumed to be offset
+ * from zero (that is, they do *not* have pci_io_addr added in).
+ * It is safe to call this function within an interrupt.
+ */
+static struct pci_dev *pci_get_device_by_addr(unsigned long addr)
+{
+       struct pci_dev *dev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       dev = __pci_get_device_by_addr(addr);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+       return dev;
+}
+
+#ifdef DEBUG
+/*
+ * Handy-dandy debug print routine, does nothing more
+ * than print out the contents of our addr cache.
+ */
+static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
+{
+       struct rb_node *n;
+       int cnt = 0;
+
+       n = rb_first(&cache->rb_root);
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
+                      (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
+                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
+               cnt++;
+               n = rb_next(n);
+       }
+}
+#endif
+
+/* Insert address range into the rb tree. */
+static struct pci_io_addr_range *
+pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
+                     unsigned long ahi, unsigned int flags)
+{
+       struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
+       struct rb_node *parent = NULL;
+       struct pci_io_addr_range *piar;
+
+       /* Walk tree, find a place to insert into tree */
+       while (*p) {
+               parent = *p;
+               piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
+               if (ahi < piar->addr_lo) {
+                       p = &parent->rb_left;
+               } else if (alo > piar->addr_hi) {
+                       p = &parent->rb_right;
+               } else {
+                       if (dev != piar->pcidev ||
+                           alo != piar->addr_lo || ahi != piar->addr_hi) {
+                               printk(KERN_WARNING "PIAR: overlapping address range\n");
+                       }
+                       return piar;
+               }
+       }
+       piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+       if (!piar)
+               return NULL;
+
+       piar->addr_lo = alo;
+       piar->addr_hi = ahi;
+       piar->pcidev = dev;
+       piar->flags = flags;
+
+#ifdef DEBUG
+       printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
+                         alo, ahi, pci_name (dev));
+#endif
+
+       rb_link_node(&piar->rb_node, parent, p);
+       rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
+
+       return piar;
+}
+
+static void __pci_addr_cache_insert_device(struct pci_dev *dev)
+{
+       struct device_node *dn;
+       struct pci_dn *pdn;
+       int i;
+       int inserted = 0;
+
+       dn = pci_device_to_OF_node(dev);
+       if (!dn) {
+               printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
+               return;
+       }
+
+       /* Skip any devices for which EEH is not enabled. */
+       pdn = PCI_DN(dn);
+       if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+           pdn->eeh_mode & EEH_MODE_NOCHECK) {
+#ifdef DEBUG
+               printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n",
+                      pci_name(dev), pdn->node->full_name);
+#endif
+               return;
+       }
+
+       /* The cache holds a reference to the device... */
+       pci_dev_get(dev);
+
+       /* Walk resources on this device, poke them into the tree */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               unsigned long start = pci_resource_start(dev,i);
+               unsigned long end = pci_resource_end(dev,i);
+               unsigned int flags = pci_resource_flags(dev,i);
+
+               /* We are interested only bus addresses, not dma or other stuff */
+               if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+                       continue;
+               if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
+                        continue;
+               pci_addr_cache_insert(dev, start, end, flags);
+               inserted = 1;
+       }
+
+       /* If there was nothing to add, the cache has no reference... */
+       if (!inserted)
+               pci_dev_put(dev);
+}
+
+/**
+ * pci_addr_cache_insert_device - Add a device to the address cache
+ * @dev: PCI device whose I/O addresses we are interested in.
+ *
+ * In order to support the fast lookup of devices based on addresses,
+ * we maintain a cache of devices that can be quickly searched.
+ * This routine adds a device to that cache.
+ */
+static void pci_addr_cache_insert_device(struct pci_dev *dev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       __pci_addr_cache_insert_device(dev);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
+{
+       struct rb_node *n;
+       int removed = 0;
+
+restart:
+       n = rb_first(&pci_io_addr_cache_root.rb_root);
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+               if (piar->pcidev == dev) {
+                       rb_erase(n, &pci_io_addr_cache_root.rb_root);
+                       removed = 1;
+                       kfree(piar);
+                       goto restart;
+               }
+               n = rb_next(n);
+       }
+
+       /* The cache no longer holds its reference to this device... */
+       if (removed)
+               pci_dev_put(dev);
+}
+
+/**
+ * pci_addr_cache_remove_device - remove pci device from addr cache
+ * @dev: device to remove
+ *
+ * Remove a device from the addr-cache tree.
+ * This is potentially expensive, since it will walk
+ * the tree multiple times (once per resource).
+ * But so what; device removal doesn't need to be that fast.
+ */
+static void pci_addr_cache_remove_device(struct pci_dev *dev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       __pci_addr_cache_remove_device(dev);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+/**
+ * pci_addr_cache_build - Build a cache of I/O addresses
+ *
+ * Build a cache of pci i/o addresses.  This cache will be used to
+ * find the pci device that corresponds to a given address.
+ * This routine scans all pci busses to build the cache.
+ * Must be run late in boot process, after the pci controllers
+ * have been scaned for devices (after all device resources are known).
+ */
+void __init pci_addr_cache_build(void)
+{
+       struct device_node *dn;
+       struct pci_dev *dev = NULL;
+
+       if (!eeh_subsystem_enabled)
+               return;
+
+       spin_lock_init(&pci_io_addr_cache_root.piar_lock);
+
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               /* Ignore PCI bridges ( XXX why ??) */
+               if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+                       continue;
+               }
+               pci_addr_cache_insert_device(dev);
+
+               /* Save the BAR's; firmware doesn't restore these after EEH reset */
+               dn = pci_device_to_OF_node(dev);
+               eeh_save_bars(dev, PCI_DN(dn));
+       }
+
+#ifdef DEBUG
+       /* Verify tree built up above, echo back the list of addrs. */
+       pci_addr_cache_print(&pci_io_addr_cache_root);
+#endif
+}
+
+/* --------------------------------------------------------------- */
+/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */
+
+void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
+{
+       unsigned long flags;
+       int rc;
+
+       /* Log the error with the rtas logger */
+       spin_lock_irqsave(&slot_errbuf_lock, flags);
+       memset(slot_errbuf, 0, eeh_error_buf_size);
+
+       rc = rtas_call(ibm_slot_error_detail,
+                      8, 1, NULL, pdn->eeh_config_addr,
+                      BUID_HI(pdn->phb->buid),
+                      BUID_LO(pdn->phb->buid), NULL, 0,
+                      virt_to_phys(slot_errbuf),
+                      eeh_error_buf_size,
+                      severity);
+
+       if (rc == 0)
+               log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
+       spin_unlock_irqrestore(&slot_errbuf_lock, flags);
+}
+
+/**
+ * read_slot_reset_state - Read the reset state of a device node's slot
+ * @dn: device node to read
+ * @rets: array to return results in
+ */
+static int read_slot_reset_state(struct pci_dn *pdn, int rets[])
+{
+       int token, outputs;
+
+       if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
+               token = ibm_read_slot_reset_state2;
+               outputs = 4;
+       } else {
+               token = ibm_read_slot_reset_state;
+               rets[2] = 0; /* fake PE Unavailable info */
+               outputs = 3;
+       }
+
+       return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
+                        BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
+}
+
+/**
+ * eeh_token_to_phys - convert EEH address token to phys address
+ * @token i/o token, should be address in the form 0xA....
+ */
+static inline unsigned long eeh_token_to_phys(unsigned long token)
+{
+       pte_t *ptep;
+       unsigned long pa;
+
+       ptep = find_linux_pte(init_mm.pgd, token);
+       if (!ptep)
+               return token;
+       pa = pte_pfn(*ptep) << PAGE_SHIFT;
+
+       return pa | (token & (PAGE_SIZE-1));
+}
+
+/** 
+ * Return the "partitionable endpoint" (pe) under which this device lies
+ */
+static struct device_node * find_device_pe(struct device_node *dn)
+{
+       while ((dn->parent) && PCI_DN(dn->parent) &&
+             (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
+               dn = dn->parent;
+       }
+       return dn;
+}
+
+/** Mark all devices that are peers of this device as failed.
+ *  Mark the device driver too, so that it can see the failure
+ *  immediately; this is critical, since some drivers poll
+ *  status registers in interrupts ... If a driver is polling,
+ *  and the slot is frozen, then the driver can deadlock in
+ *  an interrupt context, which is bad.
+ */
+
+static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
+{
+       while (dn) {
+               if (PCI_DN(dn)) {
+                       PCI_DN(dn)->eeh_mode |= mode_flag;
+
+                       if (dn->child)
+                               __eeh_mark_slot (dn->child, mode_flag);
+               }
+               dn = dn->sibling;
+       }
+}
+
+void eeh_mark_slot (struct device_node *dn, int mode_flag)
+{
+       dn = find_device_pe (dn);
+       PCI_DN(dn)->eeh_mode |= mode_flag;
+       __eeh_mark_slot (dn->child, mode_flag);
+}
+
+static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
+{
+       while (dn) {
+               if (PCI_DN(dn)) {
+                       PCI_DN(dn)->eeh_mode &= ~mode_flag;
+                       PCI_DN(dn)->eeh_check_count = 0;
+                       if (dn->child)
+                               __eeh_clear_slot (dn->child, mode_flag);
+               }
+               dn = dn->sibling;
+       }
+}
+
+void eeh_clear_slot (struct device_node *dn, int mode_flag)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&confirm_error_lock, flags);
+       dn = find_device_pe (dn);
+       PCI_DN(dn)->eeh_mode &= ~mode_flag;
+       PCI_DN(dn)->eeh_check_count = 0;
+       __eeh_clear_slot (dn->child, mode_flag);
+       spin_unlock_irqrestore(&confirm_error_lock, flags);
+}
+
+/**
+ * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze
+ * @dn device node
+ * @dev pci device, if known
+ *
+ * Check for an EEH failure for the given device node.  Call this
+ * routine if the result of a read was all 0xff's and you want to
+ * find out if this is due to an EEH slot freeze.  This routine
+ * will query firmware for the EEH status.
+ *
+ * Returns 0 if there has not been an EEH error; otherwise returns
+ * a non-zero value and queues up a slot isolation event notification.
+ *
+ * It is safe to call this routine in an interrupt context.
+ */
+int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
+{
+       int ret;
+       int rets[3];
+       unsigned long flags;
+       struct pci_dn *pdn;
+       int rc = 0;
+
+       __get_cpu_var(total_mmio_ffs)++;
+
+       if (!eeh_subsystem_enabled)
+               return 0;
+
+       if (!dn) {
+               __get_cpu_var(no_dn)++;
+               return 0;
+       }
+       pdn = PCI_DN(dn);
+
+       /* Access to IO BARs might get this far and still not want checking. */
+       if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+           pdn->eeh_mode & EEH_MODE_NOCHECK) {
+               __get_cpu_var(ignored_check)++;
+#ifdef DEBUG
+               printk ("EEH:ignored check (%x) for %s %s\n", 
+                       pdn->eeh_mode, pci_name (dev), dn->full_name);
+#endif
+               return 0;
+       }
+
+       if (!pdn->eeh_config_addr) {
+               __get_cpu_var(no_cfg_addr)++;
+               return 0;
+       }
+
+       /* If we already have a pending isolation event for this
+        * slot, we know it's bad already, we don't need to check.
+        * Do this checking under a lock; as multiple PCI devices
+        * in one slot might report errors simultaneously, and we
+        * only want one error recovery routine running.
+        */
+       spin_lock_irqsave(&confirm_error_lock, flags);
+       rc = 1;
+       if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
+               pdn->eeh_check_count ++;
+               if (pdn->eeh_check_count >= EEH_MAX_FAILS) {
+                       printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n",
+                               pdn->eeh_check_count);
+                       dump_stack();
+                       
+                       /* re-read the slot reset state */
+                       if (read_slot_reset_state(pdn, rets) != 0)
+                               rets[0] = -1;   /* reset state unknown */
+
+                       /* If we are here, then we hit an infinite loop. Stop. */
+                       panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev));
+               }
+               goto dn_unlock;
+       }
+
+       /*
+        * Now test for an EEH failure.  This is VERY expensive.
+        * Note that the eeh_config_addr may be a parent device
+        * in the case of a device behind a bridge, or it may be
+        * function zero of a multi-function device.
+        * In any case they must share a common PHB.
+        */
+       ret = read_slot_reset_state(pdn, rets);
+
+       /* If the call to firmware failed, punt */
+       if (ret != 0) {
+               printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
+                      ret, dn->full_name);
+               __get_cpu_var(false_positives)++;
+               rc = 0;
+               goto dn_unlock;
+       }
+
+       /* If EEH is not supported on this device, punt. */
+       if (rets[1] != 1) {
+               printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
+                      ret, dn->full_name);
+               __get_cpu_var(false_positives)++;
+               rc = 0;
+               goto dn_unlock;
+       }
+
+       /* If not the kind of error we know about, punt. */
+       if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
+               __get_cpu_var(false_positives)++;
+               rc = 0;
+               goto dn_unlock;
+       }
+
+       /* Note that config-io to empty slots may fail;
+        * we recognize empty because they don't have children. */
+       if ((rets[0] == 5) && (dn->child == NULL)) {
+               __get_cpu_var(false_positives)++;
+               rc = 0;
+               goto dn_unlock;
+       }
+
+       __get_cpu_var(slot_resets)++;
+       /* Avoid repeated reports of this failure, including problems
+        * with other functions on this device, and functions under
+        * bridges. */
+       eeh_mark_slot (dn, EEH_MODE_ISOLATED);
+       spin_unlock_irqrestore(&confirm_error_lock, flags);
+
+       eeh_send_failure_event (dn, dev, rets[0], rets[2]);
+       
+       /* Most EEH events are due to device driver bugs.  Having
+        * a stack trace will help the device-driver authors figure
+        * out what happened.  So print that out. */
+       if (rets[0] != 5) dump_stack();
+       return 1;
+
+dn_unlock:
+       spin_unlock_irqrestore(&confirm_error_lock, flags);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(eeh_dn_check_failure);
+
+/**
+ * eeh_check_failure - check if all 1's data is due to EEH slot freeze
+ * @token i/o token, should be address in the form 0xA....
+ * @val value, should be all 1's (XXX why do we need this arg??)
+ *
+ * Check for an EEH failure at the given token address.  Call this
+ * routine if the result of a read was all 0xff's and you want to
+ * find out if this is due to an EEH slot freeze event.  This routine
+ * will query firmware for the EEH status.
+ *
+ * Note this routine is safe to call in an interrupt context.
+ */
+unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
+{
+       unsigned long addr;
+       struct pci_dev *dev;
+       struct device_node *dn;
+
+       /* Finding the phys addr + pci device; this is pretty quick. */
+       addr = eeh_token_to_phys((unsigned long __force) token);
+       dev = pci_get_device_by_addr(addr);
+       if (!dev) {
+               __get_cpu_var(no_device)++;
+               return val;
+       }
+
+       dn = pci_device_to_OF_node(dev);
+       eeh_dn_check_failure (dn, dev);
+
+       pci_dev_put(dev);
+       return val;
+}
+
+EXPORT_SYMBOL(eeh_check_failure);
+
+/* ------------------------------------------------------------- */
+/* The code below deals with error recovery */
+
+/** Return negative value if a permanent error, else return
+ * a number of milliseconds to wait until the PCI slot is
+ * ready to be used.
+ */
+static int
+eeh_slot_availability(struct pci_dn *pdn)
+{
+       int rc;
+       int rets[3];
+
+       rc = read_slot_reset_state(pdn, rets);
+
+       if (rc) return rc;
+
+       if (rets[1] == 0) return -1;  /* EEH is not supported */
+       if (rets[0] == 0)  return 0;  /* Oll Korrect */
+       if (rets[0] == 5) {
+               if (rets[2] == 0) return -1; /* permanently unavailable */
+               return rets[2]; /* number of millisecs to wait */
+       }
+       return -1;
+}
+
+/** rtas_pci_slot_reset raises/lowers the pci #RST line
+ *  state: 1/0 to raise/lower the #RST
+ *
+ * Clear the EEH-frozen condition on a slot.  This routine
+ * asserts the PCI #RST line if the 'state' argument is '1',
+ * and drops the #RST line if 'state is '0'.  This routine is
+ * safe to call in an interrupt context.
+ *
+ */
+
+static void
+rtas_pci_slot_reset(struct pci_dn *pdn, int state)
+{
+       int rc;
+
+       BUG_ON (pdn==NULL); 
+
+       if (!pdn->phb) {
+               printk (KERN_WARNING "EEH: in slot reset, device node %s has no phb\n",
+                       pdn->node->full_name);
+               return;
+       }
+
+       rc = rtas_call(ibm_set_slot_reset,4,1, NULL,
+                      pdn->eeh_config_addr,
+                      BUID_HI(pdn->phb->buid),
+                      BUID_LO(pdn->phb->buid),
+                      state);
+       if (rc) {
+               printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", 
+                       rc, state, pdn->node->full_name);
+               return;
+       }
+}
+
+/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
+ *  dn -- device node to be reset.
+ */
+
+void
+rtas_set_slot_reset(struct pci_dn *pdn)
+{
+       int i, rc;
+
+       rtas_pci_slot_reset (pdn, 1);
+
+       /* The PCI bus requires that the reset be held high for at least
+        * a 100 milliseconds. We wait a bit longer 'just in case'.  */
+
+#define PCI_BUS_RST_HOLD_TIME_MSEC 250
+       msleep (PCI_BUS_RST_HOLD_TIME_MSEC);
+       
+       /* We might get hit with another EEH freeze as soon as the 
+        * pci slot reset line is dropped. Make sure we don't miss
+        * these, and clear the flag now. */
+       eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED);
+
+       rtas_pci_slot_reset (pdn, 0);
+
+       /* After a PCI slot has been reset, the PCI Express spec requires
+        * a 1.5 second idle time for the bus to stabilize, before starting
+        * up traffic. */
+#define PCI_BUS_SETTLE_TIME_MSEC 1800
+       msleep (PCI_BUS_SETTLE_TIME_MSEC);
+
+       /* Now double check with the firmware to make sure the device is
+        * ready to be used; if not, wait for recovery. */
+       for (i=0; i<10; i++) {
+               rc = eeh_slot_availability (pdn);
+               if (rc <= 0) break;
+
+               msleep (rc+100);
+       }
+}
+
+/* ------------------------------------------------------- */
+/** Save and restore of PCI BARs
+ *
+ * Although firmware will set up BARs during boot, it doesn't
+ * set up device BAR's after a device reset, although it will,
+ * if requested, set up bridge configuration. Thus, we need to
+ * configure the PCI devices ourselves.  
+ */
+
+/**
+ * __restore_bars - Restore the Base Address Registers
+ * Loads the PCI configuration space base address registers,
+ * the expansion ROM base address, the latency timer, and etc.
+ * from the saved values in the device node.
+ */
+static inline void __restore_bars (struct pci_dn *pdn)
+{
+       int i;
+
+       if (NULL==pdn->phb) return;
+       for (i=4; i<10; i++) {
+               rtas_write_config(pdn, i*4, 4, pdn->config_space[i]);
+       }
+
+       /* 12 == Expansion ROM Address */
+       rtas_write_config(pdn, 12*4, 4, pdn->config_space[12]);
+
+#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
+#define SAVED_BYTE(OFF) (((u8 *)(pdn->config_space))[BYTE_SWAP(OFF)])
+
+       rtas_write_config (pdn, PCI_CACHE_LINE_SIZE, 1,
+                   SAVED_BYTE(PCI_CACHE_LINE_SIZE));
+
+       rtas_write_config (pdn, PCI_LATENCY_TIMER, 1,
+                   SAVED_BYTE(PCI_LATENCY_TIMER));
+
+       /* max latency, min grant, interrupt pin and line */
+       rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]);
+}
+
+/**
+ * eeh_restore_bars - restore the PCI config space info
+ *
+ * This routine performs a recursive walk to the children
+ * of this device as well.
+ */
+void eeh_restore_bars(struct pci_dn *pdn)
+{
+       struct device_node *dn;
+       if (!pdn) 
+               return;
+       
+       if (! pdn->eeh_is_bridge)
+               __restore_bars (pdn);
+
+       dn = pdn->node->child;
+       while (dn) {
+               eeh_restore_bars (PCI_DN(dn));
+               dn = dn->sibling;
+       }
+}
+
+/**
+ * eeh_save_bars - save device bars
+ *
+ * Save the values of the device bars. Unlike the restore
+ * routine, this routine is *not* recursive. This is because
+ * PCI devices are added individuallly; but, for the restore,
+ * an entire slot is reset at a time.
+ */
+static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn)
+{
+       int i;
+
+       if (!pdev || !pdn )
+               return;
+       
+       for (i = 0; i < 16; i++)
+               pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]);
+
+       if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+               pdn->eeh_is_bridge = 1;
+}
+
+void
+rtas_configure_bridge(struct pci_dn *pdn)
+{
+       int token = rtas_token ("ibm,configure-bridge");
+       int rc;
+
+       if (token == RTAS_UNKNOWN_SERVICE)
+               return;
+       rc = rtas_call(token,3,1, NULL,
+                      pdn->eeh_config_addr,
+                      BUID_HI(pdn->phb->buid),
+                      BUID_LO(pdn->phb->buid));
+       if (rc) {
+               printk (KERN_WARNING "EEH: Unable to configure device bridge (%d) for %s\n",
+                       rc, pdn->node->full_name);
+       }
+}
+
+/* ------------------------------------------------------------- */
+/* The code below deals with enabling EEH for devices during  the
+ * early boot sequence.  EEH must be enabled before any PCI probing
+ * can be done.
+ */
+
+#define EEH_ENABLE 1
+
+struct eeh_early_enable_info {
+       unsigned int buid_hi;
+       unsigned int buid_lo;
+};
+
+/* Enable eeh for the given device node. */
+static void *early_enable_eeh(struct device_node *dn, void *data)
+{
+       struct eeh_early_enable_info *info = data;
+       int ret;
+       char *status = get_property(dn, "status", NULL);
+       u32 *class_code = (u32 *)get_property(dn, "class-code", NULL);
+       u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL);
+       u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
+       u32 *regs;
+       int enable;
+       struct pci_dn *pdn = PCI_DN(dn);
+
+       pdn->eeh_mode = 0;
+       pdn->eeh_check_count = 0;
+       pdn->eeh_freeze_count = 0;
+
+       if (status && strcmp(status, "ok") != 0)
+               return NULL;    /* ignore devices with bad status */
+
+       /* Ignore bad nodes. */
+       if (!class_code || !vendor_id || !device_id)
+               return NULL;
+
+       /* There is nothing to check on PCI to ISA bridges */
+       if (dn->type && !strcmp(dn->type, "isa")) {
+               pdn->eeh_mode |= EEH_MODE_NOCHECK;
+               return NULL;
+       }
+
+       /*
+        * Now decide if we are going to "Disable" EEH checking
+        * for this device.  We still run with the EEH hardware active,
+        * but we won't be checking for ff's.  This means a driver
+        * could return bad data (very bad!), an interrupt handler could
+        * hang waiting on status bits that won't change, etc.
+        * But there are a few cases like display devices that make sense.
+        */
+       enable = 1;     /* i.e. we will do checking */
+       if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
+               enable = 0;
+
+       if (!enable)
+               pdn->eeh_mode |= EEH_MODE_NOCHECK;
+
+       /* Ok... see if this device supports EEH.  Some do, some don't,
+        * and the only way to find out is to check each and every one. */
+       regs = (u32 *)get_property(dn, "reg", NULL);
+       if (regs) {
+               /* First register entry is addr (00BBSS00)  */
+               /* Try to enable eeh */
+               ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+                               regs[0], info->buid_hi, info->buid_lo,
+                               EEH_ENABLE);
+
+               if (ret == 0) {
+                       eeh_subsystem_enabled = 1;
+                       pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+                       pdn->eeh_config_addr = regs[0];
+#ifdef DEBUG
+                       printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
+#endif
+               } else {
+
+                       /* This device doesn't support EEH, but it may have an
+                        * EEH parent, in which case we mark it as supported. */
+                       if (dn->parent && PCI_DN(dn->parent)
+                           && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
+                               /* Parent supports EEH. */
+                               pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+                               pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
+                               return NULL;
+                       }
+               }
+       } else {
+               printk(KERN_WARNING "EEH: %s: unable to get reg property.\n",
+                      dn->full_name);
+       }
+
+       return NULL;
+}
+
+/*
+ * Initialize EEH by trying to enable it for all of the adapters in the system.
+ * As a side effect we can determine here if eeh is supported at all.
+ * Note that we leave EEH on so failed config cycles won't cause a machine
+ * check.  If a user turns off EEH for a particular adapter they are really
+ * telling Linux to ignore errors.  Some hardware (e.g. POWER5) won't
+ * grant access to a slot if EEH isn't enabled, and so we always enable
+ * EEH for all slots/all devices.
+ *
+ * The eeh-force-off option disables EEH checking globally, for all slots.
+ * Even if force-off is set, the EEH hardware is still enabled, so that
+ * newer systems can boot.
+ */
+void __init eeh_init(void)
+{
+       struct device_node *phb, *np;
+       struct eeh_early_enable_info info;
+
+       spin_lock_init(&confirm_error_lock);
+       spin_lock_init(&slot_errbuf_lock);
+
+       np = of_find_node_by_path("/rtas");
+       if (np == NULL)
+               return;
+
+       ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
+       ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
+       ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
+       ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
+       ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
+
+       if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
+               return;
+
+       eeh_error_buf_size = rtas_token("rtas-error-log-max");
+       if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
+               eeh_error_buf_size = 1024;
+       }
+       if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
+               printk(KERN_WARNING "EEH: rtas-error-log-max is bigger than allocated "
+                     "buffer ! (%d vs %d)", eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
+               eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
+       }
+
+       /* Enable EEH for all adapters.  Note that eeh requires buid's */
+       for (phb = of_find_node_by_name(NULL, "pci"); phb;
+            phb = of_find_node_by_name(phb, "pci")) {
+               unsigned long buid;
+
+               buid = get_phb_buid(phb);
+               if (buid == 0 || PCI_DN(phb) == NULL)
+                       continue;
+
+               info.buid_lo = BUID_LO(buid);
+               info.buid_hi = BUID_HI(buid);
+               traverse_pci_devices(phb, early_enable_eeh, &info);
+       }
+
+       if (eeh_subsystem_enabled)
+               printk(KERN_INFO "EEH: PCI Enhanced I/O Error Handling Enabled\n");
+       else
+               printk(KERN_WARNING "EEH: No capable adapters found\n");
+}
+
+/**
+ * eeh_add_device_early - enable EEH for the indicated device_node
+ * @dn: device node for which to set up EEH
+ *
+ * This routine must be used to perform EEH initialization for PCI
+ * devices that were added after system boot (e.g. hotplug, dlpar).
+ * This routine must be called before any i/o is performed to the
+ * adapter (inluding any config-space i/o).
+ * Whether this actually enables EEH or not for this device depends
+ * on the CEC architecture, type of the device, on earlier boot
+ * command-line arguments & etc.
+ */
+void eeh_add_device_early(struct device_node *dn)
+{
+       struct pci_controller *phb;
+       struct eeh_early_enable_info info;
+
+       if (!dn || !PCI_DN(dn))
+               return;
+       phb = PCI_DN(dn)->phb;
+       if (NULL == phb || 0 == phb->buid) {
+               printk(KERN_WARNING "EEH: Expected buid but found none for %s\n",
+                      dn->full_name);
+               dump_stack();
+               return;
+       }
+
+       info.buid_hi = BUID_HI(phb->buid);
+       info.buid_lo = BUID_LO(phb->buid);
+       early_enable_eeh(dn, &info);
+}
+EXPORT_SYMBOL_GPL(eeh_add_device_early);
+
+/**
+ * eeh_add_device_late - perform EEH initialization for the indicated pci device
+ * @dev: pci device for which to set up EEH
+ *
+ * This routine must be used to complete EEH initialization for PCI
+ * devices that were added after system boot (e.g. hotplug, dlpar).
+ */
+void eeh_add_device_late(struct pci_dev *dev)
+{
+       struct device_node *dn;
+       struct pci_dn *pdn;
+
+       if (!dev || !eeh_subsystem_enabled)
+               return;
+
+#ifdef DEBUG
+       printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
+#endif
+
+       pci_dev_get (dev);
+       dn = pci_device_to_OF_node(dev);
+       pdn = PCI_DN(dn);
+       pdn->pcidev = dev;
+
+       pci_addr_cache_insert_device (dev);
+       eeh_save_bars(dev, pdn);
+}
+EXPORT_SYMBOL_GPL(eeh_add_device_late);
+
+/**
+ * eeh_remove_device - undo EEH setup for the indicated pci device
+ * @dev: pci device to be removed
+ *
+ * This routine should be when a device is removed from a running
+ * system (e.g. by hotplug or dlpar).
+ */
+void eeh_remove_device(struct pci_dev *dev)
+{
+       struct device_node *dn;
+       if (!dev || !eeh_subsystem_enabled)
+               return;
+
+       /* Unregister the device with the EEH/PCI address search system */
+#ifdef DEBUG
+       printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
+#endif
+       pci_addr_cache_remove_device(dev);
+
+       dn = pci_device_to_OF_node(dev);
+       PCI_DN(dn)->pcidev = NULL;
+       pci_dev_put (dev);
+}
+EXPORT_SYMBOL_GPL(eeh_remove_device);
+
+static int proc_eeh_show(struct seq_file *m, void *v)
+{
+       unsigned int cpu;
+       unsigned long ffs = 0, positives = 0, failures = 0;
+       unsigned long resets = 0;
+       unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0;
+
+       for_each_cpu(cpu) {
+               ffs += per_cpu(total_mmio_ffs, cpu);
+               positives += per_cpu(false_positives, cpu);
+               failures += per_cpu(ignored_failures, cpu);
+               resets += per_cpu(slot_resets, cpu);
+               no_dev += per_cpu(no_device, cpu);
+               no_dn += per_cpu(no_dn, cpu);
+               no_cfg += per_cpu(no_cfg_addr, cpu);
+               no_check += per_cpu(ignored_check, cpu);
+       }
+
+       if (0 == eeh_subsystem_enabled) {
+               seq_printf(m, "EEH Subsystem is globally disabled\n");
+               seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs);
+       } else {
+               seq_printf(m, "EEH Subsystem is enabled\n");
+               seq_printf(m,
+                               "no device=%ld\n"
+                               "no device node=%ld\n"
+                               "no config address=%ld\n"
+                               "check not wanted=%ld\n"
+                               "eeh_total_mmio_ffs=%ld\n"
+                               "eeh_false_positives=%ld\n"
+                               "eeh_ignored_failures=%ld\n"
+                               "eeh_slot_resets=%ld\n",
+                               no_dev, no_dn, no_cfg, no_check,
+                               ffs, positives, failures, resets);
+       }
+
+       return 0;
+}
+
+static int proc_eeh_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_eeh_show, NULL);
+}
+
+static struct file_operations proc_eeh_operations = {
+       .open      = proc_eeh_open,
+       .read      = seq_read,
+       .llseek    = seq_lseek,
+       .release   = single_release,
+};
+
+static int __init eeh_init_proc(void)
+{
+       struct proc_dir_entry *e;
+
+       if (platform_is_pseries()) {
+               e = create_proc_entry("ppc64/eeh", 0, NULL);
+               if (e)
+                       e->proc_fops = &proc_eeh_operations;
+       }
+
+       return 0;
+}
+__initcall(eeh_init_proc);
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
new file mode 100644 (file)
index 0000000..9249733
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * eeh_event.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.
+ *
+ * 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
+ *
+ * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
+ */
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <asm/eeh_event.h>
+
+/** Overview:
+ *  EEH error states may be detected within exception handlers;
+ *  however, the recovery processing needs to occur asynchronously
+ *  in a normal kernel context and not an interrupt context.
+ *  This pair of routines creates an event and queues it onto a
+ *  work-queue, where a worker thread can drive recovery.
+ */
+
+/* EEH event workqueue setup. */
+static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED;
+LIST_HEAD(eeh_eventlist);
+static void eeh_thread_launcher(void *);
+DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
+
+/**
+ * eeh_panic - call panic() for an eeh event that cannot be handled.
+ * The philosophy of this routine is that it is better to panic and
+ * halt the OS than it is to risk possible data corruption by
+ * oblivious device drivers that don't know better.
+ *
+ * @dev pci device that had an eeh event
+ * @reset_state current reset state of the device slot
+ */
+static void eeh_panic(struct pci_dev *dev, int reset_state)
+{
+       /*
+        * Since the panic_on_oops sysctl is used to halt the system
+        * in light of potential corruption, we can use it here.
+        */
+       if (panic_on_oops) {
+               panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
+                     pci_name(dev));
+       }
+       else {
+               printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
+                      reset_state, pci_name(dev));
+       }
+}
+
+/**
+ * eeh_event_handler - dispatch EEH events.  The detection of a frozen
+ * slot can occur inside an interrupt, where it can be hard to do
+ * anything about it.  The goal of this routine is to pull these
+ * detection events out of the context of the interrupt handler, and
+ * re-dispatch them for processing at a later time in a normal context.
+ *
+ * @dummy - unused
+ */
+static int eeh_event_handler(void * dummy)
+{
+       unsigned long flags;
+       struct eeh_event        *event;
+
+       daemonize ("eehd");
+
+       while (1) {
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               spin_lock_irqsave(&eeh_eventlist_lock, flags);
+               event = NULL;
+               if (!list_empty(&eeh_eventlist)) {
+                       event = list_entry(eeh_eventlist.next, struct eeh_event, list);
+                       list_del(&event->list);
+               }
+               spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+               if (event == NULL)
+                       break;
+
+               printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
+                      pci_name(event->dev));
+
+               eeh_panic (event->dev, event->state);
+
+               kfree(event);
+       }
+
+       return 0;
+}
+
+/**
+ * eeh_thread_launcher
+ *
+ * @dummy - unused
+ */
+static void eeh_thread_launcher(void *dummy)
+{
+       if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
+               printk(KERN_ERR "Failed to start EEH daemon\n");
+}
+
+/**
+ * eeh_send_failure_event - generate a PCI error event
+ * @dev pci device
+ *
+ * This routine can be called within an interrupt context;
+ * the actual event will be delivered in a normal context
+ * (from a workqueue).
+ */
+int eeh_send_failure_event (struct device_node *dn,
+                            struct pci_dev *dev,
+                            int state,
+                            int time_unavail)
+{
+       unsigned long flags;
+       struct eeh_event *event;
+
+       event = kmalloc(sizeof(*event), GFP_ATOMIC);
+       if (event == NULL) {
+               printk (KERN_ERR "EEH: out of memory, event not handled\n");
+               return 1;
+       }
+
+       if (dev)
+               pci_dev_get(dev);
+
+       event->dn = dn;
+       event->dev = dev;
+       event->state = state;
+       event->time_unavail = time_unavail;
+
+       /* We may or may not be called in an interrupt context */
+       spin_lock_irqsave(&eeh_eventlist_lock, flags);
+       list_add(&event->list, &eeh_eventlist);
+       spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+
+       schedule_work(&eeh_event_wq);
+
+       return 0;
+}
+
+/********************** END OF FILE ******************************/
index fcc50bfd43fd35d560175b89917bbc51d4c56cfb..97ba5214417f856a7371652e0df54a6863ab5085 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
 #include <asm/pSeries_reconfig.h>
-#include <asm/systemcfg.h>
 #include <asm/firmware.h>
 #include <asm/tce.h>
 #include <asm/ppc-pci.h>
@@ -582,7 +581,7 @@ void iommu_init_early_pSeries(void)
                return;
        }
 
-       if (systemcfg->platform & PLATFORM_LPAR) {
+       if (platform_is_lpar()) {
                if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
                        ppc_md.tce_build = tce_buildmulti_pSeriesLP;
                        ppc_md.tce_free  = tce_freemulti_pSeriesLP;
index c198656a3bb5723faae617ec52406a17a718ff02..999a9620b5ce0f13f89cc08a8d75895ca46cad97 100644 (file)
@@ -107,7 +107,6 @@ static void __init pSeries_request_regions(void)
 
 void __init pSeries_final_fixup(void)
 {
-       phbs_remap_io();
        pSeries_request_regions();
 
        pci_addr_cache_build();
@@ -123,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
        int i;
        unsigned int reg;
 
-       if (!(systemcfg->platform & PLATFORM_PSERIES))
+       if (!platform_is_pseries())
                return;
 
        printk("Using INTC for W82c105 IDE controller.\n");
index d7d400339458d2e5e159bd67633bc919e8b8eed6..d8864164dbe809c85c012fe03957e96d4b398ff4 100644 (file)
@@ -408,7 +408,7 @@ static int proc_ppc64_create_ofdt(void)
 {
        struct proc_dir_entry *ent;
 
-       if (!(systemcfg->platform & PLATFORM_PSERIES))
+       if (!platform_is_pseries())
                return 0;
 
        ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
index e26b0420b6ddea490c8a6fb8f81a0bd9ac351422..00cf331a1dc4dd1c53de8e72c044611f5b8a1ee2 100644 (file)
@@ -482,10 +482,12 @@ static int __init rtas_init(void)
 {
        struct proc_dir_entry *entry;
 
-       /* No RTAS, only warn if we are on a pSeries box  */
+       if (!platform_is_pseries())
+               return 0;
+
+       /* No RTAS */
        if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
-               if (systemcfg->platform & PLATFORM_PSERIES)
-                       printk(KERN_INFO "rtasd: no event-scan on system\n");
+               printk(KERN_INFO "rtasd: no event-scan on system\n");
                return 1;
        }
 
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
new file mode 100644 (file)
index 0000000..2edc947
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ *  c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ *
+ * scan-log-data driver for PPC64  Todd Inglett <tinglett@vnet.ibm.com>
+ *
+ * When ppc64 hardware fails the service processor dumps internal state
+ * of the system.  After a reboot the operating system can access a dump
+ * of this data using this driver.  A dump exists if the device-tree
+ * /chosen/ibm,scan-log-data property exists.
+ *
+ * This driver exports /proc/ppc64/scan-log-dump which can be read.
+ * The driver supports only sequential reads.
+ *
+ * The driver looks at a write to the driver for the single word "reset".
+ * If given, the driver will reset the scanlog so the platform can free it.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+
+#define MODULE_VERS "1.0"
+#define MODULE_NAME "scanlog"
+
+/* Status returns from ibm,scan-log-dump */
+#define SCANLOG_COMPLETE 0
+#define SCANLOG_HWERROR -1
+#define SCANLOG_CONTINUE 1
+
+#define DEBUG(A...) do { if (scanlog_debug) printk(KERN_ERR "scanlog: " A); } while (0)
+
+static int scanlog_debug;
+static unsigned int ibm_scan_log_dump;                 /* RTAS token */
+static struct proc_dir_entry *proc_ppc64_scan_log_dump;        /* The proc file */
+
+static ssize_t scanlog_read(struct file *file, char __user *buf,
+                           size_t count, loff_t *ppos)
+{
+        struct inode * inode = file->f_dentry->d_inode;
+       struct proc_dir_entry *dp;
+       unsigned int *data;
+       int status;
+       unsigned long len, off;
+       unsigned int wait_time;
+
+        dp = PDE(inode);
+       data = (unsigned int *)dp->data;
+
+       if (!data) {
+               printk(KERN_ERR "scanlog: read failed no data\n");
+               return -EIO;
+       }
+
+       if (count > RTAS_DATA_BUF_SIZE)
+               count = RTAS_DATA_BUF_SIZE;
+
+       if (count < 1024) {
+               /* This is the min supported by this RTAS call.  Rather
+                * than do all the buffering we insist the user code handle
+                * larger reads.  As long as cp works... :)
+                */
+               printk(KERN_ERR "scanlog: cannot perform a small read (%ld)\n", count);
+               return -EINVAL;
+       }
+
+       if (!access_ok(VERIFY_WRITE, buf, count))
+               return -EFAULT;
+
+       for (;;) {
+               wait_time = 500;        /* default wait if no data */
+               spin_lock(&rtas_data_buf_lock);
+               memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE);
+               status = rtas_call(ibm_scan_log_dump, 2, 1, NULL,
+                                  (u32) __pa(rtas_data_buf), (u32) count);
+               memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE);
+               spin_unlock(&rtas_data_buf_lock);
+
+               DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n",
+                     status, data[0], data[1], data[2]);
+               switch (status) {
+                   case SCANLOG_COMPLETE:
+                       DEBUG("hit eof\n");
+                       return 0;
+                   case SCANLOG_HWERROR:
+                       DEBUG("hardware error reading scan log data\n");
+                       return -EIO;
+                   case SCANLOG_CONTINUE:
+                       /* We may or may not have data yet */
+                       len = data[1];
+                       off = data[2];
+                       if (len > 0) {
+                               if (copy_to_user(buf, ((char *)data)+off, len))
+                                       return -EFAULT;
+                               return len;
+                       }
+                       /* Break to sleep default time */
+                       break;
+                   default:
+                       if (status > 9900 && status <= 9905) {
+                               wait_time = rtas_extended_busy_delay_time(status);
+                       } else {
+                               printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status);
+                               return -EIO;
+                       }
+               }
+               /* Apparently no data yet.  Wait and try again. */
+               msleep_interruptible(wait_time);
+       }
+       /*NOTREACHED*/
+}
+
+static ssize_t scanlog_write(struct file * file, const char __user * buf,
+                            size_t count, loff_t *ppos)
+{
+       char stkbuf[20];
+       int status;
+
+       if (count > 19) count = 19;
+       if (copy_from_user (stkbuf, buf, count)) {
+               return -EFAULT;
+       }
+       stkbuf[count] = 0;
+
+       if (buf) {
+               if (strncmp(stkbuf, "reset", 5) == 0) {
+                       DEBUG("reset scanlog\n");
+                       status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0);
+                       DEBUG("rtas returns %d\n", status);
+               } else if (strncmp(stkbuf, "debugon", 7) == 0) {
+                       printk(KERN_ERR "scanlog: debug on\n");
+                       scanlog_debug = 1;
+               } else if (strncmp(stkbuf, "debugoff", 8) == 0) {
+                       printk(KERN_ERR "scanlog: debug off\n");
+                       scanlog_debug = 0;
+               }
+       }
+       return count;
+}
+
+static int scanlog_open(struct inode * inode, struct file * file)
+{
+       struct proc_dir_entry *dp = PDE(inode);
+       unsigned int *data = (unsigned int *)dp->data;
+
+       if (!data) {
+               printk(KERN_ERR "scanlog: open failed no data\n");
+               return -EIO;
+       }
+
+       if (data[0] != 0) {
+               /* This imperfect test stops a second copy of the
+                * data (or a reset while data is being copied)
+                */
+               return -EBUSY;
+       }
+
+       data[0] = 0;    /* re-init so we restart the scan */
+
+       return 0;
+}
+
+static int scanlog_release(struct inode * inode, struct file * file)
+{
+       struct proc_dir_entry *dp = PDE(inode);
+       unsigned int *data = (unsigned int *)dp->data;
+
+       if (!data) {
+               printk(KERN_ERR "scanlog: release failed no data\n");
+               return -EIO;
+       }
+       data[0] = 0;
+
+       return 0;
+}
+
+struct file_operations scanlog_fops = {
+       .owner          = THIS_MODULE,
+       .read           = scanlog_read,
+       .write          = scanlog_write,
+       .open           = scanlog_open,
+       .release        = scanlog_release,
+};
+
+int __init scanlog_init(void)
+{
+       struct proc_dir_entry *ent;
+
+       ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
+       if (ibm_scan_log_dump == RTAS_UNKNOWN_SERVICE) {
+               printk(KERN_ERR "scan-log-dump not implemented on this system\n");
+               return -EIO;
+       }
+
+        ent = create_proc_entry("ppc64/rtas/scan-log-dump",  S_IRUSR, NULL);
+       if (ent) {
+               ent->proc_fops = &scanlog_fops;
+               /* Ideally we could allocate a buffer < 4G */
+               ent->data = kmalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+               if (!ent->data) {
+                       printk(KERN_ERR "Failed to allocate a buffer\n");
+                       remove_proc_entry("scan-log-dump", ent->parent);
+                       return -ENOMEM;
+               }
+               ((unsigned int *)ent->data)[0] = 0;
+       } else {
+               printk(KERN_ERR "Failed to create ppc64/scan-log-dump proc entry\n");
+               return -EIO;
+       }
+       proc_ppc64_scan_log_dump = ent;
+
+       return 0;
+}
+
+void __exit scanlog_cleanup(void)
+{
+       if (proc_ppc64_scan_log_dump) {
+               kfree(proc_ppc64_scan_log_dump->data);
+               remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
+       }
+}
+
+module_init(scanlog_init);
+module_exit(scanlog_cleanup);
+MODULE_LICENSE("GPL");
index a093a0d4dd69d15c03f7379521e7e54dae6b1f94..e94247c28d422a321def8829c0ca3db2daa8429e 100644 (file)
@@ -249,7 +249,7 @@ static void __init pSeries_setup_arch(void)
                ppc_md.idle_loop = default_idle;
        }
 
-       if (systemcfg->platform & PLATFORM_LPAR)
+       if (platform_is_lpar())
                ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
        else
                ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -378,7 +378,7 @@ static void __init pSeries_init_early(void)
 
        fw_feature_init();
        
-       if (systemcfg->platform & PLATFORM_LPAR)
+       if (platform_is_lpar())
                hpte_init_lpar();
        else {
                hpte_init_native();
@@ -388,7 +388,7 @@ static void __init pSeries_init_early(void)
 
        generic_find_legacy_serial_ports(&physport, &default_speed);
 
-       if (systemcfg->platform & PLATFORM_LPAR)
+       if (platform_is_lpar())
                find_udbg_vterm();
        else if (physport) {
                /* Map the uart for udbg. */
@@ -592,7 +592,7 @@ static void pseries_shared_idle(void)
 
 static int pSeries_pci_probe_mode(struct pci_bus *bus)
 {
-       if (systemcfg->platform & PLATFORM_LPAR)
+       if (platform_is_lpar())
                return PCI_PROBE_DEVTREE;
        return PCI_PROBE_NORMAL;
 }
index 7a243e8ccd7ea254002a84d2442ab173c8c8920f..3ba794ca3288c72fbed747cf1f254fdd5c8ed59a 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/rtas.h>
 #include <asm/pSeries_reconfig.h>
 #include <asm/mpic.h>
+#include <asm/systemcfg.h>
 
 #include "plpar_wrappers.h"
 
@@ -96,7 +97,7 @@ int pSeries_cpu_disable(void)
        int cpu = smp_processor_id();
 
        cpu_clear(cpu, cpu_online_map);
-       systemcfg->processorCount--;
+       _systemcfg->processorCount--;
 
        /*fix boot_cpuid here*/
        if (cpu == boot_cpuid)
@@ -441,7 +442,7 @@ void __init smp_init_pSeries(void)
        smp_ops->cpu_die = pSeries_cpu_die;
 
        /* Processors can be added/removed only on LPAR */
-       if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+       if (platform_is_lpar())
                pSeries_reconfig_notifier_register(&pSeries_smp_nb);
 #endif
 
index c72c86f05cb6533f4c1645001e9d5d42d3f029ff..72ac18067ecef58c4af36c49502e387be119d3fd 100644 (file)
@@ -545,7 +545,9 @@ nextnode:
                of_node_put(np);
        }
 
-       if (systemcfg->platform == PLATFORM_PSERIES) {
+       if (platform_is_lpar())
+               ops = &pSeriesLP_ops;
+       else {
 #ifdef CONFIG_SMP
                for_each_cpu(i) {
                        int hard_id;
@@ -561,12 +563,11 @@ nextnode:
 #else
                xics_per_cpu[0] = ioremap(intr_base, intr_size);
 #endif /* CONFIG_SMP */
-       } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
-               ops = &pSeriesLP_ops;
        }
 
        xics_8259_pic.enable = i8259_pic.enable;
        xics_8259_pic.disable = i8259_pic.disable;
+       xics_8259_pic.end = i8259_pic.end;
        for (i = 0; i < 16; ++i)
                get_irq_desc(i)->handler = &xics_8259_pic;
        for (; i < NR_IRQS; ++i)
index 543d6590981248ff1ebdff05822c36aaeefe9ca0..f32baf7f4693eb0980c3a42ba366492fb9c0517e 100644 (file)
@@ -226,7 +226,7 @@ static void iommu_table_u3_setup(void)
        iommu_table_u3.it_busno = 0;
        iommu_table_u3.it_offset = 0;
        /* it_size is in number of entries */
-       iommu_table_u3.it_size = dart_tablesize / sizeof(u32);
+       iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
 
        /* Initialize the common IOMMU code */
        iommu_table_u3.it_base = (unsigned long)dart_vbase;
index 79a784f0e7a94aee5f2e83c871c25f52d9b39ce6..b20312e5ed271784bbeb79495ca122541d68707a 100644 (file)
@@ -8,4 +8,4 @@ obj-$(CONFIG_8xx)       += start_8xx.o
 obj-$(CONFIG_6xx)      += start_32.o
 obj-$(CONFIG_4xx)      += start_32.o
 obj-$(CONFIG_PPC64)    += start_64.o
-obj-y                  += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+obj-y                  += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c
new file mode 100644 (file)
index 0000000..7876583
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ *      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/string.h>
+#include <asm/time.h>
+#include "nonstdio.h"
+
+int xmon_putchar(int c)
+{
+       char ch = c;
+
+       if (c == '\n')
+               xmon_putchar('\r');
+       return xmon_write(&ch, 1) == 1? c: -1;
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned long timeout)
+{
+       int c;
+       unsigned long t0;
+
+       /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
+       timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
+       t0 = get_tbl();
+       do {
+               lineptr = line;
+               for (;;) {
+                       c = xmon_read_poll();
+                       if (c == -1) {
+                               if (get_tbl() - t0 > timeout)
+                                       return 0;
+                               continue;
+                       }
+                       if (c == '\n')
+                               break;
+                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+                               *lineptr++ = c;
+               }
+               *lineptr = 0;
+       } while (strstr(line, str) == NULL);
+       return 1;
+}
+
+int xmon_getchar(void)
+{
+       int c;
+
+       if (lineleft == 0) {
+               lineptr = line;
+               for (;;) {
+                       c = xmon_readchar();
+                       if (c == -1 || c == 4)
+                               break;
+                       if (c == '\r' || c == '\n') {
+                               *lineptr++ = '\n';
+                               xmon_putchar('\n');
+                               break;
+                       }
+                       switch (c) {
+                       case 0177:
+                       case '\b':
+                               if (lineptr > line) {
+                                       xmon_putchar('\b');
+                                       xmon_putchar(' ');
+                                       xmon_putchar('\b');
+                                       --lineptr;
+                               }
+                               break;
+                       case 'U' & 0x1F:
+                               while (lineptr > line) {
+                                       xmon_putchar('\b');
+                                       xmon_putchar(' ');
+                                       xmon_putchar('\b');
+                                       --lineptr;
+                               }
+                               break;
+                       default:
+                               if (lineptr >= &line[sizeof(line) - 1])
+                                       xmon_putchar('\a');
+                               else {
+                                       xmon_putchar(c);
+                                       *lineptr++ = c;
+                               }
+                       }
+               }
+               lineleft = lineptr - line;
+               lineptr = line;
+       }
+       if (lineleft == 0)
+               return -1;
+       --lineleft;
+       return *lineptr++;
+}
+
+char *xmon_gets(char *str, int nb)
+{
+       char *p;
+       int c;
+
+       for (p = str; p < str + nb - 1; ) {
+               c = xmon_getchar();
+               if (c == -1) {
+                       if (p == str)
+                               return NULL;
+                       break;
+               }
+               *p++ = c;
+               if (c == '\n')
+                       break;
+       }
+       *p = 0;
+       return str;
+}
+
+void xmon_printf(const char *format, ...)
+{
+       va_list args;
+       int n;
+       static char xmon_outbuf[1024];
+
+       va_start(args, format);
+       n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
+       va_end(args);
+       xmon_write(xmon_outbuf, n);
+}
index 84211a21c6f4495e14a1895a648a1adc6a9b8bd9..47cebbd2b1b1b06e3d53d99c9dc3a41eb42b6db2 100644 (file)
@@ -1,22 +1,14 @@
-typedef int    FILE;
-extern FILE *xmon_stdin, *xmon_stdout;
 #define EOF    (-1)
-#define stdin  xmon_stdin
-#define stdout xmon_stdout
+
 #define printf xmon_printf
-#define fprintf        xmon_fprintf
-#define fputs  xmon_fputs
-#define fgets  xmon_fgets
 #define putchar        xmon_putchar
-#define getchar        xmon_getchar
-#define putc   xmon_putc
-#define getc   xmon_getc
-#define fopen(n, m)    NULL
-#define fflush(f)      do {} while (0)
-#define fclose(f)      do {} while (0)
-extern char *fgets(char *, int, void *);
-extern void xmon_printf(const char *, ...);
-extern void xmon_fprintf(void *, const char *, ...);
-extern void xmon_sprintf(char *, const char *, ...);
 
-#define perror(s)      printf("%s: no files!\n", (s))
+extern int xmon_putchar(int c);
+extern int xmon_getchar(void);
+extern char *xmon_gets(char *, int);
+extern void xmon_printf(const char *, ...);
+extern void xmon_map_scc(void);
+extern int xmon_expect(const char *str, unsigned long timeout);
+extern int xmon_write(void *ptr, int nb);
+extern int xmon_readchar(void);
+extern int xmon_read_poll(void);
index f8e40dfd2bff8e15866b4b0ea0f0ca33229951e6..96a91f10e2ec52ed5e05f3cdda3841e37c5fd61a 100644 (file)
 
 _GLOBAL(xmon_setjmp)
        mflr    r0
-       STL     r0,0(r3)
-       STL     r1,SZL(r3)
-       STL     r2,2*SZL(r3)
+       PPC_STL r0,0(r3)
+       PPC_STL r1,SZL(r3)
+       PPC_STL r2,2*SZL(r3)
        mfcr    r0
-       STL     r0,3*SZL(r3)
-       STL     r13,4*SZL(r3)
-       STL     r14,5*SZL(r3)
-       STL     r15,6*SZL(r3)
-       STL     r16,7*SZL(r3)
-       STL     r17,8*SZL(r3)
-       STL     r18,9*SZL(r3)
-       STL     r19,10*SZL(r3)
-       STL     r20,11*SZL(r3)
-       STL     r21,12*SZL(r3)
-       STL     r22,13*SZL(r3)
-       STL     r23,14*SZL(r3)
-       STL     r24,15*SZL(r3)
-       STL     r25,16*SZL(r3)
-       STL     r26,17*SZL(r3)
-       STL     r27,18*SZL(r3)
-       STL     r28,19*SZL(r3)
-       STL     r29,20*SZL(r3)
-       STL     r30,21*SZL(r3)
-       STL     r31,22*SZL(r3)
+       PPC_STL r0,3*SZL(r3)
+       PPC_STL r13,4*SZL(r3)
+       PPC_STL r14,5*SZL(r3)
+       PPC_STL r15,6*SZL(r3)
+       PPC_STL r16,7*SZL(r3)
+       PPC_STL r17,8*SZL(r3)
+       PPC_STL r18,9*SZL(r3)
+       PPC_STL r19,10*SZL(r3)
+       PPC_STL r20,11*SZL(r3)
+       PPC_STL r21,12*SZL(r3)
+       PPC_STL r22,13*SZL(r3)
+       PPC_STL r23,14*SZL(r3)
+       PPC_STL r24,15*SZL(r3)
+       PPC_STL r25,16*SZL(r3)
+       PPC_STL r26,17*SZL(r3)
+       PPC_STL r27,18*SZL(r3)
+       PPC_STL r28,19*SZL(r3)
+       PPC_STL r29,20*SZL(r3)
+       PPC_STL r30,21*SZL(r3)
+       PPC_STL r31,22*SZL(r3)
        li      r3,0
        blr
 
 _GLOBAL(xmon_longjmp)
-       CMPI    r4,0
+       PPC_LCMPI r4,0
        bne     1f
        li      r4,1
-1:     LDL     r13,4*SZL(r3)
-       LDL     r14,5*SZL(r3)
-       LDL     r15,6*SZL(r3)
-       LDL     r16,7*SZL(r3)
-       LDL     r17,8*SZL(r3)
-       LDL     r18,9*SZL(r3)
-       LDL     r19,10*SZL(r3)
-       LDL     r20,11*SZL(r3)
-       LDL     r21,12*SZL(r3)
-       LDL     r22,13*SZL(r3)
-       LDL     r23,14*SZL(r3)
-       LDL     r24,15*SZL(r3)
-       LDL     r25,16*SZL(r3)
-       LDL     r26,17*SZL(r3)
-       LDL     r27,18*SZL(r3)
-       LDL     r28,19*SZL(r3)
-       LDL     r29,20*SZL(r3)
-       LDL     r30,21*SZL(r3)
-       LDL     r31,22*SZL(r3)
-       LDL     r0,3*SZL(r3)
+1:     PPC_LL  r13,4*SZL(r3)
+       PPC_LL  r14,5*SZL(r3)
+       PPC_LL  r15,6*SZL(r3)
+       PPC_LL  r16,7*SZL(r3)
+       PPC_LL  r17,8*SZL(r3)
+       PPC_LL  r18,9*SZL(r3)
+       PPC_LL  r19,10*SZL(r3)
+       PPC_LL  r20,11*SZL(r3)
+       PPC_LL  r21,12*SZL(r3)
+       PPC_LL  r22,13*SZL(r3)
+       PPC_LL  r23,14*SZL(r3)
+       PPC_LL  r24,15*SZL(r3)
+       PPC_LL  r25,16*SZL(r3)
+       PPC_LL  r26,17*SZL(r3)
+       PPC_LL  r27,18*SZL(r3)
+       PPC_LL  r28,19*SZL(r3)
+       PPC_LL  r29,20*SZL(r3)
+       PPC_LL  r30,21*SZL(r3)
+       PPC_LL  r31,22*SZL(r3)
+       PPC_LL  r0,3*SZL(r3)
        mtcrf   0x38,r0
-       LDL     r0,0(r3)
-       LDL     r1,SZL(r3)
-       LDL     r2,2*SZL(r3)
+       PPC_LL  r0,0(r3)
+       PPC_LL  r1,SZL(r3)
+       PPC_LL  r2,2*SZL(r3)
        mtlr    r0
        mr      r3,r4
        blr
@@ -84,52 +84,52 @@ _GLOBAL(xmon_longjmp)
  * different ABIs, though).
  */
 _GLOBAL(xmon_save_regs)
-       STL     r0,0*SZL(r3)
-       STL     r2,2*SZL(r3)
-       STL     r3,3*SZL(r3)
-       STL     r4,4*SZL(r3)
-       STL     r5,5*SZL(r3)
-       STL     r6,6*SZL(r3)
-       STL     r7,7*SZL(r3)
-       STL     r8,8*SZL(r3)
-       STL     r9,9*SZL(r3)
-       STL     r10,10*SZL(r3)
-       STL     r11,11*SZL(r3)
-       STL     r12,12*SZL(r3)
-       STL     r13,13*SZL(r3)
-       STL     r14,14*SZL(r3)
-       STL     r15,15*SZL(r3)
-       STL     r16,16*SZL(r3)
-       STL     r17,17*SZL(r3)
-       STL     r18,18*SZL(r3)
-       STL     r19,19*SZL(r3)
-       STL     r20,20*SZL(r3)
-       STL     r21,21*SZL(r3)
-       STL     r22,22*SZL(r3)
-       STL     r23,23*SZL(r3)
-       STL     r24,24*SZL(r3)
-       STL     r25,25*SZL(r3)
-       STL     r26,26*SZL(r3)
-       STL     r27,27*SZL(r3)
-       STL     r28,28*SZL(r3)
-       STL     r29,29*SZL(r3)
-       STL     r30,30*SZL(r3)
-       STL     r31,31*SZL(r3)
+       PPC_STL r0,0*SZL(r3)
+       PPC_STL r2,2*SZL(r3)
+       PPC_STL r3,3*SZL(r3)
+       PPC_STL r4,4*SZL(r3)
+       PPC_STL r5,5*SZL(r3)
+       PPC_STL r6,6*SZL(r3)
+       PPC_STL r7,7*SZL(r3)
+       PPC_STL r8,8*SZL(r3)
+       PPC_STL r9,9*SZL(r3)
+       PPC_STL r10,10*SZL(r3)
+       PPC_STL r11,11*SZL(r3)
+       PPC_STL r12,12*SZL(r3)
+       PPC_STL r13,13*SZL(r3)
+       PPC_STL r14,14*SZL(r3)
+       PPC_STL r15,15*SZL(r3)
+       PPC_STL r16,16*SZL(r3)
+       PPC_STL r17,17*SZL(r3)
+       PPC_STL r18,18*SZL(r3)
+       PPC_STL r19,19*SZL(r3)
+       PPC_STL r20,20*SZL(r3)
+       PPC_STL r21,21*SZL(r3)
+       PPC_STL r22,22*SZL(r3)
+       PPC_STL r23,23*SZL(r3)
+       PPC_STL r24,24*SZL(r3)
+       PPC_STL r25,25*SZL(r3)
+       PPC_STL r26,26*SZL(r3)
+       PPC_STL r27,27*SZL(r3)
+       PPC_STL r28,28*SZL(r3)
+       PPC_STL r29,29*SZL(r3)
+       PPC_STL r30,30*SZL(r3)
+       PPC_STL r31,31*SZL(r3)
        /* go up one stack frame for SP */
-       LDL     r4,0(r1)
-       STL     r4,1*SZL(r3)
+       PPC_LL  r4,0(r1)
+       PPC_STL r4,1*SZL(r3)
        /* get caller's LR */
-       LDL     r0,LRSAVE(r4)
-       STL     r0,_NIP-STACK_FRAME_OVERHEAD(r3)
-       STL     r0,_LINK-STACK_FRAME_OVERHEAD(r3)
+       PPC_LL  r0,LRSAVE(r4)
+       PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
        mfmsr   r0
-       STL     r0,_MSR-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
        mfctr   r0
-       STL     r0,_CTR-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
        mfxer   r0
-       STL     r0,_XER-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
        mfcr    r0
-       STL     r0,_CCR-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
        li      r0,0
-       STL     r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
        blr
index 69b658c0f7608df2e04e130b22db83cbbe8d44af..c2464df4217eac408c51e4b2b18ca47fb9e91a54 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/cuda.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/sysrq.h>
 #include <linux/bitops.h>
 #include <asm/xmon.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
 #include <asm/btext.h>
+#include <asm/time.h>
+#include "nonstdio.h"
 
 static volatile unsigned char __iomem *sccc, *sccd;
 unsigned int TXRDY, RXRDY, DLAB;
-static int xmon_expect(const char *str, unsigned int timeout);
 
 static int use_serial;
 static int use_screen;
@@ -33,16 +33,6 @@ static int via_modem;
 static int xmon_use_sccb;
 static struct device_node *channel_node;
 
-#define TB_SPEED       25000000
-
-static inline unsigned int readtb(void)
-{
-       unsigned int ret;
-
-       asm volatile("mftb %0" : "=r" (ret) :);
-       return ret;
-}
-
 void buf_access(void)
 {
        if (DLAB)
@@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void)
 }
 #endif /* CONFIG_PPC_CHRP */
 
-#ifdef CONFIG_MAGIC_SYSRQ
-static void sysrq_handle_xmon(int key, struct pt_regs *regs,
-                             struct tty_struct *tty)
-{
-       xmon(regs);
-}
-
-static struct sysrq_key_op sysrq_xmon_op =
-{
-       .handler =      sysrq_handle_xmon,
-       .help_msg =     "Xmon",
-       .action_msg =   "Entering xmon",
-};
-#endif
-
-void
-xmon_map_scc(void)
+void xmon_map_scc(void)
 {
 #ifdef CONFIG_PPC_MULTIPLATFORM
        volatile unsigned char __iomem *base;
@@ -217,8 +191,6 @@ xmon_map_scc(void)
        RXRDY = 1;
        DLAB = 0x80;
 #endif /* platform */
-
-       register_sysrq_key('x', &sysrq_xmon_op);
 }
 
 static int scc_initialized = 0;
@@ -238,8 +210,7 @@ static inline void do_poll_adb(void)
 #endif /* CONFIG_ADB_CUDA */
 }
 
-int
-xmon_write(void *handle, void *ptr, int nb)
+int xmon_write(void *ptr, int nb)
 {
        char *p = ptr;
        int i, c, ct;
@@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] =
        "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
        "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
 
-static int
-xmon_get_adb_key(void)
+static int xmon_get_adb_key(void)
 {
        int k, t, on;
 
@@ -350,32 +320,21 @@ xmon_get_adb_key(void)
 }
 #endif /* CONFIG_BOOTX_TEXT */
 
-int
-xmon_read(void *handle, void *ptr, int nb)
+int xmon_readchar(void)
 {
-    char *p = ptr;
-    int i;
-
 #ifdef CONFIG_BOOTX_TEXT
-    if (use_screen) {
-       for (i = 0; i < nb; ++i)
-           *p++ = xmon_get_adb_key();
-       return i;
-    }
+       if (use_screen)
+               return xmon_get_adb_key();
 #endif
-    if (!scc_initialized)
-       xmon_init_scc();
-    for (i = 0; i < nb; ++i) {
+       if (!scc_initialized)
+               xmon_init_scc();
        while ((*sccc & RXRDY) == 0)
-           do_poll_adb();
+               do_poll_adb();
        buf_access();
-       *p++ = *sccd;
-    }
-    return i;
+       return *sccd;
 }
 
-int
-xmon_read_poll(void)
+int xmon_read_poll(void)
 {
        if ((*sccc & RXRDY) == 0) {
                do_poll_adb();
@@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = {
     3,  0xc1,          /* rx enable, 8 bits */
 };
 
-void
-xmon_init_scc(void)
+void xmon_init_scc(void)
 {
        if ( _machine == _MACH_chrp )
        {
@@ -410,6 +368,7 @@ xmon_init_scc(void)
        else if ( _machine == _MACH_Pmac )
        {
                int i, x;
+               unsigned long timeout;
 
                if (channel_node != 0)
                        pmac_call_feature(
@@ -424,8 +383,12 @@ xmon_init_scc(void)
                                PMAC_FTR_MODEM_ENABLE,
                                channel_node, 0, 1);
                        printk(KERN_INFO "Modem powered up by debugger !\n");
-                       t0 = readtb();
-                       while (readtb() - t0 < 3*TB_SPEED)
+                       t0 = get_tbl();
+                       timeout = 3 * tb_ticks_per_sec;
+                       if (timeout == 0)
+                               /* assume 25MHz if tb_ticks_per_sec not set */
+                               timeout = 75000000;
+                       while (get_tbl() - t0 < timeout)
                                eieio();
                }
                /* use the B channel if requested */
@@ -447,164 +410,19 @@ xmon_init_scc(void)
        scc_initialized = 1;
        if (via_modem) {
                for (;;) {
-                       xmon_write(NULL, "ATE1V1\r", 7);
+                       xmon_write("ATE1V1\r", 7);
                        if (xmon_expect("OK", 5)) {
-                               xmon_write(NULL, "ATA\r", 4);
+                               xmon_write("ATA\r", 4);
                                if (xmon_expect("CONNECT", 40))
                                        break;
                        }
-                       xmon_write(NULL, "+++", 3);
+                       xmon_write("+++", 3);
                        xmon_expect("OK", 3);
                }
        }
 }
 
-void *xmon_stdin;
-void *xmon_stdout;
-void *xmon_stderr;
-
-int xmon_putc(int c, void *f)
-{
-    char ch = c;
-
-    if (c == '\n')
-       xmon_putc('\r', f);
-    return xmon_write(f, &ch, 1) == 1? c: -1;
-}
-
-int xmon_putchar(int c)
-{
-       return xmon_putc(c, xmon_stdout);
-}
-
-int xmon_fputs(char *str, void *f)
-{
-       int n = strlen(str);
-
-       return xmon_write(f, str, n) == n? 0: -1;
-}
-
-int
-xmon_readchar(void)
-{
-       char ch;
-
-       for (;;) {
-               switch (xmon_read(xmon_stdin, &ch, 1)) {
-               case 1:
-                       return ch;
-               case -1:
-                       xmon_printf("read(stdin) returned -1\r\n", 0, 0);
-                       return -1;
-               }
-       }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int xmon_expect(const char *str, unsigned int timeout)
-{
-       int c;
-       unsigned int t0;
-
-       timeout *= TB_SPEED;
-       t0 = readtb();
-       do {
-               lineptr = line;
-               for (;;) {
-                       c = xmon_read_poll();
-                       if (c == -1) {
-                               if (readtb() - t0 > timeout)
-                                       return 0;
-                               continue;
-                       }
-                       if (c == '\n')
-                               break;
-                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
-                               *lineptr++ = c;
-               }
-               *lineptr = 0;
-       } while (strstr(line, str) == NULL);
-       return 1;
-}
-
-int
-xmon_getchar(void)
-{
-    int c;
-
-    if (lineleft == 0) {
-       lineptr = line;
-       for (;;) {
-           c = xmon_readchar();
-           if (c == -1 || c == 4)
-               break;
-           if (c == '\r' || c == '\n') {
-               *lineptr++ = '\n';
-               xmon_putchar('\n');
-               break;
-           }
-           switch (c) {
-           case 0177:
-           case '\b':
-               if (lineptr > line) {
-                   xmon_putchar('\b');
-                   xmon_putchar(' ');
-                   xmon_putchar('\b');
-                   --lineptr;
-               }
-               break;
-           case 'U' & 0x1F:
-               while (lineptr > line) {
-                   xmon_putchar('\b');
-                   xmon_putchar(' ');
-                   xmon_putchar('\b');
-                   --lineptr;
-               }
-               break;
-           default:
-               if (lineptr >= &line[sizeof(line) - 1])
-                   xmon_putchar('\a');
-               else {
-                   xmon_putchar(c);
-                   *lineptr++ = c;
-               }
-           }
-       }
-       lineleft = lineptr - line;
-       lineptr = line;
-    }
-    if (lineleft == 0)
-       return -1;
-    --lineleft;
-    return *lineptr++;
-}
-
-char *
-xmon_fgets(char *str, int nb, void *f)
-{
-    char *p;
-    int c;
-
-    for (p = str; p < str + nb - 1; ) {
-       c = xmon_getchar();
-       if (c == -1) {
-           if (p == str)
-               return NULL;
-           break;
-       }
-       *p++ = c;
-       if (c == '\n')
-           break;
-    }
-    *p = 0;
-    return str;
-}
-
-void
-xmon_enter(void)
+void xmon_enter(void)
 {
 #ifdef CONFIG_ADB_PMU
        if (_machine == _MACH_Pmac) {
@@ -613,8 +431,7 @@ xmon_enter(void)
 #endif
 }
 
-void
-xmon_leave(void)
+void xmon_leave(void)
 {
 #ifdef CONFIG_ADB_PMU
        if (_machine == _MACH_Pmac) {
index e50c158191e169fb4a08c23ef04caa842089c91c..712552c4f24215f263d495c75bbbc2cc1cf72481 100644 (file)
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/sysrq.h>
-#include <linux/init.h>
 #include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/processor.h>
 #include <asm/udbg.h>
-#include <asm/system.h>
 #include "nonstdio.h"
 
-#ifdef CONFIG_MAGIC_SYSRQ
-
-static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty) 
-{
-       /* ensure xmon is enabled */
-       xmon_init(1);
-       debugger(pt_regs);
-}
-
-static struct sysrq_key_op sysrq_xmon_op = 
+void xmon_map_scc(void)
 {
-       .handler =      sysrq_handle_xmon,
-       .help_msg =     "Xmon",
-       .action_msg =   "Entering xmon",
-};
-
-static int __init setup_xmon_sysrq(void)
-{
-       register_sysrq_key('x', &sysrq_xmon_op);
-       return 0;
 }
-__initcall(setup_xmon_sysrq);
-#endif /* CONFIG_MAGIC_SYSRQ */
 
-int
-xmon_write(void *handle, void *ptr, int nb)
+int xmon_write(void *ptr, int nb)
 {
        return udbg_write(ptr, nb);
 }
 
-int
-xmon_read(void *handle, void *ptr, int nb)
+int xmon_readchar(void)
 {
-       return udbg_read(ptr, nb);
+       if (udbg_getc)
+               return udbg_getc();
+       return -1;
 }
 
-int
-xmon_read_poll(void)
+int xmon_read_poll(void)
 {
        if (udbg_getc_poll)
                return udbg_getc_poll();
        return -1;
 }
-FILE *xmon_stdin;
-FILE *xmon_stdout;
-
-int
-xmon_putc(int c, void *f)
-{
-       char ch = c;
-
-       if (c == '\n')
-               xmon_putc('\r', f);
-       return xmon_write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-xmon_putchar(int c)
-{
-       return xmon_putc(c, xmon_stdout);
-}
-
-int
-xmon_fputs(char *str, void *f)
-{
-       int n = strlen(str);
-
-       return xmon_write(f, str, n) == n? 0: -1;
-}
-
-int
-xmon_readchar(void)
-{
-       char ch;
-
-       for (;;) {
-               switch (xmon_read(xmon_stdin, &ch, 1)) {
-               case 1:
-                       return ch;
-               case -1:
-                       xmon_printf("read(stdin) returned -1\r\n", 0, 0);
-                       return -1;
-               }
-       }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-xmon_getchar(void)
-{
-       int c;
-
-       if (lineleft == 0) {
-               lineptr = line;
-               for (;;) {
-                       c = xmon_readchar();
-                       if (c == -1 || c == 4)
-                               break;
-                       if (c == '\r' || c == '\n') {
-                               *lineptr++ = '\n';
-                               xmon_putchar('\n');
-                               break;
-                       }
-                       switch (c) {
-                       case 0177:
-                       case '\b':
-                               if (lineptr > line) {
-                                       xmon_putchar('\b');
-                                       xmon_putchar(' ');
-                                       xmon_putchar('\b');
-                                       --lineptr;
-                               }
-                               break;
-                       case 'U' & 0x1F:
-                               while (lineptr > line) {
-                                       xmon_putchar('\b');
-                                       xmon_putchar(' ');
-                                       xmon_putchar('\b');
-                                       --lineptr;
-                               }
-                               break;
-                       default:
-                               if (lineptr >= &line[sizeof(line) - 1])
-                                       xmon_putchar('\a');
-                               else {
-                                       xmon_putchar(c);
-                                       *lineptr++ = c;
-                               }
-                       }
-               }
-               lineleft = lineptr - line;
-               lineptr = line;
-       }
-       if (lineleft == 0)
-               return -1;
-       --lineleft;
-       return *lineptr++;
-}
-
-char *
-xmon_fgets(char *str, int nb, void *f)
-{
-       char *p;
-       int c;
-
-       for (p = str; p < str + nb - 1; ) {
-               c = xmon_getchar();
-               if (c == -1) {
-                       if (p == str)
-                               return NULL;
-                       break;
-               }
-               *p++ = c;
-               if (c == '\n')
-                       break;
-       }
-       *p = 0;
-       return str;
-}
index a48bd594cf61a181b56c608e15b85c6f0babbd30..4c17b0486ad5b7f69bcf79560da162e2df86957d 100644 (file)
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
 #include <asm/commproc.h>
+#include "nonstdio.h"
 
-extern void xmon_printf(const char *fmt, ...);
 extern int xmon_8xx_write(char *str, int nb);
 extern int xmon_8xx_read_poll(void);
 extern int xmon_8xx_read_char(void);
-void prom_drawhex(uint);
-void prom_drawstring(const char *str);
 
-static int use_screen = 1; /* default */
-
-#define TB_SPEED       25000000
-
-static inline unsigned int readtb(void)
-{
-       unsigned int ret;
-
-       asm volatile("mftb %0" : "=r" (ret) :);
-       return ret;
-}
-
-void buf_access(void)
-{
-}
-
-void
-xmon_map_scc(void)
+void xmon_map_scc(void)
 {
-
        cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
-       use_screen = 0;
-       
-       prom_drawstring("xmon uses serial port\n");
 }
 
-static int scc_initialized = 0;
-
 void xmon_init_scc(void);
 
-int
-xmon_write(void *handle, void *ptr, int nb)
+int xmon_write(void *ptr, int nb)
 {
-       char *p = ptr;
-       int i, c, ct;
-
-       if (!scc_initialized)
-               xmon_init_scc();
-
        return(xmon_8xx_write(ptr, nb));
 }
 
-int xmon_wants_key;
-
-int
-xmon_read(void *handle, void *ptr, int nb)
+int xmon_readchar(void)
 {
-       char *p = ptr;
-       int i;
-
-       if (!scc_initialized)
-               xmon_init_scc();
-
-       for (i = 0; i < nb; ++i) {
-               *p++ = xmon_8xx_read_char();
-       }
-       return i;
+       return xmon_8xx_read_char();
 }
 
-int
-xmon_read_poll(void)
+int xmon_read_poll(void)
 {
        return(xmon_8xx_read_poll());
 }
-
-void
-xmon_init_scc()
-{
-       scc_initialized = 1;
-}
-
-#if 0
-extern int (*prom_entry)(void *);
-
-int
-xmon_exit(void)
-{
-    struct prom_args {
-       char *service;
-    } args;
-
-    for (;;) {
-       args.service = "exit";
-       (*prom_entry)(&args);
-    }
-}
-#endif
-
-void *xmon_stdin;
-void *xmon_stdout;
-void *xmon_stderr;
-
-void
-xmon_init(void)
-{
-}
-
-int
-xmon_putc(int c, void *f)
-{
-    char ch = c;
-
-    if (c == '\n')
-       xmon_putc('\r', f);
-    return xmon_write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-xmon_putchar(int c)
-{
-    return xmon_putc(c, xmon_stdout);
-}
-
-int
-xmon_fputs(char *str, void *f)
-{
-    int n = strlen(str);
-
-    return xmon_write(f, str, n) == n? 0: -1;
-}
-
-int
-xmon_readchar(void)
-{
-    char ch;
-
-    for (;;) {
-       switch (xmon_read(xmon_stdin, &ch, 1)) {
-       case 1:
-           return ch;
-       case -1:
-           xmon_printf("read(stdin) returned -1\r\n", 0, 0);
-           return -1;
-       }
-    }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-#if 0
-int xmon_expect(const char *str, unsigned int timeout)
-{
-       int c;
-       unsigned int t0;
-
-       timeout *= TB_SPEED;
-       t0 = readtb();
-       do {
-               lineptr = line;
-               for (;;) {
-                       c = xmon_read_poll();
-                       if (c == -1) {
-                               if (readtb() - t0 > timeout)
-                                       return 0;
-                               continue;
-                       }
-                       if (c == '\n')
-                               break;
-                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
-                               *lineptr++ = c;
-               }
-               *lineptr = 0;
-       } while (strstr(line, str) == NULL);
-       return 1;
-}
-#endif
-
-int
-xmon_getchar(void)
-{
-    int c;
-
-    if (lineleft == 0) {
-       lineptr = line;
-       for (;;) {
-           c = xmon_readchar();
-           if (c == -1 || c == 4)
-               break;
-           if (c == '\r' || c == '\n') {
-               *lineptr++ = '\n';
-               xmon_putchar('\n');
-               break;
-           }
-           switch (c) {
-           case 0177:
-           case '\b':
-               if (lineptr > line) {
-                   xmon_putchar('\b');
-                   xmon_putchar(' ');
-                   xmon_putchar('\b');
-                   --lineptr;
-               }
-               break;
-           case 'U' & 0x1F:
-               while (lineptr > line) {
-                   xmon_putchar('\b');
-                   xmon_putchar(' ');
-                   xmon_putchar('\b');
-                   --lineptr;
-               }
-               break;
-           default:
-               if (lineptr >= &line[sizeof(line) - 1])
-                   xmon_putchar('\a');
-               else {
-                   xmon_putchar(c);
-                   *lineptr++ = c;
-               }
-           }
-       }
-       lineleft = lineptr - line;
-       lineptr = line;
-    }
-    if (lineleft == 0)
-       return -1;
-    --lineleft;
-    return *lineptr++;
-}
-
-char *
-xmon_fgets(char *str, int nb, void *f)
-{
-    char *p;
-    int c;
-
-    for (p = str; p < str + nb - 1; ) {
-       c = xmon_getchar();
-       if (c == -1) {
-           if (p == str)
-               return 0;
-           break;
-       }
-       *p++ = c;
-       if (c == '\n')
-           break;
-    }
-    *p = 0;
-    return str;
-}
-
-void
-prom_drawhex(uint val)
-{
-       unsigned char buf[10];
-
-       int i;
-       for (i = 7;  i >= 0;  i--)
-       {
-               buf[i] = "0123456789abcdef"[val & 0x0f];
-               val >>= 4;
-       }
-       buf[8] = '\0';
-       xmon_fputs(buf, xmon_stdout);
-}
-
-void
-prom_drawstring(const char *str)
-{
-       xmon_fputs(str, xmon_stdout);
-}
diff --git a/arch/powerpc/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c
deleted file mode 100644 (file)
index b48738c..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Written by Cort Dougan to replace the version originally used
- * by Paul Mackerras, which came from NetBSD and thus had copyright
- * conflicts with Linux.
- *
- * This file makes liberal use of the standard linux utility
- * routines to reduce the size of the binary.  We assume we can
- * trust some parts of Linux inside the debugger.
- *   -- Cort (cort@cs.nmt.edu)
- *
- * Copyright (C) 1999 Cort Dougan.
- *
- *      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/kernel.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <stdarg.h>
-#include "nonstdio.h"
-
-extern int xmon_write(void *, void *, int);
-
-void xmon_vfprintf(void *f, const char *fmt, va_list ap)
-{
-       static char xmon_buf[2048];
-       int n;
-
-       n = vsprintf(xmon_buf, fmt, ap);
-       xmon_write(f, xmon_buf, n);
-}
-
-void xmon_printf(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       xmon_vfprintf(stdout, fmt, ap);
-       va_end(ap);
-}
-EXPORT_SYMBOL(xmon_printf);
-
-void xmon_fprintf(void *f, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       xmon_vfprintf(f, fmt, ap);
-       va_end(ap);
-}
-
index 1124f1146202859ecbd759012f9566ec011b724c..cfcb2a56d6625d9c9c24edb94cc6aa63504874c1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Routines providing a simple monitor for use on the PowerMac.
  *
- * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 1996-2005 Paul Mackerras.
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -18,6 +18,7 @@
 #include <linux/kallsyms.h>
 #include <linux/cpumask.h>
 #include <linux/module.h>
+#include <linux/sysrq.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
@@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
 static const char *getvecname(unsigned long vec);
 
 extern int print_insn_powerpc(unsigned long, unsigned long, int);
-extern void printf(const char *fmt, ...);
-extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
-extern int xmon_putc(int c, void *f);
-extern int putchar(int ch);
 
 extern void xmon_enter(void);
 extern void xmon_leave(void);
 
-extern int xmon_read_poll(void);
 extern long setjmp(long *);
 extern void longjmp(long *, long);
 extern void xmon_save_regs(struct pt_regs *);
@@ -748,7 +744,6 @@ cmds(struct pt_regs *excp)
                printf("%x:", smp_processor_id());
 #endif /* CONFIG_SMP */
                printf("mon> ");
-               fflush(stdout);
                flush_input();
                termch = 0;
                cmd = skipbl();
@@ -1797,7 +1792,7 @@ memex(void)
        for(;;){
                if (!mnoread)
                        n = mread(adrs, val, size);
-               printf("%.16x%c", adrs, brev? 'r': ' ');
+               printf(REG"%c", adrs, brev? 'r': ' ');
                if (!mnoread) {
                        if (brev)
                                byterev(val, size);
@@ -1976,17 +1971,18 @@ prdump(unsigned long adrs, long ndump)
                nr = mread(adrs, temp, r);
                adrs += nr;
                for (m = 0; m < r; ++m) {
-                       if ((m & 7) == 0 && m > 0)
-                           putchar(' ');
+                       if ((m & (sizeof(long) - 1)) == 0 && m > 0)
+                               putchar(' ');
                        if (m < nr)
                                printf("%.2x", temp[m]);
                        else
                                printf("%s", fault_chars[fault_type]);
                }
-               if (m <= 8)
-                       printf(" ");
-               for (; m < 16; ++m)
+               for (; m < 16; ++m) {
+                       if ((m & (sizeof(long) - 1)) == 0)
+                               putchar(' ');
                        printf("  ");
+               }
                printf("  |");
                for (m = 0; m < r; ++m) {
                        if (m < nr) {
@@ -2151,7 +2147,6 @@ memzcan(void)
                ok = mread(a, &v, 1);
                if (ok && !ook) {
                        printf("%.8x .. ", a);
-                       fflush(stdout);
                } else if (!ok && ook)
                        printf("%.8x\n", a - mskip);
                ook = ok;
@@ -2372,7 +2367,7 @@ int
 inchar(void)
 {
        if (lineptr == NULL || *lineptr == 0) {
-               if (fgets(line, sizeof(line), stdin) == NULL) {
+               if (xmon_gets(line, sizeof(line)) == NULL) {
                        lineptr = NULL;
                        return EOF;
                }
@@ -2526,4 +2521,29 @@ void xmon_init(int enable)
                __debugger_dabr_match = NULL;
                __debugger_fault_handler = NULL;
        }
+       xmon_map_scc();
+}
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
+                             struct tty_struct *tty) 
+{
+       /* ensure xmon is enabled */
+       xmon_init(1);
+       debugger(pt_regs);
+}
+
+static struct sysrq_key_op sysrq_xmon_op = 
+{
+       .handler =      sysrq_handle_xmon,
+       .help_msg =     "Xmon",
+       .action_msg =   "Entering xmon",
+};
+
+static int __init setup_xmon_sysrq(void)
+{
+       register_sysrq_key('x', &sysrq_xmon_op);
+       return 0;
 }
+__initcall(setup_xmon_sysrq);
+#endif /* CONFIG_MAGIC_SYSRQ */
index 69173df76db0c06b8cb65de84c0a5f8859a8345a..4ed88acfa73a20f956f2287ba9f226491387201e 100644 (file)
@@ -19,6 +19,9 @@ extern prom_entry of_prom_entry;
 
 /* function declarations */
 
+int    call_prom(const char *service, int nargs, int nret, ...);
+int    call_prom_ret(const char *service, int nargs, int nret,
+                     unsigned int *rets, ...);
 void * claim(unsigned int virt, unsigned int size, unsigned int align);
 int    map(unsigned int phys, unsigned int virt, unsigned int size);
 void   enter(void);
index 02e6f235d7cb3bc6e32fb79b9a964e2ebc0b2144..0b979c0049729351a75931e38eb85a93d126bb9a 100644 (file)
@@ -3,4 +3,4 @@
 #
 
 lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o        \
-        ofstdio.o read.o release.o write.o map.o
+        ofstdio.o read.o release.o write.o map.o call_prom.o
diff --git a/arch/ppc/boot/of1275/call_prom.c b/arch/ppc/boot/of1275/call_prom.c
new file mode 100644 (file)
index 0000000..9479a3a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * 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 "of1275.h"
+#include <stdarg.h>
+
+int call_prom(const char *service, int nargs, int nret, ...)
+{
+       int i;
+       struct prom_args {
+               const char *service;
+               int nargs;
+               int nret;
+               unsigned int args[12];
+       } args;
+       va_list list;
+
+       args.service = service;
+       args.nargs = nargs;
+       args.nret = nret;
+
+       va_start(list, nret);
+       for (i = 0; i < nargs; i++)
+               args.args[i] = va_arg(list, unsigned int);
+       va_end(list);
+
+       for (i = 0; i < nret; i++)
+               args.args[nargs+i] = 0;
+
+       if (of_prom_entry(&args) < 0)
+               return -1;
+
+       return (nret > 0)? args.args[nargs]: 0;
+}
+
+int call_prom_ret(const char *service, int nargs, int nret,
+                 unsigned int *rets, ...)
+{
+       int i;
+       struct prom_args {
+               const char *service;
+               int nargs;
+               int nret;
+               unsigned int args[12];
+       } args;
+       va_list list;
+
+       args.service = service;
+       args.nargs = nargs;
+       args.nret = nret;
+
+       va_start(list, rets);
+       for (i = 0; i < nargs; i++)
+               args.args[i] = va_arg(list, unsigned int);
+       va_end(list);
+
+       for (i = 0; i < nret; i++)
+               args.args[nargs+i] = 0;
+
+       if (of_prom_entry(&args) < 0)
+               return -1;
+
+       if (rets != (void *) 0)
+               for (i = 1; i < nret; ++i)
+                       rets[i-1] = args.args[nargs+i];
+
+       return (nret > 0)? args.args[nargs]: 0;
+}
index 13169a5c4339d862128b660da5d8c149858b5871..1ed3aeeff8ae469d00ae21afa7a3575810b92aeb 100644 (file)
@@ -9,27 +9,84 @@
  */
 
 #include "of1275.h"
+#include "nonstdio.h"
 
-void *
-claim(unsigned int virt, unsigned int size, unsigned int align)
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
+ */
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
+
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
+{
+       for (; *s2; ++s2)
+               if (*s1++ != *s2)
+                       return 0;
+       return 1;
+}
+
+static int check_of_version(void)
+{
+       phandle oprom, chosen;
+       char version[64];
+
+       oprom = finddevice("/openprom");
+       if (oprom == OF_INVALID_HANDLE)
+               return 0;
+       if (getprop(oprom, "model", version, sizeof(version)) <= 0)
+               return 0;
+       version[sizeof(version)-1] = 0;
+       printf("OF version = '%s'\n", version);
+       if (!string_match(version, "Open Firmware, 1.")
+           && !string_match(version, "FirmWorks,3."))
+               return 0;
+       chosen = finddevice("/chosen");
+       if (chosen == OF_INVALID_HANDLE) {
+               chosen = finddevice("/chosen@0");
+               if (chosen == OF_INVALID_HANDLE) {
+                       printf("no chosen\n");
+                       return 0;
+               }
+       }
+       if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+               printf("no mmu\n");
+               return 0;
+       }
+       memory = (ihandle) call_prom("open", 1, 1, "/memory");
+       if (memory == OF_INVALID_HANDLE) {
+               memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
+               if (memory == OF_INVALID_HANDLE) {
+                       printf("no memory node\n");
+                       return 0;
+               }
+       }
+       printf("old OF detected\n");
+       return 1;
+}
+
+void *claim(unsigned int virt, unsigned int size, unsigned int align)
 {
-    struct prom_args {
-       char *service;
-       int nargs;
-       int nret;
-       unsigned int virt;
-       unsigned int size;
-       unsigned int align;
-       void *ret;
-    } args;
+       int ret;
+       unsigned int result;
 
-    args.service = "claim";
-    args.nargs = 3;
-    args.nret = 1;
-    args.virt = virt;
-    args.size = size;
-    args.align = align;
-    args.ret = (void *) 0;
-    (*of_prom_entry)(&args);
-    return args.ret;
+       if (need_map < 0)
+               need_map = check_of_version();
+       if (align || !need_map)
+               return (void *) call_prom("claim", 3, 1, virt, size, align);
+       
+       ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+                           align, size, virt);
+       if (ret != 0 || result == -1)
+               return (void *) -1;
+       ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+                           align, size, virt);
+       /* 0x12 == coherent + read/write */
+       ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
+                       0x12, size, virt, virt);
+       return virt;
 }
index 2c0f7cbb793e20b750b0eb913767abe20d44579e..0dcb1201b7722f7811370a51debb28b2e0361115 100644 (file)
 
 #include "of1275.h"
 
-phandle
-finddevice(const char *name)
+phandle finddevice(const char *name)
 {
-    struct prom_args {
-       char *service;
-       int nargs;
-       int nret;
-       const char *devspec;
-       phandle device;
-    } args;
-
-    args.service = "finddevice";
-    args.nargs = 1;
-    args.nret = 1;
-    args.devspec = name;
-    args.device = OF_INVALID_HANDLE;
-    (*of_prom_entry)(&args);
-    return args.device;
+       return (phandle) call_prom("finddevice", 1, 1, name);
 }
index 03415238fabf67791bd084775aacf22997ff9370..83a6433459ce1fe487b10272c8fbf82ec04bc9f0 100644 (file)
@@ -80,8 +80,7 @@ $(obj)/note: $(utils)/mknote FORCE
        $(call if_changed,mknote)
 
 
-$(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF
-$(obj)/crt0.o:     EXTRA_AFLAGS := -traditional
+$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
 targets += coffcrt0.o crt0.o
 $(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
        $(call if_changed_dep,as_o_S)
index 76a55a438f2383cc2c72294b078356c88078b9f9..17a4da65e275f99930ca6664a89ab28424f919cd 100644 (file)
@@ -12,7 +12,7 @@ extra-$(CONFIG_6xx)           += idle_6xx.o
 extra-$(CONFIG_POWER4)         += idle_power4.o
 extra-y                                += vmlinux.lds
 
-obj-y                          := entry.o traps.o irq.o idle.o time.o misc.o \
+obj-y                          := entry.o traps.o idle.o time.o misc.o \
                                        process.o align.o \
                                        setup.o \
                                        ppc_htab.o
@@ -38,8 +38,7 @@ endif
 # These are here while we do the architecture merge
 
 else
-obj-y                          := irq.o idle.o \
-                                       align.o
+obj-y                          := idle.o align.o
 obj-$(CONFIG_6xx)              += l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
 obj-$(CONFIG_MODULES)          += module.o
index aeb349b47af35f49040c45d5f2cc94b29a3af2d3..f3d274c6b231df80847e6e1ab9b112f80be7205f 100644 (file)
@@ -358,6 +358,6 @@ label:
        NORMAL_EXCEPTION_PROLOG;                                              \
        bne     load_up_fpu;            /* if from user, just load it up */   \
        addi    r3,r1,STACK_FRAME_OVERHEAD;                                   \
-       EXC_XFER_EE_LITE(0x800, KernelFP)
+       EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
 
 #endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
deleted file mode 100644 (file)
index fbb2b9f..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  arch/ppc/kernel/irq.c
- *
- *  Derived from arch/i386/kernel/irq.c
- *    Copyright (C) 1992 Linus Torvalds
- *  Adapted from arch/i386 by Gary Thomas
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
- *    Copyright (C) 1996-2001 Cort Dougan
- *  Adapted for Power Macintosh by Paul Mackerras
- *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- *
- * The MPC8xx has an interrupt mask in the SIU.  If a bit is set, the
- * interrupt is _enabled_.  As expected, IRQ0 is bit 0 in the 32-bit
- * mask register (of which only 16 are defined), hence the weird shifting
- * and complement of the cached_irq_mask.  I want to be able to stuff
- * this right into the SIU SMASK register.
- * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
- * to reduce code space and undefined function references.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/threads.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
-#include <linux/random.h>
-#include <linux/seq_file.h>
-#include <linux/cpumask.h>
-#include <linux/profile.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/cache.h>
-#include <asm/prom.h>
-#include <asm/ptrace.h>
-#include <asm/machdep.h>
-
-#define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
-
-extern atomic_t ipi_recv;
-extern atomic_t ipi_sent;
-
-#define MAXCOUNT 10000000
-
-int ppc_spurious_interrupts = 0;
-struct irqaction *ppc_irq_action[NR_IRQS];
-unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-atomic_t ppc_n_lost_interrupts;
-
-#ifdef CONFIG_TAU_INT
-extern int tau_initialized;
-extern int tau_interrupts(int);
-#endif
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v, j;
-       struct irqaction * action;
-       unsigned long flags;
-
-       if (i == 0) {
-               seq_puts(p, "           ");
-               for (j=0; j<NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "CPU%d       ", j);
-               seq_putc(p, '\n');
-       }
-
-       if (i < NR_IRQS) {
-               spin_lock_irqsave(&irq_desc[i].lock, flags);
-               action = irq_desc[i].action;
-               if ( !action || !action->handler )
-                       goto skip;
-               seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
-               for (j = 0; j < NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "%10u ",
-                                          kstat_cpu(j).irqs[i]);
-#else
-               seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
-               if (irq_desc[i].handler)
-                       seq_printf(p, " %s ", irq_desc[i].handler->typename);
-               else
-                       seq_puts(p, "  None      ");
-               seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
-               seq_printf(p, "    %s", action->name);
-               for (action = action->next; action; action = action->next)
-                       seq_printf(p, ", %s", action->name);
-               seq_putc(p, '\n');
-skip:
-               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       } else if (i == NR_IRQS) {
-#ifdef CONFIG_TAU_INT
-               if (tau_initialized){
-                       seq_puts(p, "TAU: ");
-                       for (j = 0; j < NR_CPUS; j++)
-                               if (cpu_online(j))
-                                       seq_printf(p, "%10u ", tau_interrupts(j));
-                       seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
-               }
-#endif
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
-               /* should this be per processor send/receive? */
-               seq_printf(p, "IPI (recv/sent): %10u/%u\n",
-                               atomic_read(&ipi_recv), atomic_read(&ipi_sent));
-#endif
-               seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
-       }
-       return 0;
-}
-
-void do_IRQ(struct pt_regs *regs)
-{
-       int irq, first = 1;
-        irq_enter();
-
-       /*
-        * Every platform is required to implement ppc_md.get_irq.
-        * This function will either return an irq number or -1 to
-        * indicate there are no more pending.  But the first time
-        * through the loop this means there wasn't and IRQ pending.
-        * The value -2 is for buggy hardware and means that this IRQ
-        * has already been handled. -- Tom
-        */
-       while ((irq = ppc_md.get_irq(regs)) >= 0) {
-               __do_IRQ(irq, regs);
-               first = 0;
-       }
-       if (irq != -2 && first)
-               /* That's not SMP safe ... but who cares ? */
-               ppc_spurious_interrupts++;
-        irq_exit();
-}
-
-void __init init_IRQ(void)
-{
-       ppc_md.init_IRQ();
-}
index ae6af29938a1efc96513a6b8f33d25667d248f4f..5e61124581d03fda7f374379eb76ae7176240fc8 100644 (file)
@@ -497,9 +497,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  * and invalidate the corresponding instruction cache blocks.
  * This is a no-op on the 601.
  *
- * flush_icache_range(unsigned long start, unsigned long stop)
+ * __flush_icache_range(unsigned long start, unsigned long stop)
  */
-_GLOBAL(flush_icache_range)
+_GLOBAL(__flush_icache_range)
 BEGIN_FTR_SECTION
        blr                             /* for 601, do nothing */
 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
index e0ca61b37f4fc9b0b51b2861966b79cb4cecd208..66073f775193d2084ef7b629cf130f9e744c3bd3 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/btext.h>
 #include <asm/div64.h>
 #include <asm/xmon.h>
+#include <asm/signal.h>
 
 #ifdef  CONFIG_8xx
 #include <asm/commproc.h>
@@ -57,7 +58,6 @@ extern void machine_check_exception(struct pt_regs *regs);
 extern void alignment_exception(struct pt_regs *regs);
 extern void program_check_exception(struct pt_regs *regs);
 extern void single_step_exception(struct pt_regs *regs);
-extern int do_signal(sigset_t *, struct pt_regs *);
 extern int pmac_newworld;
 extern int sys_sigreturn(struct pt_regs *regs);
 
@@ -78,7 +78,6 @@ EXPORT_SYMBOL(program_check_exception);
 EXPORT_SYMBOL(single_step_exception);
 EXPORT_SYMBOL(sys_sigreturn);
 EXPORT_SYMBOL(ppc_n_lost_interrupts);
-EXPORT_SYMBOL(ppc_lost_interrupts);
 
 EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL(DMA_MODE_READ);
@@ -176,6 +175,7 @@ EXPORT_SYMBOL(pci_bus_to_phys);
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
+extern void flush_dcache_all(void);
 EXPORT_SYMBOL(flush_dcache_all);
 #endif
 
@@ -217,9 +217,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
 EXPORT_SYMBOL(cuda_request);
 EXPORT_SYMBOL(cuda_poll);
 #endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_PPC_MULTIPLATFORM
-EXPORT_SYMBOL(_machine);
-#endif
 #ifdef CONFIG_PPC_PMAC
 EXPORT_SYMBOL(sys_ctrler);
 EXPORT_SYMBOL(pmac_newworld);
index 6bcb85d2b7fd92be45bf49d1b7e9d23526c0276e..dc55e1abc45bde685741522caa14f1cfae7cfb5e 100644 (file)
@@ -76,6 +76,7 @@ unsigned int DMA_MODE_WRITE;
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
 int _machine = 0;
+EXPORT_SYMBOL(_machine);
 
 extern void prep_init(unsigned long r3, unsigned long r4,
                unsigned long r5, unsigned long r6, unsigned long r7);
index 9f2d95ea856478212df2498a73085e0899612aa9..4742bf609357949bc66cdb6ea8d2db77bd74e255 100644 (file)
@@ -75,6 +75,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock);
 #define GATWICK_IRQ_POOL_SIZE        10
 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
 
+#define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
+static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
+
 /*
  * Mark an irq as "lost".  This is only used on the pmac
  * since it can lose interrupts (see pmac_set_irq_mask).
index 067d7d53b81e76fc7fe097cc56f99307770e5025..4415748071dc8836faaa6f4e6752f4cb12e865ca 100644 (file)
 #include <asm/pci-bridge.h>
 #include <asm/todc.h>
 
+/* prep registers for L2 */
+#define CACHECRBA       0x80000823      /* Cache configuration register address */
+#define L2CACHE_MASK   0x03    /* Mask for 2 L2 Cache bits */
+#define L2CACHE_512KB  0x00    /* 512KB */
+#define L2CACHE_256KB  0x01    /* 256KB */
+#define L2CACHE_1MB    0x02    /* 1MB */
+#define L2CACHE_NONE   0x03    /* NONE */
+#define L2CACHE_PARITY  0x08    /* Mask for L2 Cache Parity Protected bit */
+
 TODC_ALLOC();
 
 unsigned char ucSystemType;
index 29552348e58165db414bf6f609ae19e31e9fad7a..c9d32db9d76a0e0d84f87ec13e0b14cb6091b262 100644 (file)
@@ -297,6 +297,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
        def_bool y
        depends on NEED_MULTIPLE_NODES
 
+config ARCH_MEMORY_PROBE
+       def_bool y
+       depends on MEMORY_HOTPLUG
+
 # Some NUMA nodes have memory ranges that span
 # other nodes.  Even though a pfn is valid and
 # between a node's start and end pfns, it may not
index 7f2c09473394836597317beb4ef70c9dab6b4ba8..c02a99952be7cdfa4f2c2b4061c6af58d8a2403f 100644 (file)
@@ -5,11 +5,59 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string.h>
+#include <elf.h>
 
 #define ElfHeaderSize  (64 * 1024)
 #define ElfPages  (ElfHeaderSize / 4096)
 #define KERNELBASE (0xc000000000000000)
+#define _ALIGN_UP(addr,size)   (((addr)+((size)-1))&(~((size)-1)))
 
+struct addr_range {
+       unsigned long long addr;
+       unsigned long memsize;
+       unsigned long offset;
+};
+
+static int check_elf64(void *p, int size, struct addr_range *r)
+{
+       Elf64_Ehdr *elf64 = p;
+       Elf64_Phdr *elf64ph;
+
+       if (elf64->e_ident[EI_MAG0] != ELFMAG0 ||
+           elf64->e_ident[EI_MAG1] != ELFMAG1 ||
+           elf64->e_ident[EI_MAG2] != ELFMAG2 ||
+           elf64->e_ident[EI_MAG3] != ELFMAG3 ||
+           elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
+           elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
+           elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64)
+               return 0;
+
+       if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size)
+               return 0;
+
+       elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 +
+                                 (unsigned long)elf64->e_phoff);
+
+       r->memsize = (unsigned long)elf64ph->p_memsz;
+       r->offset = (unsigned long)elf64ph->p_offset;
+       r->addr = (unsigned long long)elf64ph->p_vaddr;
+
+#ifdef DEBUG
+       printf("PPC64 ELF file, ph:\n");
+       printf("p_type   0x%08x\n", elf64ph->p_type);
+       printf("p_flags  0x%08x\n", elf64ph->p_flags);
+       printf("p_offset 0x%016llx\n", elf64ph->p_offset);
+       printf("p_vaddr  0x%016llx\n", elf64ph->p_vaddr);
+       printf("p_paddr  0x%016llx\n", elf64ph->p_paddr);
+       printf("p_filesz 0x%016llx\n", elf64ph->p_filesz);
+       printf("p_memsz  0x%016llx\n", elf64ph->p_memsz);
+       printf("p_align  0x%016llx\n", elf64ph->p_align);
+       printf("... skipping 0x%08lx bytes of ELF header\n",
+              (unsigned long)elf64ph->p_offset);
+#endif
+
+       return 64;
+}
 void get4k(FILE *file, char *buf )
 {
        unsigned j;
@@ -34,97 +82,92 @@ void death(const char *msg, FILE *fdesc, const char *fname)
 int main(int argc, char **argv)
 {
        char inbuf[4096];
-       FILE *ramDisk = NULL;
-       FILE *sysmap = NULL;
-       FILE *inputVmlinux = NULL;
-       FILE *outputVmlinux = NULL;
-  
-       unsigned i = 0;
-       unsigned long ramFileLen = 0;
-       unsigned long ramLen = 0;
-       unsigned long roundR = 0;
-  
-       unsigned long sysmapFileLen = 0;
-       unsigned long sysmapLen = 0;
-       unsigned long sysmapPages = 0;
-       char* ptr_end = NULL; 
-       unsigned long offset_end = 0;
-
-       unsigned long kernelLen = 0;
-       unsigned long actualKernelLen = 0;
-       unsigned long round = 0;
-       unsigned long roundedKernelLen = 0;
-       unsigned long ramStartOffs = 0;
-       unsigned long ramPages = 0;
-       unsigned long roundedKernelPages = 0;
-       unsigned long hvReleaseData = 0;
+       struct addr_range vmlinux;
+       FILE *ramDisk;
+       FILE *inputVmlinux;
+       FILE *outputVmlinux;
+
+       char *rd_name, *lx_name, *out_name;
+
+       size_t i;
+       unsigned long ramFileLen;
+       unsigned long ramLen;
+       unsigned long roundR;
+       unsigned long offset_end;
+
+       unsigned long kernelLen;
+       unsigned long actualKernelLen;
+       unsigned long round;
+       unsigned long roundedKernelLen;
+       unsigned long ramStartOffs;
+       unsigned long ramPages;
+       unsigned long roundedKernelPages;
+       unsigned long hvReleaseData;
        u_int32_t eyeCatcher = 0xc8a5d9c4;
-       unsigned long naca = 0;
-       unsigned long xRamDisk = 0;
-       unsigned long xRamDiskSize = 0;
-       long padPages = 0;
+       unsigned long naca;
+       unsigned long xRamDisk;
+       unsigned long xRamDiskSize;
+       long padPages;
   
   
        if (argc < 2) {
                fprintf(stderr, "Name of RAM disk file missing.\n");
                exit(1);
        }
+       rd_name = argv[1];
 
        if (argc < 3) {
-               fprintf(stderr, "Name of System Map input file is missing.\n");
-               exit(1);
-       }
-  
-       if (argc < 4) {
                fprintf(stderr, "Name of vmlinux file missing.\n");
                exit(1);
        }
+       lx_name = argv[2];
 
-       if (argc < 5) {
+       if (argc < 4) {
                fprintf(stderr, "Name of vmlinux output file missing.\n");
                exit(1);
        }
+       out_name = argv[3];
 
 
-       ramDisk = fopen(argv[1], "r");
+       ramDisk = fopen(rd_name, "r");
        if ( ! ramDisk ) {
-               fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", argv[1]);
+               fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name);
                exit(1);
        }
 
-       sysmap = fopen(argv[2], "r");
-       if ( ! sysmap ) {
-               fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]);
-               exit(1);
-       }
-  
-       inputVmlinux = fopen(argv[3], "r");
+       inputVmlinux = fopen(lx_name, "r");
        if ( ! inputVmlinux ) {
-               fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[3]);
+               fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name);
                exit(1);
        }
   
-       outputVmlinux = fopen(argv[4], "w+");
+       outputVmlinux = fopen(out_name, "w+");
        if ( ! outputVmlinux ) {
-               fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[4]);
+               fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name);
                exit(1);
        }
-  
-  
-  
+
+       i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux);
+       if (i != sizeof(inbuf)) {
+               fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i);
+               exit(1);
+       }
+
+       i = check_elf64(inbuf, sizeof(inbuf), &vmlinux);
+       if (i == 0) {
+               fprintf(stderr, "You must have a linux kernel specified as argv[2]\n");
+               exit(1);
+       }
+
        /* Input Vmlinux file */
        fseek(inputVmlinux, 0, SEEK_END);
        kernelLen = ftell(inputVmlinux);
        fseek(inputVmlinux, 0, SEEK_SET);
-       printf("kernel file size = %d\n", kernelLen);
-       if ( kernelLen == 0 ) {
-               fprintf(stderr, "You must have a linux kernel specified as argv[3]\n");
-               exit(1);
-       }
+       printf("kernel file size = %lu\n", kernelLen);
 
        actualKernelLen = kernelLen - ElfHeaderSize;
 
-       printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
+       printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen);
 
        round = actualKernelLen % 4096;
        roundedKernelLen = actualKernelLen;
@@ -134,39 +177,7 @@ int main(int argc, char **argv)
        roundedKernelPages = roundedKernelLen / 4096;
        printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
 
-
-
-       /* Input System Map file */
-       /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
-       fseek(sysmap, 0, SEEK_END);
-       sysmapFileLen = ftell(sysmap);
-       fseek(sysmap, 0, SEEK_SET);
-       printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
-
-       sysmapLen = sysmapFileLen;
-
-       roundR = 4096 - (sysmapLen % 4096);
-       if (roundR) {
-               printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
-               sysmapLen += roundR;
-       }
-       printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
-  
-       /* Process the Sysmap file to determine where _end is */
-       sysmapPages = sysmapLen / 4096;
-       /* read the whole file line by line, expect that it doesn't fail */
-       while ( fgets(inbuf, 4096, sysmap) )  ;
-       /* search for _end in the last page of the system map */
-       ptr_end = strstr(inbuf, " _end");
-       if (!ptr_end) {
-               fprintf(stderr, "Unable to find _end in the sysmap file \n");
-               fprintf(stderr, "inbuf: \n");
-               fprintf(stderr, "%s \n", inbuf);
-               exit(1);
-       }
-       printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
-       /* convert address of _end in system map to hex offset. */
-       offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
+       offset_end = _ALIGN_UP(vmlinux.memsize, 4096);
        /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
        padPages = offset_end/4096 - roundedKernelPages;
 
@@ -194,7 +205,7 @@ int main(int argc, char **argv)
        fseek(ramDisk, 0, SEEK_END);
        ramFileLen = ftell(ramDisk);
        fseek(ramDisk, 0, SEEK_SET);
-       printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen);
+       printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen);
 
        ramLen = ramFileLen;
 
@@ -248,19 +259,19 @@ int main(int argc, char **argv)
        /* fseek to the hvReleaseData pointer */
        fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
        if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
-               death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]);
+               death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name);
        }
        hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
-       printf("hvReleaseData is at %08x\n", hvReleaseData);
+       printf("hvReleaseData is at %08lx\n", hvReleaseData);
 
        /* fseek to the hvReleaseData */
        fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
        if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
-               death("Could not read hvReleaseData\n", outputVmlinux, argv[4]);
+               death("Could not read hvReleaseData\n", outputVmlinux, out_name);
        }
        /* Check hvReleaseData sanity */
        if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
-               death("hvReleaseData is invalid\n", outputVmlinux, argv[4]);
+               death("hvReleaseData is invalid\n", outputVmlinux, out_name);
        }
        /* Get the naca pointer */
        naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
@@ -269,13 +280,13 @@ int main(int argc, char **argv)
        /* fseek to the naca */
        fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
        if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
-               death("Could not read naca\n", outputVmlinux, argv[4]);
+               death("Could not read naca\n", outputVmlinux, out_name);
        }
        xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
        xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
        /* Make sure a RAM disk isn't already present */
        if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
-               death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]);
+               death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name);
        }
        /* Fill in the values */
        *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
@@ -285,15 +296,15 @@ int main(int argc, char **argv)
        fflush(outputVmlinux);
        fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
        if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
-               death("Could not write naca\n", outputVmlinux, argv[4]);
+               death("Could not write naca\n", outputVmlinux, out_name);
        }
-       printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n",
+       printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n",
               ramPages, ramStartOffs);
 
        /* Done */
        fclose(outputVmlinux);
        /* Set permission to executable */
-       chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+       chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
 
        return 0;
 }
index c441aebe76481aebf0bef4525979a2be1de7b766..58b19f1076568c85ae7cc17d903b7db4050b72a5 100644 (file)
@@ -11,12 +11,11 @@ obj-y               :=      misc.o prom.o
 
 endif
 
-obj-y               += irq.o idle.o dma.o \
-                       align.o pacaData.o \
-                       udbg.o ioctl32.o \
+obj-y               += idle.o dma.o \
+                       align.o \
+                       udbg.o \
                        rtc.o \
-                       cpu_setup_power4.o \
-                       iommu.o sysfs.o vdso.o firmware.o
+                       iommu.o vdso.o
 obj-y += vdso32/ vdso64/
 
 pci-obj-$(CONFIG_PPC_MULTIPLATFORM)    += pci_dn.o pci_direct_iommu.o
@@ -31,15 +30,10 @@ endif
 obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
 
 obj-$(CONFIG_KEXEC)            += machine_kexec.o
-obj-$(CONFIG_EEH)              += eeh.o
-obj-$(CONFIG_PROC_FS)          += proc_ppc64.o
 obj-$(CONFIG_MODULES)          += module.o
 ifneq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_MODULES)          += ppc_ksyms.o
 endif
-obj-$(CONFIG_PPC_RTAS)         += rtas_pci.o
-obj-$(CONFIG_SCANLOG)          += scanlog.o
-obj-$(CONFIG_LPARCFG)          += lparcfg.o
 obj-$(CONFIG_HVC_CONSOLE)      += hvconsole.o
 ifneq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_BOOTX_TEXT)       += btext.o
@@ -52,8 +46,6 @@ obj-$(CONFIG_PPC_MAPLE)               += udbg_16550.o
 
 obj-$(CONFIG_KPROBES)          += kprobes.o
 
-CFLAGS_ioctl32.o += -Ifs/
-
 ifneq ($(CONFIG_PPC_MERGE),y)
 ifeq ($(CONFIG_PPC_ISERIES),y)
 arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
index bce9065da6cbea1f193477637008290b5953114c..84ab5c18ef529b66eecc3e3d25ddfc588668a510 100644 (file)
@@ -74,7 +74,6 @@ int main(void)
        DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
-       DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
        DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
 
        /* paca */
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S
deleted file mode 100644 (file)
index 1fb673c..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file contains low level CPU setup functions.
- *    Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.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.
- *
- */
-
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cache.h>
-
-_GLOBAL(__970_cpu_preinit)
-       /*
-        * Do nothing if not running in HV mode
-        */
-       mfmsr   r0
-       rldicl. r0,r0,4,63
-       beqlr
-
-       /*
-        * Deal only with PPC970 and PPC970FX.
-        */
-       mfspr   r0,SPRN_PVR
-       srwi    r0,r0,16
-       cmpwi   r0,0x39
-       beq     1f
-       cmpwi   r0,0x3c
-       beq     1f
-       cmpwi   r0,0x44
-       bnelr
-1:
-
-       /* Make sure HID4:rm_ci is off before MMU is turned off, that large
-        * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
-        * HID5:DCBZ32_ill
-        */
-       li      r0,0
-       mfspr   r3,SPRN_HID4
-       rldimi  r3,r0,40,23     /* clear bit 23 (rm_ci) */
-       rldimi  r3,r0,2,61      /* clear bit 61 (lg_pg_en) */
-       sync
-       mtspr   SPRN_HID4,r3
-       isync
-       sync
-       mfspr   r3,SPRN_HID5
-       rldimi  r3,r0,6,56      /* clear bits 56 & 57 (DCBZ*) */
-       sync
-       mtspr   SPRN_HID5,r3
-       isync
-       sync
-
-       /* Setup some basic HID1 features */
-       mfspr   r0,SPRN_HID1
-       li      r3,0x1200               /* enable i-fetch cacheability */
-       sldi    r3,r3,44                /* and prefetch */
-       or      r0,r0,r3
-       mtspr   SPRN_HID1,r0
-       mtspr   SPRN_HID1,r0
-       isync
-
-       /* Clear HIOR */
-       li      r0,0
-       sync
-       mtspr   SPRN_HIOR,0             /* Clear interrupt prefix */
-       isync
-       blr
-
-_GLOBAL(__setup_cpu_power4)
-       blr
-
-_GLOBAL(__setup_cpu_be)
-        /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
-        addi    r3, 0,  0
-        ori     r3, r3, HID6_LB
-        sldi    r3, r3, 32
-        nor     r3, r3, r3
-        mfspr   r4, SPRN_HID6
-        and     r4, r4, r3
-        addi    r3, 0, 0x02000
-        sldi    r3, r3, 32
-        or      r4, r4, r3
-        mtspr   SPRN_HID6, r4
-       blr
-
-_GLOBAL(__setup_cpu_ppc970)
-       mfspr   r0,SPRN_HID0
-       li      r11,5                   /* clear DOZE and SLEEP */
-       rldimi  r0,r11,52,8             /* set NAP and DPM */
-       mtspr   SPRN_HID0,r0
-       mfspr   r0,SPRN_HID0
-       mfspr   r0,SPRN_HID0
-       mfspr   r0,SPRN_HID0
-       mfspr   r0,SPRN_HID0
-       mfspr   r0,SPRN_HID0
-       mfspr   r0,SPRN_HID0
-       sync
-       isync
-       blr
-
-/* Definitions for the table use to save CPU states */
-#define CS_HID0                0
-#define CS_HID1                8
-#define        CS_HID4         16
-#define CS_HID5                24
-#define CS_SIZE                32
-
-       .data
-       .balign L1_CACHE_BYTES,0
-cpu_state_storage:     
-       .space  CS_SIZE
-       .balign L1_CACHE_BYTES,0
-       .text
-       
-/* Called in normal context to backup CPU 0 state. This
- * does not include cache settings. This function is also
- * called for machine sleep. This does not include the MMU
- * setup, BATs, etc... but rather the "special" registers
- * like HID0, HID1, HID4, etc...
- */
-_GLOBAL(__save_cpu_setup)
-       /* Some CR fields are volatile, we back it up all */
-       mfcr    r7
-
-       /* Get storage ptr */
-       LOADADDR(r5,cpu_state_storage)
-
-       /* We only deal with 970 for now */
-       mfspr   r0,SPRN_PVR
-       srwi    r0,r0,16
-       cmpwi   r0,0x39
-       beq     1f
-       cmpwi   r0,0x3c
-       beq     1f
-       cmpwi   r0,0x44
-       bne     2f
-
-1:     /* Save HID0,1,4 and 5 */
-       mfspr   r3,SPRN_HID0
-       std     r3,CS_HID0(r5)
-       mfspr   r3,SPRN_HID1
-       std     r3,CS_HID1(r5)
-       mfspr   r3,SPRN_HID4
-       std     r3,CS_HID4(r5)
-       mfspr   r3,SPRN_HID5
-       std     r3,CS_HID5(r5)
-       
-2:
-       mtcr    r7
-       blr
-
-/* Called with no MMU context (typically MSR:IR/DR off) to
- * restore CPU state as backed up by the previous
- * function. This does not include cache setting
- */
-_GLOBAL(__restore_cpu_setup)
-       /* Get storage ptr (FIXME when using anton reloc as we
-        * are running with translation disabled here
-        */
-       LOADADDR(r5,cpu_state_storage)
-
-       /* We only deal with 970 for now */
-       mfspr   r0,SPRN_PVR
-       srwi    r0,r0,16
-       cmpwi   r0,0x39
-       beq     1f
-       cmpwi   r0,0x3c
-       beq     1f
-       cmpwi   r0,0x44
-       bnelr
-
-1:     /* Before accessing memory, we make sure rm_ci is clear */
-       li      r0,0
-       mfspr   r3,SPRN_HID4
-       rldimi  r3,r0,40,23     /* clear bit 23 (rm_ci) */
-       sync
-       mtspr   SPRN_HID4,r3
-       isync
-       sync
-
-       /* Clear interrupt prefix */
-       li      r0,0
-       sync
-       mtspr   SPRN_HIOR,0
-       isync
-
-       /* Restore HID0 */
-       ld      r3,CS_HID0(r5)
-       sync
-       isync
-       mtspr   SPRN_HID0,r3
-       mfspr   r3,SPRN_HID0
-       mfspr   r3,SPRN_HID0
-       mfspr   r3,SPRN_HID0
-       mfspr   r3,SPRN_HID0
-       mfspr   r3,SPRN_HID0
-       mfspr   r3,SPRN_HID0
-       sync
-       isync
-
-       /* Restore HID1 */
-       ld      r3,CS_HID1(r5)
-       sync
-       isync
-       mtspr   SPRN_HID1,r3
-       mtspr   SPRN_HID1,r3
-       sync
-       isync
-       
-       /* Restore HID4 */
-       ld      r3,CS_HID4(r5)
-       sync
-       isync
-       mtspr   SPRN_HID4,r3
-       sync
-       isync
-
-       /* Restore HID5 */
-       ld      r3,CS_HID5(r5)
-       sync
-       isync
-       mtspr   SPRN_HID5,r3
-       sync
-       isync
-       blr
-
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
deleted file mode 100644 (file)
index 035d1b1..0000000
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * eeh.c
- * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/bootmem.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/notifier.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/rbtree.h>
-#include <linux/seq_file.h>
-#include <linux/spinlock.h>
-#include <asm/eeh.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/rtas.h>
-#include <asm/atomic.h>
-#include <asm/systemcfg.h>
-#include <asm/ppc-pci.h>
-
-#undef DEBUG
-
-/** Overview:
- *  EEH, or "Extended Error Handling" is a PCI bridge technology for
- *  dealing with PCI bus errors that can't be dealt with within the
- *  usual PCI framework, except by check-stopping the CPU.  Systems
- *  that are designed for high-availability/reliability cannot afford
- *  to crash due to a "mere" PCI error, thus the need for EEH.
- *  An EEH-capable bridge operates by converting a detected error
- *  into a "slot freeze", taking the PCI adapter off-line, making
- *  the slot behave, from the OS'es point of view, as if the slot
- *  were "empty": all reads return 0xff's and all writes are silently
- *  ignored.  EEH slot isolation events can be triggered by parity
- *  errors on the address or data busses (e.g. during posted writes),
- *  which in turn might be caused by dust, vibration, humidity,
- *  radioactivity or plain-old failed hardware.
- *
- *  Note, however, that one of the leading causes of EEH slot
- *  freeze events are buggy device drivers, buggy device microcode,
- *  or buggy device hardware.  This is because any attempt by the
- *  device to bus-master data to a memory address that is not
- *  assigned to the device will trigger a slot freeze.   (The idea
- *  is to prevent devices-gone-wild from corrupting system memory).
- *  Buggy hardware/drivers will have a miserable time co-existing
- *  with EEH.
- *
- *  Ideally, a PCI device driver, when suspecting that an isolation
- *  event has occured (e.g. by reading 0xff's), will then ask EEH
- *  whether this is the case, and then take appropriate steps to
- *  reset the PCI slot, the PCI device, and then resume operations.
- *  However, until that day,  the checking is done here, with the
- *  eeh_check_failure() routine embedded in the MMIO macros.  If
- *  the slot is found to be isolated, an "EEH Event" is synthesized
- *  and sent out for processing.
- */
-
-/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
-#define BUID_HI(buid) ((buid) >> 32)
-#define BUID_LO(buid) ((buid) & 0xffffffff)
-
-/* EEH event workqueue setup. */
-static DEFINE_SPINLOCK(eeh_eventlist_lock);
-LIST_HEAD(eeh_eventlist);
-static void eeh_event_handler(void *);
-DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL);
-
-static struct notifier_block *eeh_notifier_chain;
-
-/*
- * If a device driver keeps reading an MMIO register in an interrupt
- * handler after a slot isolation event has occurred, we assume it
- * is broken and panic.  This sets the threshold for how many read
- * attempts we allow before panicking.
- */
-#define EEH_MAX_FAILS  1000
-static atomic_t eeh_fail_count;
-
-/* RTAS tokens */
-static int ibm_set_eeh_option;
-static int ibm_set_slot_reset;
-static int ibm_read_slot_reset_state;
-static int ibm_read_slot_reset_state2;
-static int ibm_slot_error_detail;
-
-static int eeh_subsystem_enabled;
-
-/* Buffer for reporting slot-error-detail rtas calls */
-static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
-static DEFINE_SPINLOCK(slot_errbuf_lock);
-static int eeh_error_buf_size;
-
-/* System monitoring statistics */
-static DEFINE_PER_CPU(unsigned long, total_mmio_ffs);
-static DEFINE_PER_CPU(unsigned long, false_positives);
-static DEFINE_PER_CPU(unsigned long, ignored_failures);
-static DEFINE_PER_CPU(unsigned long, slot_resets);
-
-/**
- * The pci address cache subsystem.  This subsystem places
- * PCI device address resources into a red-black tree, sorted
- * according to the address range, so that given only an i/o
- * address, the corresponding PCI device can be **quickly**
- * found. It is safe to perform an address lookup in an interrupt
- * context; this ability is an important feature.
- *
- * Currently, the only customer of this code is the EEH subsystem;
- * thus, this code has been somewhat tailored to suit EEH better.
- * In particular, the cache does *not* hold the addresses of devices
- * for which EEH is not enabled.
- *
- * (Implementation Note: The RB tree seems to be better/faster
- * than any hash algo I could think of for this problem, even
- * with the penalty of slow pointer chases for d-cache misses).
- */
-struct pci_io_addr_range
-{
-       struct rb_node rb_node;
-       unsigned long addr_lo;
-       unsigned long addr_hi;
-       struct pci_dev *pcidev;
-       unsigned int flags;
-};
-
-static struct pci_io_addr_cache
-{
-       struct rb_root rb_root;
-       spinlock_t piar_lock;
-} pci_io_addr_cache_root;
-
-static inline struct pci_dev *__pci_get_device_by_addr(unsigned long addr)
-{
-       struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
-
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-               if (addr < piar->addr_lo) {
-                       n = n->rb_left;
-               } else {
-                       if (addr > piar->addr_hi) {
-                               n = n->rb_right;
-                       } else {
-                               pci_dev_get(piar->pcidev);
-                               return piar->pcidev;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-/**
- * pci_get_device_by_addr - Get device, given only address
- * @addr: mmio (PIO) phys address or i/o port number
- *
- * Given an mmio phys address, or a port number, find a pci device
- * that implements this address.  Be sure to pci_dev_put the device
- * when finished.  I/O port numbers are assumed to be offset
- * from zero (that is, they do *not* have pci_io_addr added in).
- * It is safe to call this function within an interrupt.
- */
-static struct pci_dev *pci_get_device_by_addr(unsigned long addr)
-{
-       struct pci_dev *dev;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       dev = __pci_get_device_by_addr(addr);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-       return dev;
-}
-
-#ifdef DEBUG
-/*
- * Handy-dandy debug print routine, does nothing more
- * than print out the contents of our addr cache.
- */
-static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
-{
-       struct rb_node *n;
-       int cnt = 0;
-
-       n = rb_first(&cache->rb_root);
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
-                      (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
-                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
-               cnt++;
-               n = rb_next(n);
-       }
-}
-#endif
-
-/* Insert address range into the rb tree. */
-static struct pci_io_addr_range *
-pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
-                     unsigned long ahi, unsigned int flags)
-{
-       struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
-       struct rb_node *parent = NULL;
-       struct pci_io_addr_range *piar;
-
-       /* Walk tree, find a place to insert into tree */
-       while (*p) {
-               parent = *p;
-               piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
-               if (alo < piar->addr_lo) {
-                       p = &parent->rb_left;
-               } else if (ahi > piar->addr_hi) {
-                       p = &parent->rb_right;
-               } else {
-                       if (dev != piar->pcidev ||
-                           alo != piar->addr_lo || ahi != piar->addr_hi) {
-                               printk(KERN_WARNING "PIAR: overlapping address range\n");
-                       }
-                       return piar;
-               }
-       }
-       piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
-       if (!piar)
-               return NULL;
-
-       piar->addr_lo = alo;
-       piar->addr_hi = ahi;
-       piar->pcidev = dev;
-       piar->flags = flags;
-
-       rb_link_node(&piar->rb_node, parent, p);
-       rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
-
-       return piar;
-}
-
-static void __pci_addr_cache_insert_device(struct pci_dev *dev)
-{
-       struct device_node *dn;
-       struct pci_dn *pdn;
-       int i;
-       int inserted = 0;
-
-       dn = pci_device_to_OF_node(dev);
-       if (!dn) {
-               printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n",
-                       pci_name(dev));
-               return;
-       }
-
-       /* Skip any devices for which EEH is not enabled. */
-       pdn = dn->data;
-       if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
-           pdn->eeh_mode & EEH_MODE_NOCHECK) {
-#ifdef DEBUG
-               printk(KERN_INFO "PCI: skip building address cache for=%s\n",
-                      pci_name(dev));
-#endif
-               return;
-       }
-
-       /* The cache holds a reference to the device... */
-       pci_dev_get(dev);
-
-       /* Walk resources on this device, poke them into the tree */
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               unsigned long start = pci_resource_start(dev,i);
-               unsigned long end = pci_resource_end(dev,i);
-               unsigned int flags = pci_resource_flags(dev,i);
-
-               /* We are interested only bus addresses, not dma or other stuff */
-               if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
-                       continue;
-               if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
-                        continue;
-               pci_addr_cache_insert(dev, start, end, flags);
-               inserted = 1;
-       }
-
-       /* If there was nothing to add, the cache has no reference... */
-       if (!inserted)
-               pci_dev_put(dev);
-}
-
-/**
- * pci_addr_cache_insert_device - Add a device to the address cache
- * @dev: PCI device whose I/O addresses we are interested in.
- *
- * In order to support the fast lookup of devices based on addresses,
- * we maintain a cache of devices that can be quickly searched.
- * This routine adds a device to that cache.
- */
-void pci_addr_cache_insert_device(struct pci_dev *dev)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       __pci_addr_cache_insert_device(dev);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
-{
-       struct rb_node *n;
-       int removed = 0;
-
-restart:
-       n = rb_first(&pci_io_addr_cache_root.rb_root);
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-               if (piar->pcidev == dev) {
-                       rb_erase(n, &pci_io_addr_cache_root.rb_root);
-                       removed = 1;
-                       kfree(piar);
-                       goto restart;
-               }
-               n = rb_next(n);
-       }
-
-       /* The cache no longer holds its reference to this device... */
-       if (removed)
-               pci_dev_put(dev);
-}
-
-/**
- * pci_addr_cache_remove_device - remove pci device from addr cache
- * @dev: device to remove
- *
- * Remove a device from the addr-cache tree.
- * This is potentially expensive, since it will walk
- * the tree multiple times (once per resource).
- * But so what; device removal doesn't need to be that fast.
- */
-void pci_addr_cache_remove_device(struct pci_dev *dev)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       __pci_addr_cache_remove_device(dev);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-/**
- * pci_addr_cache_build - Build a cache of I/O addresses
- *
- * Build a cache of pci i/o addresses.  This cache will be used to
- * find the pci device that corresponds to a given address.
- * This routine scans all pci busses to build the cache.
- * Must be run late in boot process, after the pci controllers
- * have been scaned for devices (after all device resources are known).
- */
-void __init pci_addr_cache_build(void)
-{
-       struct pci_dev *dev = NULL;
-
-       spin_lock_init(&pci_io_addr_cache_root.piar_lock);
-
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               /* Ignore PCI bridges ( XXX why ??) */
-               if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
-                       continue;
-               }
-               pci_addr_cache_insert_device(dev);
-       }
-
-#ifdef DEBUG
-       /* Verify tree built up above, echo back the list of addrs. */
-       pci_addr_cache_print(&pci_io_addr_cache_root);
-#endif
-}
-
-/* --------------------------------------------------------------- */
-/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */
-
-/**
- * eeh_register_notifier - Register to find out about EEH events.
- * @nb: notifier block to callback on events
- */
-int eeh_register_notifier(struct notifier_block *nb)
-{
-       return notifier_chain_register(&eeh_notifier_chain, nb);
-}
-
-/**
- * eeh_unregister_notifier - Unregister to an EEH event notifier.
- * @nb: notifier block to callback on events
- */
-int eeh_unregister_notifier(struct notifier_block *nb)
-{
-       return notifier_chain_unregister(&eeh_notifier_chain, nb);
-}
-
-/**
- * read_slot_reset_state - Read the reset state of a device node's slot
- * @dn: device node to read
- * @rets: array to return results in
- */
-static int read_slot_reset_state(struct device_node *dn, int rets[])
-{
-       int token, outputs;
-       struct pci_dn *pdn = dn->data;
-
-       if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
-               token = ibm_read_slot_reset_state2;
-               outputs = 4;
-       } else {
-               token = ibm_read_slot_reset_state;
-               outputs = 3;
-       }
-
-       return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
-                        BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
-}
-
-/**
- * eeh_panic - call panic() for an eeh event that cannot be handled.
- * The philosophy of this routine is that it is better to panic and
- * halt the OS than it is to risk possible data corruption by
- * oblivious device drivers that don't know better.
- *
- * @dev pci device that had an eeh event
- * @reset_state current reset state of the device slot
- */
-static void eeh_panic(struct pci_dev *dev, int reset_state)
-{
-       /*
-        * XXX We should create a separate sysctl for this.
-        *
-        * Since the panic_on_oops sysctl is used to halt the system
-        * in light of potential corruption, we can use it here.
-        */
-       if (panic_on_oops)
-               panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
-                     pci_name(dev));
-       else {
-               __get_cpu_var(ignored_failures)++;
-               printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
-                      reset_state, pci_name(dev));
-       }
-}
-
-/**
- * eeh_event_handler - dispatch EEH events.  The detection of a frozen
- * slot can occur inside an interrupt, where it can be hard to do
- * anything about it.  The goal of this routine is to pull these
- * detection events out of the context of the interrupt handler, and
- * re-dispatch them for processing at a later time in a normal context.
- *
- * @dummy - unused
- */
-static void eeh_event_handler(void *dummy)
-{
-       unsigned long flags;
-       struct eeh_event        *event;
-
-       while (1) {
-               spin_lock_irqsave(&eeh_eventlist_lock, flags);
-               event = NULL;
-               if (!list_empty(&eeh_eventlist)) {
-                       event = list_entry(eeh_eventlist.next, struct eeh_event, list);
-                       list_del(&event->list);
-               }
-               spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
-               if (event == NULL)
-                       break;
-
-               printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
-                      "%s\n", event->reset_state,
-                      pci_name(event->dev));
-
-               atomic_set(&eeh_fail_count, 0);
-               notifier_call_chain (&eeh_notifier_chain,
-                                    EEH_NOTIFY_FREEZE, event);
-
-               __get_cpu_var(slot_resets)++;
-
-               pci_dev_put(event->dev);
-               kfree(event);
-       }
-}
-
-/**
- * eeh_token_to_phys - convert EEH address token to phys address
- * @token i/o token, should be address in the form 0xE....
- */
-static inline unsigned long eeh_token_to_phys(unsigned long token)
-{
-       pte_t *ptep;
-       unsigned long pa;
-
-       ptep = find_linux_pte(init_mm.pgd, token);
-       if (!ptep)
-               return token;
-       pa = pte_pfn(*ptep) << PAGE_SHIFT;
-
-       return pa | (token & (PAGE_SIZE-1));
-}
-
-/**
- * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze
- * @dn device node
- * @dev pci device, if known
- *
- * Check for an EEH failure for the given device node.  Call this
- * routine if the result of a read was all 0xff's and you want to
- * find out if this is due to an EEH slot freeze.  This routine
- * will query firmware for the EEH status.
- *
- * Returns 0 if there has not been an EEH error; otherwise returns
- * a non-zero value and queues up a solt isolation event notification.
- *
- * It is safe to call this routine in an interrupt context.
- */
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
-{
-       int ret;
-       int rets[3];
-       unsigned long flags;
-       int rc, reset_state;
-       struct eeh_event  *event;
-       struct pci_dn *pdn;
-
-       __get_cpu_var(total_mmio_ffs)++;
-
-       if (!eeh_subsystem_enabled)
-               return 0;
-
-       if (!dn)
-               return 0;
-       pdn = dn->data;
-
-       /* Access to IO BARs might get this far and still not want checking. */
-       if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
-           pdn->eeh_mode & EEH_MODE_NOCHECK) {
-               return 0;
-       }
-
-       if (!pdn->eeh_config_addr) {
-               return 0;
-       }
-
-       /*
-        * If we already have a pending isolation event for this
-        * slot, we know it's bad already, we don't need to check...
-        */
-       if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
-               atomic_inc(&eeh_fail_count);
-               if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
-                       /* re-read the slot reset state */
-                       if (read_slot_reset_state(dn, rets) != 0)
-                               rets[0] = -1;   /* reset state unknown */
-                       eeh_panic(dev, rets[0]);
-               }
-               return 0;
-       }
-
-       /*
-        * Now test for an EEH failure.  This is VERY expensive.
-        * Note that the eeh_config_addr may be a parent device
-        * in the case of a device behind a bridge, or it may be
-        * function zero of a multi-function device.
-        * In any case they must share a common PHB.
-        */
-       ret = read_slot_reset_state(dn, rets);
-       if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) {
-               __get_cpu_var(false_positives)++;
-               return 0;
-       }
-
-       /* prevent repeated reports of this failure */
-       pdn->eeh_mode |= EEH_MODE_ISOLATED;
-
-       reset_state = rets[0];
-
-       spin_lock_irqsave(&slot_errbuf_lock, flags);
-       memset(slot_errbuf, 0, eeh_error_buf_size);
-
-       rc = rtas_call(ibm_slot_error_detail,
-                      8, 1, NULL, pdn->eeh_config_addr,
-                      BUID_HI(pdn->phb->buid),
-                      BUID_LO(pdn->phb->buid), NULL, 0,
-                      virt_to_phys(slot_errbuf),
-                      eeh_error_buf_size,
-                      1 /* Temporary Error */);
-
-       if (rc == 0)
-               log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
-       spin_unlock_irqrestore(&slot_errbuf_lock, flags);
-
-       printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n",
-              rets[0], dn->name, dn->full_name);
-       event = kmalloc(sizeof(*event), GFP_ATOMIC);
-       if (event == NULL) {
-               eeh_panic(dev, reset_state);
-               return 1;
-       }
-
-       event->dev = dev;
-       event->dn = dn;
-       event->reset_state = reset_state;
-
-       /* We may or may not be called in an interrupt context */
-       spin_lock_irqsave(&eeh_eventlist_lock, flags);
-       list_add(&event->list, &eeh_eventlist);
-       spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
-
-       /* Most EEH events are due to device driver bugs.  Having
-        * a stack trace will help the device-driver authors figure
-        * out what happened.  So print that out. */
-       dump_stack();
-       schedule_work(&eeh_event_wq);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(eeh_dn_check_failure);
-
-/**
- * eeh_check_failure - check if all 1's data is due to EEH slot freeze
- * @token i/o token, should be address in the form 0xA....
- * @val value, should be all 1's (XXX why do we need this arg??)
- *
- * Check for an eeh failure at the given token address.
- * Check for an EEH failure at the given token address.  Call this
- * routine if the result of a read was all 0xff's and you want to
- * find out if this is due to an EEH slot freeze event.  This routine
- * will query firmware for the EEH status.
- *
- * Note this routine is safe to call in an interrupt context.
- */
-unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
-{
-       unsigned long addr;
-       struct pci_dev *dev;
-       struct device_node *dn;
-
-       /* Finding the phys addr + pci device; this is pretty quick. */
-       addr = eeh_token_to_phys((unsigned long __force) token);
-       dev = pci_get_device_by_addr(addr);
-       if (!dev)
-               return val;
-
-       dn = pci_device_to_OF_node(dev);
-       eeh_dn_check_failure (dn, dev);
-
-       pci_dev_put(dev);
-       return val;
-}
-
-EXPORT_SYMBOL(eeh_check_failure);
-
-struct eeh_early_enable_info {
-       unsigned int buid_hi;
-       unsigned int buid_lo;
-};
-
-/* Enable eeh for the given device node. */
-static void *early_enable_eeh(struct device_node *dn, void *data)
-{
-       struct eeh_early_enable_info *info = data;
-       int ret;
-       char *status = get_property(dn, "status", NULL);
-       u32 *class_code = (u32 *)get_property(dn, "class-code", NULL);
-       u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL);
-       u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
-       u32 *regs;
-       int enable;
-       struct pci_dn *pdn = dn->data;
-
-       pdn->eeh_mode = 0;
-
-       if (status && strcmp(status, "ok") != 0)
-               return NULL;    /* ignore devices with bad status */
-
-       /* Ignore bad nodes. */
-       if (!class_code || !vendor_id || !device_id)
-               return NULL;
-
-       /* There is nothing to check on PCI to ISA bridges */
-       if (dn->type && !strcmp(dn->type, "isa")) {
-               pdn->eeh_mode |= EEH_MODE_NOCHECK;
-               return NULL;
-       }
-
-       /*
-        * Now decide if we are going to "Disable" EEH checking
-        * for this device.  We still run with the EEH hardware active,
-        * but we won't be checking for ff's.  This means a driver
-        * could return bad data (very bad!), an interrupt handler could
-        * hang waiting on status bits that won't change, etc.
-        * But there are a few cases like display devices that make sense.
-        */
-       enable = 1;     /* i.e. we will do checking */
-       if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
-               enable = 0;
-
-       if (!enable)
-               pdn->eeh_mode |= EEH_MODE_NOCHECK;
-
-       /* Ok... see if this device supports EEH.  Some do, some don't,
-        * and the only way to find out is to check each and every one. */
-       regs = (u32 *)get_property(dn, "reg", NULL);
-       if (regs) {
-               /* First register entry is addr (00BBSS00)  */
-               /* Try to enable eeh */
-               ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-                               regs[0], info->buid_hi, info->buid_lo,
-                               EEH_ENABLE);
-               if (ret == 0) {
-                       eeh_subsystem_enabled = 1;
-                       pdn->eeh_mode |= EEH_MODE_SUPPORTED;
-                       pdn->eeh_config_addr = regs[0];
-#ifdef DEBUG
-                       printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
-#endif
-               } else {
-
-                       /* This device doesn't support EEH, but it may have an
-                        * EEH parent, in which case we mark it as supported. */
-                       if (dn->parent && dn->parent->data
-                           && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
-                               /* Parent supports EEH. */
-                               pdn->eeh_mode |= EEH_MODE_SUPPORTED;
-                               pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
-                               return NULL;
-                       }
-               }
-       } else {
-               printk(KERN_WARNING "EEH: %s: unable to get reg property.\n",
-                      dn->full_name);
-       }
-
-       return NULL; 
-}
-
-/*
- * Initialize EEH by trying to enable it for all of the adapters in the system.
- * As a side effect we can determine here if eeh is supported at all.
- * Note that we leave EEH on so failed config cycles won't cause a machine
- * check.  If a user turns off EEH for a particular adapter they are really
- * telling Linux to ignore errors.  Some hardware (e.g. POWER5) won't
- * grant access to a slot if EEH isn't enabled, and so we always enable
- * EEH for all slots/all devices.
- *
- * The eeh-force-off option disables EEH checking globally, for all slots.
- * Even if force-off is set, the EEH hardware is still enabled, so that
- * newer systems can boot.
- */
-void __init eeh_init(void)
-{
-       struct device_node *phb, *np;
-       struct eeh_early_enable_info info;
-
-       np = of_find_node_by_path("/rtas");
-       if (np == NULL)
-               return;
-
-       ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
-       ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-       ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
-       ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-       ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-
-       if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
-               return;
-
-       eeh_error_buf_size = rtas_token("rtas-error-log-max");
-       if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-               eeh_error_buf_size = 1024;
-       }
-       if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-               printk(KERN_WARNING "EEH: rtas-error-log-max is bigger than allocated "
-                     "buffer ! (%d vs %d)", eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-               eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-       }
-
-       /* Enable EEH for all adapters.  Note that eeh requires buid's */
-       for (phb = of_find_node_by_name(NULL, "pci"); phb;
-            phb = of_find_node_by_name(phb, "pci")) {
-               unsigned long buid;
-               struct pci_dn *pci;
-
-               buid = get_phb_buid(phb);
-               if (buid == 0 || phb->data == NULL)
-                       continue;
-
-               pci = phb->data;
-               info.buid_lo = BUID_LO(buid);
-               info.buid_hi = BUID_HI(buid);
-               traverse_pci_devices(phb, early_enable_eeh, &info);
-       }
-
-       if (eeh_subsystem_enabled)
-               printk(KERN_INFO "EEH: PCI Enhanced I/O Error Handling Enabled\n");
-       else
-               printk(KERN_WARNING "EEH: No capable adapters found\n");
-}
-
-/**
- * eeh_add_device_early - enable EEH for the indicated device_node
- * @dn: device node for which to set up EEH
- *
- * This routine must be used to perform EEH initialization for PCI
- * devices that were added after system boot (e.g. hotplug, dlpar).
- * This routine must be called before any i/o is performed to the
- * adapter (inluding any config-space i/o).
- * Whether this actually enables EEH or not for this device depends
- * on the CEC architecture, type of the device, on earlier boot
- * command-line arguments & etc.
- */
-void eeh_add_device_early(struct device_node *dn)
-{
-       struct pci_controller *phb;
-       struct eeh_early_enable_info info;
-
-       if (!dn || !dn->data)
-               return;
-       phb = PCI_DN(dn)->phb;
-       if (NULL == phb || 0 == phb->buid) {
-               printk(KERN_WARNING "EEH: Expected buid but found none\n");
-               return;
-       }
-
-       info.buid_hi = BUID_HI(phb->buid);
-       info.buid_lo = BUID_LO(phb->buid);
-       early_enable_eeh(dn, &info);
-}
-EXPORT_SYMBOL(eeh_add_device_early);
-
-/**
- * eeh_add_device_late - perform EEH initialization for the indicated pci device
- * @dev: pci device for which to set up EEH
- *
- * This routine must be used to complete EEH initialization for PCI
- * devices that were added after system boot (e.g. hotplug, dlpar).
- */
-void eeh_add_device_late(struct pci_dev *dev)
-{
-       if (!dev || !eeh_subsystem_enabled)
-               return;
-
-#ifdef DEBUG
-       printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
-#endif
-
-       pci_addr_cache_insert_device (dev);
-}
-EXPORT_SYMBOL(eeh_add_device_late);
-
-/**
- * eeh_remove_device - undo EEH setup for the indicated pci device
- * @dev: pci device to be removed
- *
- * This routine should be when a device is removed from a running
- * system (e.g. by hotplug or dlpar).
- */
-void eeh_remove_device(struct pci_dev *dev)
-{
-       if (!dev || !eeh_subsystem_enabled)
-               return;
-
-       /* Unregister the device with the EEH/PCI address search system */
-#ifdef DEBUG
-       printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
-#endif
-       pci_addr_cache_remove_device(dev);
-}
-EXPORT_SYMBOL(eeh_remove_device);
-
-static int proc_eeh_show(struct seq_file *m, void *v)
-{
-       unsigned int cpu;
-       unsigned long ffs = 0, positives = 0, failures = 0;
-       unsigned long resets = 0;
-
-       for_each_cpu(cpu) {
-               ffs += per_cpu(total_mmio_ffs, cpu);
-               positives += per_cpu(false_positives, cpu);
-               failures += per_cpu(ignored_failures, cpu);
-               resets += per_cpu(slot_resets, cpu);
-       }
-
-       if (0 == eeh_subsystem_enabled) {
-               seq_printf(m, "EEH Subsystem is globally disabled\n");
-               seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs);
-       } else {
-               seq_printf(m, "EEH Subsystem is enabled\n");
-               seq_printf(m, "eeh_total_mmio_ffs=%ld\n"
-                          "eeh_false_positives=%ld\n"
-                          "eeh_ignored_failures=%ld\n"
-                          "eeh_slot_resets=%ld\n"
-                               "eeh_fail_count=%d\n",
-                          ffs, positives, failures, resets,
-                               eeh_fail_count.counter);
-       }
-
-       return 0;
-}
-
-static int proc_eeh_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, proc_eeh_show, NULL);
-}
-
-static struct file_operations proc_eeh_operations = {
-       .open      = proc_eeh_open,
-       .read      = seq_read,
-       .llseek    = seq_lseek,
-       .release   = single_release,
-};
-
-static int __init eeh_init_proc(void)
-{
-       struct proc_dir_entry *e;
-
-       if (systemcfg->platform & PLATFORM_PSERIES) {
-               e = create_proc_entry("ppc64/eeh", 0, NULL);
-               if (e)
-                       e->proc_fops = &proc_eeh_operations;
-       }
-
-       return 0;
-}
-__initcall(eeh_init_proc);
diff --git a/arch/ppc64/kernel/firmware.c b/arch/ppc64/kernel/firmware.c
deleted file mode 100644 (file)
index d8432c0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  arch/ppc64/kernel/firmware.c
- *
- *  Extracted from cputable.c
- *
- *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- *  Modifications for ppc64:
- *      Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
- *  Copyright (C) 2005 Stephen Rothwell, IBM Corporation
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-
-#include <asm/firmware.h>
-
-unsigned long ppc64_firmware_features;
-
-#ifdef CONFIG_PPC_PSERIES
-firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
-       {FW_FEATURE_PFT,                "hcall-pft"},
-       {FW_FEATURE_TCE,                "hcall-tce"},
-       {FW_FEATURE_SPRG0,              "hcall-sprg0"},
-       {FW_FEATURE_DABR,               "hcall-dabr"},
-       {FW_FEATURE_COPY,               "hcall-copy"},
-       {FW_FEATURE_ASR,                "hcall-asr"},
-       {FW_FEATURE_DEBUG,              "hcall-debug"},
-       {FW_FEATURE_PERF,               "hcall-perf"},
-       {FW_FEATURE_DUMP,               "hcall-dump"},
-       {FW_FEATURE_INTERRUPT,          "hcall-interrupt"},
-       {FW_FEATURE_MIGRATE,            "hcall-migrate"},
-       {FW_FEATURE_PERFMON,            "hcall-perfmon"},
-       {FW_FEATURE_CRQ,                "hcall-crq"},
-       {FW_FEATURE_VIO,                "hcall-vio"},
-       {FW_FEATURE_RDMA,               "hcall-rdma"},
-       {FW_FEATURE_LLAN,               "hcall-lLAN"},
-       {FW_FEATURE_BULK,               "hcall-bulk"},
-       {FW_FEATURE_XDABR,              "hcall-xdabr"},
-       {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
-       {FW_FEATURE_SPLPAR,             "hcall-splpar"},
-};
-#endif
index 9e8050ea1225fa05c002328203d76ca94d82f6dc..1c869ea72d28448c45124e5e881a307e7e0d5388 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/systemcfg.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/bug.h>
@@ -1701,21 +1700,9 @@ _GLOBAL(__secondary_start)
        HMT_MEDIUM                      /* Set thread priority to MEDIUM */
 
        ld      r2,PACATOC(r13)
-       li      r6,0
-       stb     r6,PACAPROCENABLED(r13)
-
-#ifndef CONFIG_PPC_ISERIES
-       /* Initialize the page table pointer register. */
-       LOADADDR(r6,_SDR1)
-       ld      r6,0(r6)                /* get the value of _SDR1        */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location         */
-#endif
-       /* Initialize the first segment table (or SLB) entry             */
-       ld      r3,PACASTABVIRT(r13)    /* get addr of segment table     */
-BEGIN_FTR_SECTION
-       bl      .stab_initialize
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-       bl      .slb_initialize
+
+       /* Do early setup for that CPU */
+       bl      .early_setup_secondary
 
        /* Initialize the kernel stack.  Just a repeat for iSeries.      */
        LOADADDR(r3,current_set)
@@ -1724,37 +1711,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
        std     r1,PACAKSAVE(r13)
 
-       ld      r3,PACASTABREAL(r13)    /* get raddr of segment table    */
-       ori     r4,r3,1                 /* turn on valid bit             */
-
-#ifdef CONFIG_PPC_ISERIES
-       li      r0,-1                   /* hypervisor call */
-       li      r3,1
-       sldi    r3,r3,63                /* 0x8000000000000000 */
-       ori     r3,r3,4                 /* 0x8000000000000004 */
-       sc                              /* HvCall_setASR */
-#else
-       /* set the ASR */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg         */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags           */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar  */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star)  */
-       mtasr   r4                      /* set the stab location         */
-99:
-#endif
        li      r7,0
        mtlr    r7
 
@@ -1896,40 +1852,6 @@ _STATIC(start_here_multiplatform)
        mr      r3,r31
        bl      .early_setup
 
-       /* set the ASR */
-       ld      r3,PACASTABREAL(r13)
-       ori     r4,r3,1                 /* turn on valid bit             */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star) */
-       mtasr   r4                      /* set the stab location        */
-99:
-       /* Set SDR1 (hash table pointer) */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       /* Test if bit 0 is set (LPAR bit) */
-       andi.   r3,r3,PLATFORM_LPAR
-       bne     98f                     /* branch if result is !0  */
-       LOADADDR(r6,_SDR1)              /* Only if NOT LPAR */
-       sub     r6,r6,r26
-       ld      r6,0(r6)                /* get the value of _SDR1 */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location  */
-98: 
        LOADADDR(r3,.start_here_common)
        SET_REG_TO_CONST(r4, MSR_KERNEL)
        mtspr   SPRN_SRR0,r3
index 715bc0e71e0f4dbc45327ce08a59a5a1ab58a335..b879d3057ef83d5ba5287321a6d3d5550554b8d3 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/processor.h>
 #include <asm/cputable.h>
 #include <asm/time.h>
-#include <asm/systemcfg.h>
 #include <asm/machdep.h>
 #include <asm/smp.h>
 
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
deleted file mode 100644 (file)
index ba4a899..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* 
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- * 
- * Based on sparc64 ioctl32.c by:
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- *
- * ppc64 changes:
- *
- * Copyright (C) 2000  Ken Aaker (kdaaker@rchland.vnet.ibm.com)
- * Copyright (C) 2001  Anton Blanchard (antonb@au.ibm.com)
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- *
- * 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.
- */
-
-#define INCLUDES
-#include "compat_ioctl.c"
-#include <linux/syscalls.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-
-#define IOCTL_TABLE_START \
-       struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-       };
-
-IOCTL_TABLE_START
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-
-/* Little p (/dev/rtc, /dev/envctrl, etc.) */
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
deleted file mode 100644 (file)
index 8747458..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *  arch/ppc/kernel/irq.c
- *
- *  Derived from arch/i386/kernel/irq.c
- *    Copyright (C) 1992 Linus Torvalds
- *  Adapted from arch/i386 by Gary Thomas
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *  Updated and modified by Cort Dougan (cort@cs.nmt.edu)
- *    Copyright (C) 1996 Cort Dougan
- *  Adapted for Power Macintosh by Paul Mackerras
- *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- * 
- * 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 file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/threads.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
-#include <linux/random.h>
-#include <linux/kallsyms.h>
-#include <linux/profile.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/cache.h>
-#include <asm/prom.h>
-#include <asm/ptrace.h>
-#include <asm/iseries/it_lp_queue.h>
-#include <asm/machdep.h>
-#include <asm/paca.h>
-
-#ifdef CONFIG_SMP
-extern void iSeries_smp_message_recv( struct pt_regs * );
-#endif
-
-extern irq_desc_t irq_desc[NR_IRQS];
-EXPORT_SYMBOL(irq_desc);
-
-int distribute_irqs = 1;
-int __irq_offset_value;
-int ppc_spurious_interrupts;
-u64 ppc64_interrupt_controller;
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v, j;
-       struct irqaction * action;
-       irq_desc_t *desc;
-       unsigned long flags;
-
-       if (i == 0) {
-               seq_printf(p, "           ");
-               for (j=0; j<NR_CPUS; j++) {
-                       if (cpu_online(j))
-                               seq_printf(p, "CPU%d       ",j);
-               }
-               seq_putc(p, '\n');
-       }
-
-       if (i < NR_IRQS) {
-               desc = get_irq_desc(i);
-               spin_lock_irqsave(&desc->lock, flags);
-               action = desc->action;
-               if (!action || !action->handler)
-                       goto skip;
-               seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
-               for (j = 0; j < NR_CPUS; j++) {
-                       if (cpu_online(j))
-                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-               }
-#else
-               seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
-               if (desc->handler)
-                       seq_printf(p, " %s ", desc->handler->typename );
-               else
-                       seq_printf(p, "  None      ");
-               seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
-               seq_printf(p, "    %s",action->name);
-               for (action=action->next; action; action = action->next)
-                       seq_printf(p, ", %s", action->name);
-               seq_putc(p, '\n');
-skip:
-               spin_unlock_irqrestore(&desc->lock, flags);
-       } else if (i == NR_IRQS)
-               seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
-       return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(cpumask_t map)
-{
-       unsigned int irq;
-       static int warned;
-
-       for_each_irq(irq) {
-               cpumask_t mask;
-
-               if (irq_desc[irq].status & IRQ_PER_CPU)
-                       continue;
-
-               cpus_and(mask, irq_affinity[irq], map);
-               if (any_online_cpu(mask) == NR_CPUS) {
-                       printk("Breaking affinity for irq %i\n", irq);
-                       mask = map;
-               }
-               if (irq_desc[irq].handler->set_affinity)
-                       irq_desc[irq].handler->set_affinity(irq, mask);
-               else if (irq_desc[irq].action && !(warned++))
-                       printk("Cannot set affinity for irq %i\n", irq);
-       }
-
-       local_irq_enable();
-       mdelay(1);
-       local_irq_disable();
-}
-#endif
-
-extern int noirqdebug;
-
-/*
- * Eventually, this should take an array of interrupts and an array size
- * so it can dispatch multiple interrupts.
- */
-void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
-{
-       int status;
-       struct irqaction *action;
-       int cpu = smp_processor_id();
-       irq_desc_t *desc = get_irq_desc(irq);
-       irqreturn_t action_ret;
-#ifdef CONFIG_IRQSTACKS
-       struct thread_info *curtp, *irqtp;
-#endif
-
-       kstat_cpu(cpu).irqs[irq]++;
-
-       if (desc->status & IRQ_PER_CPU) {
-               /* no locking required for CPU-local interrupts: */
-               ack_irq(irq);
-               action_ret = handle_IRQ_event(irq, regs, desc->action);
-               desc->handler->end(irq);
-               return;
-       }
-
-       spin_lock(&desc->lock);
-       ack_irq(irq);   
-       /*
-          REPLAY is when Linux resends an IRQ that was dropped earlier
-          WAITING is used by probe to mark irqs that are being tested
-          */
-       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-       status |= IRQ_PENDING; /* we _want_ to handle it */
-
-       /*
-        * If the IRQ is disabled for whatever reason, we cannot
-        * use the action we have.
-        */
-       action = NULL;
-       if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
-               action = desc->action;
-               if (!action || !action->handler) {
-                       ppc_spurious_interrupts++;
-                       printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
-                       /* We can't call disable_irq here, it would deadlock */
-                       if (!desc->depth)
-                               desc->depth = 1;
-                       desc->status |= IRQ_DISABLED;
-                       /* This is not a real spurrious interrupt, we
-                        * have to eoi it, so we jump to out
-                        */
-                       mask_irq(irq);
-                       goto out;
-               }
-               status &= ~IRQ_PENDING; /* we commit to handling */
-               status |= IRQ_INPROGRESS; /* we are handling it */
-       }
-       desc->status = status;
-
-       /*
-        * If there is no IRQ handler or it was disabled, exit early.
-          Since we set PENDING, if another processor is handling
-          a different instance of this same irq, the other processor
-          will take care of it.
-        */
-       if (unlikely(!action))
-               goto out;
-
-       /*
-        * Edge triggered interrupts need to remember
-        * pending events.
-        * This applies to any hw interrupts that allow a second
-        * instance of the same irq to arrive while we are in do_IRQ
-        * or in the handler. But the code here only handles the _second_
-        * instance of the irq, not the third or fourth. So it is mostly
-        * useful for irq hardware that does not mask cleanly in an
-        * SMP environment.
-        */
-       for (;;) {
-               spin_unlock(&desc->lock);
-
-#ifdef CONFIG_IRQSTACKS
-               /* Switch to the irq stack to handle this */
-               curtp = current_thread_info();
-               irqtp = hardirq_ctx[smp_processor_id()];
-               if (curtp != irqtp) {
-                       irqtp->task = curtp->task;
-                       irqtp->flags = 0;
-                       action_ret = call_handle_IRQ_event(irq, regs, action, irqtp);
-                       irqtp->task = NULL;
-                       if (irqtp->flags)
-                               set_bits(irqtp->flags, &curtp->flags);
-               } else
-#endif
-                       action_ret = handle_IRQ_event(irq, regs, action);
-
-               spin_lock(&desc->lock);
-               if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret, regs);
-               if (likely(!(desc->status & IRQ_PENDING)))
-                       break;
-               desc->status &= ~IRQ_PENDING;
-       }
-out:
-       desc->status &= ~IRQ_INPROGRESS;
-       /*
-        * The ->end() handler has to deal with interrupts which got
-        * disabled while the handler was running.
-        */
-       if (desc->handler) {
-               if (desc->handler->end)
-                       desc->handler->end(irq);
-               else if (desc->handler->enable)
-                       desc->handler->enable(irq);
-       }
-       spin_unlock(&desc->lock);
-}
-
-#ifdef CONFIG_PPC_ISERIES
-void do_IRQ(struct pt_regs *regs)
-{
-       struct paca_struct *lpaca;
-
-       irq_enter();
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-       /* Debugging check for stack overflow: is there less than 2KB free? */
-       {
-               long sp;
-
-               sp = __get_SP() & (THREAD_SIZE-1);
-
-               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
-                       printk("do_IRQ: stack overflow: %ld\n",
-                               sp - sizeof(struct thread_info));
-                       dump_stack();
-               }
-       }
-#endif
-
-       lpaca = get_paca();
-#ifdef CONFIG_SMP
-       if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
-               lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
-               iSeries_smp_message_recv(regs);
-       }
-#endif /* CONFIG_SMP */
-       if (hvlpevent_is_pending())
-               process_hvlpevents(regs);
-
-       irq_exit();
-
-       if (lpaca->lppaca.int_dword.fields.decr_int) {
-               lpaca->lppaca.int_dword.fields.decr_int = 0;
-               /* Signal a fake decrementer interrupt */
-               timer_interrupt(regs);
-       }
-}
-
-#else  /* CONFIG_PPC_ISERIES */
-
-void do_IRQ(struct pt_regs *regs)
-{
-       int irq;
-
-       irq_enter();
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-       /* Debugging check for stack overflow: is there less than 2KB free? */
-       {
-               long sp;
-
-               sp = __get_SP() & (THREAD_SIZE-1);
-
-               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
-                       printk("do_IRQ: stack overflow: %ld\n",
-                               sp - sizeof(struct thread_info));
-                       dump_stack();
-               }
-       }
-#endif
-
-       irq = ppc_md.get_irq(regs);
-
-       if (irq >= 0)
-               ppc_irq_dispatch_handler(regs, irq);
-       else
-               /* That's not SMP safe ... but who cares ? */
-               ppc_spurious_interrupts++;
-
-       irq_exit();
-}
-#endif /* CONFIG_PPC_ISERIES */
-
-void __init init_IRQ(void)
-{
-       static int once = 0;
-
-       if (once)
-               return;
-
-       once++;
-
-       ppc_md.init_IRQ();
-       irq_ctx_init();
-}
-
-#ifndef CONFIG_PPC_ISERIES
-/*
- * Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
- */
-
-#define UNDEFINED_IRQ 0xffffffff
-unsigned int virt_irq_to_real_map[NR_IRQS];
-
-/*
- * Don't use virtual irqs 0, 1, 2 for devices.
- * The pcnet32 driver considers interrupt numbers < 2 to be invalid,
- * and 2 is the XICS IPI interrupt.
- * We limit virtual irqs to 17 less than NR_IRQS so that when we
- * offset them by 16 (to reserve the first 16 for ISA interrupts)
- * we don't end up with an interrupt number >= NR_IRQS.
- */
-#define MIN_VIRT_IRQ   3
-#define MAX_VIRT_IRQ   (NR_IRQS - NUM_ISA_INTERRUPTS - 1)
-#define NR_VIRT_IRQS   (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1)
-
-void
-virt_irq_init(void)
-{
-       int i;
-       for (i = 0; i < NR_IRQS; i++)
-               virt_irq_to_real_map[i] = UNDEFINED_IRQ;
-}
-
-/* Create a mapping for a real_irq if it doesn't already exist.
- * Return the virtual irq as a convenience.
- */
-int virt_irq_create_mapping(unsigned int real_irq)
-{
-       unsigned int virq, first_virq;
-       static int warned;
-
-       if (ppc64_interrupt_controller == IC_OPEN_PIC)
-               return real_irq;        /* no mapping for openpic (for now) */
-
-       if (ppc64_interrupt_controller == IC_CELL_PIC)
-               return real_irq;        /* no mapping for iic either */
-
-       /* don't map interrupts < MIN_VIRT_IRQ */
-       if (real_irq < MIN_VIRT_IRQ) {
-               virt_irq_to_real_map[real_irq] = real_irq;
-               return real_irq;
-       }
-
-       /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */
-       virq = real_irq;
-       if (virq > MAX_VIRT_IRQ)
-               virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
-
-       /* search for this number or a free slot */
-       first_virq = virq;
-       while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) {
-               if (virt_irq_to_real_map[virq] == real_irq)
-                       return virq;
-               if (++virq > MAX_VIRT_IRQ)
-                       virq = MIN_VIRT_IRQ;
-               if (virq == first_virq)
-                       goto nospace;   /* oops, no free slots */
-       }
-
-       virt_irq_to_real_map[virq] = real_irq;
-       return virq;
-
- nospace:
-       if (!warned) {
-               printk(KERN_CRIT "Interrupt table is full\n");
-               printk(KERN_CRIT "Increase NR_IRQS (currently %d) "
-                      "in your kernel sources and rebuild.\n", NR_IRQS);
-               warned = 1;
-       }
-       return NO_IRQ;
-}
-
-/*
- * In most cases will get a hit on the very first slot checked in the
- * virt_irq_to_real_map.  Only when there are a large number of
- * IRQs will this be expensive.
- */
-unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
-{
-       unsigned int virq;
-       unsigned int first_virq;
-
-       virq = real_irq;
-
-       if (virq > MAX_VIRT_IRQ)
-               virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
-
-       first_virq = virq;
-
-       do {
-               if (virt_irq_to_real_map[virq] == real_irq)
-                       return virq;
-
-               virq++;
-
-               if (virq >= MAX_VIRT_IRQ)
-                       virq = 0;
-
-       } while (first_virq != virq);
-
-       return NO_IRQ;
-
-}
-
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_IRQSTACKS
-struct thread_info *softirq_ctx[NR_CPUS];
-struct thread_info *hardirq_ctx[NR_CPUS];
-
-void irq_ctx_init(void)
-{
-       struct thread_info *tp;
-       int i;
-
-       for_each_cpu(i) {
-               memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
-               tp = softirq_ctx[i];
-               tp->cpu = i;
-               tp->preempt_count = SOFTIRQ_OFFSET;
-
-               memset((void *)hardirq_ctx[i], 0, THREAD_SIZE);
-               tp = hardirq_ctx[i];
-               tp->cpu = i;
-               tp->preempt_count = HARDIRQ_OFFSET;
-       }
-}
-
-void do_softirq(void)
-{
-       unsigned long flags;
-       struct thread_info *curtp, *irqtp;
-
-       if (in_interrupt())
-               return;
-
-       local_irq_save(flags);
-
-       if (local_softirq_pending()) {
-               curtp = current_thread_info();
-               irqtp = softirq_ctx[smp_processor_id()];
-               irqtp->task = curtp->task;
-               call_do_softirq(irqtp);
-               irqtp->task = NULL;
-       }
-
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(do_softirq);
-
-#endif /* CONFIG_IRQSTACKS */
-
-static int __init setup_noirqdistrib(char *str)
-{
-       distribute_irqs = 0;
-       return 1;
-}
-
-__setup("noirqdistrib", setup_noirqdistrib);
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c
deleted file mode 100644 (file)
index 3e7b2f2..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * PowerPC64 LPAR Configuration Information Driver
- *
- * Dave Engebretsen engebret@us.ibm.com
- *    Copyright (c) 2003 Dave Engebretsen
- * Will Schmidt willschm@us.ibm.com
- *    SPLPAR updates, Copyright (c) 2003 Will Schmidt IBM Corporation.
- *    seq_file updates, Copyright (c) 2004 Will Schmidt IBM Corporation.
- * Nathan Lynch nathanl@austin.ibm.com
- *    Added lparcfg_write, Copyright (C) 2004 Nathan Lynch IBM Corporation.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- *
- * This driver creates a proc file at /proc/ppc64/lparcfg which contains
- * keyword - value pairs that specify the configuration of the partition.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#include <asm/iseries/hv_lp_config.h>
-#include <asm/lppaca.h>
-#include <asm/hvcall.h>
-#include <asm/firmware.h>
-#include <asm/rtas.h>
-#include <asm/system.h>
-#include <asm/time.h>
-#include <asm/iseries/it_exp_vpd_panel.h>
-#include <asm/prom.h>
-
-#define MODULE_VERS "1.6"
-#define MODULE_NAME "lparcfg"
-
-/* #define LPARCFG_DEBUG */
-
-/* find a better place for this function... */
-void log_plpar_hcall_return(unsigned long rc, char *tag)
-{
-       if (rc == 0)            /* success, return */
-               return;
-/* check for null tag ? */
-       if (rc == H_Hardware)
-               printk(KERN_INFO
-                      "plpar-hcall (%s) failed with hardware fault\n", tag);
-       else if (rc == H_Function)
-               printk(KERN_INFO
-                      "plpar-hcall (%s) failed; function not allowed\n", tag);
-       else if (rc == H_Authority)
-               printk(KERN_INFO
-                      "plpar-hcall (%s) failed; not authorized to this function\n",
-                      tag);
-       else if (rc == H_Parameter)
-               printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
-                      tag);
-       else
-               printk(KERN_INFO
-                      "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
-                      tag, rc);
-
-}
-
-static struct proc_dir_entry *proc_ppc64_lparcfg;
-#define LPARCFG_BUFF_SIZE 4096
-
-#ifdef CONFIG_PPC_ISERIES
-
-/*
- * For iSeries legacy systems, the PPA purr function is available from the
- * emulated_time_base field in the paca.
- */
-static unsigned long get_purr(void)
-{
-       unsigned long sum_purr = 0;
-       int cpu;
-       struct paca_struct *lpaca;
-
-       for_each_cpu(cpu) {
-               lpaca = paca + cpu;
-               sum_purr += lpaca->lppaca.emulated_time_base;
-
-#ifdef PURR_DEBUG
-               printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
-                       cpu, lpaca->lppaca.emulated_time_base);
-#endif
-       }
-       return sum_purr;
-}
-
-#define lparcfg_write NULL
-
-/* 
- * Methods used to fetch LPAR data when running on an iSeries platform.
- */
-static int lparcfg_data(struct seq_file *m, void *v)
-{
-       unsigned long pool_id, lp_index;
-       int shared, entitled_capacity, max_entitled_capacity;
-       int processors, max_processors;
-       struct paca_struct *lpaca = get_paca();
-       unsigned long purr = get_purr();
-
-       seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
-       shared = (int)(lpaca->lppaca_ptr->shared_proc);
-       seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
-                  e2a(xItExtVpdPanel.mfgID[2]),
-                  e2a(xItExtVpdPanel.mfgID[3]),
-                  e2a(xItExtVpdPanel.systemSerial[1]),
-                  e2a(xItExtVpdPanel.systemSerial[2]),
-                  e2a(xItExtVpdPanel.systemSerial[3]),
-                  e2a(xItExtVpdPanel.systemSerial[4]),
-                  e2a(xItExtVpdPanel.systemSerial[5]));
-
-       seq_printf(m, "system_type=%c%c%c%c\n",
-                  e2a(xItExtVpdPanel.machineType[0]),
-                  e2a(xItExtVpdPanel.machineType[1]),
-                  e2a(xItExtVpdPanel.machineType[2]),
-                  e2a(xItExtVpdPanel.machineType[3]));
-
-       lp_index = HvLpConfig_getLpIndex();
-       seq_printf(m, "partition_id=%d\n", (int)lp_index);
-
-       seq_printf(m, "system_active_processors=%d\n",
-                  (int)HvLpConfig_getSystemPhysicalProcessors());
-
-       seq_printf(m, "system_potential_processors=%d\n",
-                  (int)HvLpConfig_getSystemPhysicalProcessors());
-
-       processors = (int)HvLpConfig_getPhysicalProcessors();
-       seq_printf(m, "partition_active_processors=%d\n", processors);
-
-       max_processors = (int)HvLpConfig_getMaxPhysicalProcessors();
-       seq_printf(m, "partition_potential_processors=%d\n", max_processors);
-
-       if (shared) {
-               entitled_capacity = HvLpConfig_getSharedProcUnits();
-               max_entitled_capacity = HvLpConfig_getMaxSharedProcUnits();
-       } else {
-               entitled_capacity = processors * 100;
-               max_entitled_capacity = max_processors * 100;
-       }
-       seq_printf(m, "partition_entitled_capacity=%d\n", entitled_capacity);
-
-       seq_printf(m, "partition_max_entitled_capacity=%d\n",
-                  max_entitled_capacity);
-
-       if (shared) {
-               pool_id = HvLpConfig_getSharedPoolIndex();
-               seq_printf(m, "pool=%d\n", (int)pool_id);
-               seq_printf(m, "pool_capacity=%d\n",
-                          (int)(HvLpConfig_getNumProcsInSharedPool(pool_id) *
-                                100));
-               seq_printf(m, "purr=%ld\n", purr);
-       }
-
-       seq_printf(m, "shared_processor_mode=%d\n", shared);
-
-       return 0;
-}
-#endif                         /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_PSERIES
-/* 
- * Methods used to fetch LPAR data when running on a pSeries platform.
- */
-
-/*
- * H_GET_PPP hcall returns info in 4 parms.
- *  entitled_capacity,unallocated_capacity,
- *  aggregation, resource_capability).
- *
- *  R4 = Entitled Processor Capacity Percentage. 
- *  R5 = Unallocated Processor Capacity Percentage.
- *  R6 (AABBCCDDEEFFGGHH).
- *      XXXX - reserved (0)
- *          XXXX - reserved (0)
- *              XXXX - Group Number
- *                  XXXX - Pool Number.
- *  R7 (IIJJKKLLMMNNOOPP).
- *      XX - reserved. (0)
- *        XX - bit 0-6 reserved (0).   bit 7 is Capped indicator.
- *          XX - variable processor Capacity Weight
- *            XX - Unallocated Variable Processor Capacity Weight.
- *              XXXX - Active processors in Physical Processor Pool.
- *                  XXXX  - Processors active on platform. 
- */
-static unsigned int h_get_ppp(unsigned long *entitled,
-                             unsigned long *unallocated,
-                             unsigned long *aggregation,
-                             unsigned long *resource)
-{
-       unsigned long rc;
-       rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated,
-                             aggregation, resource);
-
-       log_plpar_hcall_return(rc, "H_GET_PPP");
-
-       return rc;
-}
-
-static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
-{
-       unsigned long rc;
-       unsigned long dummy;
-       rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy);
-
-       log_plpar_hcall_return(rc, "H_PIC");
-}
-
-static unsigned long get_purr(void);
-
-/* Track sum of all purrs across all processors. This is used to further */
-/* calculate usage values by different applications                       */
-
-static unsigned long get_purr(void)
-{
-       unsigned long sum_purr = 0;
-       int cpu;
-       struct cpu_usage *cu;
-
-       for_each_cpu(cpu) {
-               cu = &per_cpu(cpu_usage_array, cpu);
-               sum_purr += cu->current_tb;
-       }
-       return sum_purr;
-}
-
-#define SPLPAR_CHARACTERISTICS_TOKEN 20
-#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
-
-/*
- * parse_system_parameter_string()
- * Retrieve the potential_processors, max_entitled_capacity and friends
- * through the get-system-parameter rtas call.  Replace keyword strings as
- * necessary.
- */
-static void parse_system_parameter_string(struct seq_file *m)
-{
-       int call_status;
-
-       char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
-       if (!local_buffer) {
-               printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
-                      __FILE__, __FUNCTION__, __LINE__);
-               return;
-       }
-
-       spin_lock(&rtas_data_buf_lock);
-       memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
-       call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-                               NULL,
-                               SPLPAR_CHARACTERISTICS_TOKEN,
-                               __pa(rtas_data_buf));
-       memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
-       spin_unlock(&rtas_data_buf_lock);
-
-       if (call_status != 0) {
-               printk(KERN_INFO
-                      "%s %s Error calling get-system-parameter (0x%x)\n",
-                      __FILE__, __FUNCTION__, call_status);
-       } else {
-               int splpar_strlen;
-               int idx, w_idx;
-               char *workbuffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
-               if (!workbuffer) {
-                       printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
-                              __FILE__, __FUNCTION__, __LINE__);
-                       kfree(local_buffer);                    
-                       return;
-               }
-#ifdef LPARCFG_DEBUG
-               printk(KERN_INFO "success calling get-system-parameter \n");
-#endif
-               splpar_strlen = local_buffer[0] * 16 + local_buffer[1];
-               local_buffer += 2;      /* step over strlen value */
-
-               memset(workbuffer, 0, SPLPAR_MAXLENGTH);
-               w_idx = 0;
-               idx = 0;
-               while ((*local_buffer) && (idx < splpar_strlen)) {
-                       workbuffer[w_idx++] = local_buffer[idx++];
-                       if ((local_buffer[idx] == ',')
-                           || (local_buffer[idx] == '\0')) {
-                               workbuffer[w_idx] = '\0';
-                               if (w_idx) {
-                                       /* avoid the empty string */
-                                       seq_printf(m, "%s\n", workbuffer);
-                               }
-                               memset(workbuffer, 0, SPLPAR_MAXLENGTH);
-                               idx++;  /* skip the comma */
-                               w_idx = 0;
-                       } else if (local_buffer[idx] == '=') {
-                               /* code here to replace workbuffer contents
-                                  with different keyword strings */
-                               if (0 == strcmp(workbuffer, "MaxEntCap")) {
-                                       strcpy(workbuffer,
-                                              "partition_max_entitled_capacity");
-                                       w_idx = strlen(workbuffer);
-                               }
-                               if (0 == strcmp(workbuffer, "MaxPlatProcs")) {
-                                       strcpy(workbuffer,
-                                              "system_potential_processors");
-                                       w_idx = strlen(workbuffer);
-                               }
-                       }
-               }
-               kfree(workbuffer);
-               local_buffer -= 2;      /* back up over strlen value */
-       }
-       kfree(local_buffer);
-}
-
-static int lparcfg_count_active_processors(void);
-
-/* Return the number of processors in the system.
- * This function reads through the device tree and counts
- * the virtual processors, this does not include threads.
- */
-static int lparcfg_count_active_processors(void)
-{
-       struct device_node *cpus_dn = NULL;
-       int count = 0;
-
-       while ((cpus_dn = of_find_node_by_type(cpus_dn, "cpu"))) {
-#ifdef LPARCFG_DEBUG
-               printk(KERN_ERR "cpus_dn %p \n", cpus_dn);
-#endif
-               count++;
-       }
-       return count;
-}
-
-static int lparcfg_data(struct seq_file *m, void *v)
-{
-       int partition_potential_processors;
-       int partition_active_processors;
-       struct device_node *rootdn;
-       const char *model = "";
-       const char *system_id = "";
-       unsigned int *lp_index_ptr, lp_index = 0;
-       struct device_node *rtas_node;
-       int *lrdrp;
-
-       rootdn = find_path_device("/");
-       if (rootdn) {
-               model = get_property(rootdn, "model", NULL);
-               system_id = get_property(rootdn, "system-id", NULL);
-               lp_index_ptr = (unsigned int *)
-                   get_property(rootdn, "ibm,partition-no", NULL);
-               if (lp_index_ptr)
-                       lp_index = *lp_index_ptr;
-       }
-
-       seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
-       seq_printf(m, "serial_number=%s\n", system_id);
-
-       seq_printf(m, "system_type=%s\n", model);
-
-       seq_printf(m, "partition_id=%d\n", (int)lp_index);
-
-       rtas_node = find_path_device("/rtas");
-       lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
-
-       if (lrdrp == NULL) {
-               partition_potential_processors = systemcfg->processorCount;
-       } else {
-               partition_potential_processors = *(lrdrp + 4);
-       }
-
-       partition_active_processors = lparcfg_count_active_processors();
-
-       if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
-               unsigned long h_entitled, h_unallocated;
-               unsigned long h_aggregation, h_resource;
-               unsigned long pool_idle_time, pool_procs;
-               unsigned long purr;
-
-               h_get_ppp(&h_entitled, &h_unallocated, &h_aggregation,
-                         &h_resource);
-
-               seq_printf(m, "R4=0x%lx\n", h_entitled);
-               seq_printf(m, "R5=0x%lx\n", h_unallocated);
-               seq_printf(m, "R6=0x%lx\n", h_aggregation);
-               seq_printf(m, "R7=0x%lx\n", h_resource);
-
-               purr = get_purr();
-
-               /* this call handles the ibm,get-system-parameter contents */
-               parse_system_parameter_string(m);
-
-               seq_printf(m, "partition_entitled_capacity=%ld\n", h_entitled);
-
-               seq_printf(m, "group=%ld\n", (h_aggregation >> 2 * 8) & 0xffff);
-
-               seq_printf(m, "system_active_processors=%ld\n",
-                          (h_resource >> 0 * 8) & 0xffff);
-
-               /* pool related entries are apropriate for shared configs */
-               if (paca[0].lppaca.shared_proc) {
-
-                       h_pic(&pool_idle_time, &pool_procs);
-
-                       seq_printf(m, "pool=%ld\n",
-                                  (h_aggregation >> 0 * 8) & 0xffff);
-
-                       /* report pool_capacity in percentage */
-                       seq_printf(m, "pool_capacity=%ld\n",
-                                  ((h_resource >> 2 * 8) & 0xffff) * 100);
-
-                       seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
-
-                       seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
-               }
-
-               seq_printf(m, "unallocated_capacity_weight=%ld\n",
-                          (h_resource >> 4 * 8) & 0xFF);
-
-               seq_printf(m, "capacity_weight=%ld\n",
-                          (h_resource >> 5 * 8) & 0xFF);
-
-               seq_printf(m, "capped=%ld\n", (h_resource >> 6 * 8) & 0x01);
-
-               seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated);
-
-               seq_printf(m, "purr=%ld\n", purr);
-
-       } else {                /* non SPLPAR case */
-
-               seq_printf(m, "system_active_processors=%d\n",
-                          partition_potential_processors);
-
-               seq_printf(m, "system_potential_processors=%d\n",
-                          partition_potential_processors);
-
-               seq_printf(m, "partition_max_entitled_capacity=%d\n",
-                          partition_potential_processors * 100);
-
-               seq_printf(m, "partition_entitled_capacity=%d\n",
-                          partition_active_processors * 100);
-       }
-
-       seq_printf(m, "partition_active_processors=%d\n",
-                  partition_active_processors);
-
-       seq_printf(m, "partition_potential_processors=%d\n",
-                  partition_potential_processors);
-
-       seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc);
-
-       return 0;
-}
-
-/*
- * Interface for changing system parameters (variable capacity weight
- * and entitled capacity).  Format of input is "param_name=value";
- * anything after value is ignored.  Valid parameters at this time are
- * "partition_entitled_capacity" and "capacity_weight".  We use
- * H_SET_PPP to alter parameters.
- *
- * This function should be invoked only on systems with
- * FW_FEATURE_SPLPAR.
- */
-static ssize_t lparcfg_write(struct file *file, const char __user * buf,
-                            size_t count, loff_t * off)
-{
-       char *kbuf;
-       char *tmp;
-       u64 new_entitled, *new_entitled_ptr = &new_entitled;
-       u8 new_weight, *new_weight_ptr = &new_weight;
-
-       unsigned long current_entitled; /* parameters for h_get_ppp */
-       unsigned long dummy;
-       unsigned long resource;
-       u8 current_weight;
-
-       ssize_t retval = -ENOMEM;
-
-       kbuf = kmalloc(count, GFP_KERNEL);
-       if (!kbuf)
-               goto out;
-
-       retval = -EFAULT;
-       if (copy_from_user(kbuf, buf, count))
-               goto out;
-
-       retval = -EINVAL;
-       kbuf[count - 1] = '\0';
-       tmp = strchr(kbuf, '=');
-       if (!tmp)
-               goto out;
-
-       *tmp++ = '\0';
-
-       if (!strcmp(kbuf, "partition_entitled_capacity")) {
-               char *endp;
-               *new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
-               if (endp == tmp)
-                       goto out;
-               new_weight_ptr = &current_weight;
-       } else if (!strcmp(kbuf, "capacity_weight")) {
-               char *endp;
-               *new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
-               if (endp == tmp)
-                       goto out;
-               new_entitled_ptr = &current_entitled;
-       } else
-               goto out;
-
-       /* Get our current parameters */
-       retval = h_get_ppp(&current_entitled, &dummy, &dummy, &resource);
-       if (retval) {
-               retval = -EIO;
-               goto out;
-       }
-
-       current_weight = (resource >> 5 * 8) & 0xFF;
-
-       pr_debug("%s: current_entitled = %lu, current_weight = %lu\n",
-                __FUNCTION__, current_entitled, current_weight);
-
-       pr_debug("%s: new_entitled = %lu, new_weight = %lu\n",
-                __FUNCTION__, *new_entitled_ptr, *new_weight_ptr);
-
-       retval = plpar_hcall_norets(H_SET_PPP, *new_entitled_ptr,
-                                   *new_weight_ptr);
-
-       if (retval == H_Success || retval == H_Constrained) {
-               retval = count;
-       } else if (retval == H_Busy) {
-               retval = -EBUSY;
-       } else if (retval == H_Hardware) {
-               retval = -EIO;
-       } else if (retval == H_Parameter) {
-               retval = -EINVAL;
-       } else {
-               printk(KERN_WARNING "%s: received unknown hv return code %ld",
-                      __FUNCTION__, retval);
-               retval = -EIO;
-       }
-
-      out:
-       kfree(kbuf);
-       return retval;
-}
-
-#endif                         /* CONFIG_PPC_PSERIES */
-
-static int lparcfg_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, lparcfg_data, NULL);
-}
-
-struct file_operations lparcfg_fops = {
-      .owner   = THIS_MODULE,
-      .read    = seq_read,
-      .open    = lparcfg_open,
-      .release = single_release,
-};
-
-int __init lparcfg_init(void)
-{
-       struct proc_dir_entry *ent;
-       mode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
-
-       /* Allow writing if we have FW_FEATURE_SPLPAR */
-       if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
-               lparcfg_fops.write = lparcfg_write;
-               mode |= S_IWUSR;
-       }
-
-       ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
-       if (ent) {
-               ent->proc_fops = &lparcfg_fops;
-               ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL);
-               if (!ent->data) {
-                       printk(KERN_ERR
-                              "Failed to allocate buffer for lparcfg\n");
-                       remove_proc_entry("lparcfg", ent->parent);
-                       return -ENOMEM;
-               }
-       } else {
-               printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
-               return -EIO;
-       }
-
-       proc_ppc64_lparcfg = ent;
-       return 0;
-}
-
-void __exit lparcfg_cleanup(void)
-{
-       if (proc_ppc64_lparcfg) {
-               kfree(proc_ppc64_lparcfg->data);
-               remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
-       }
-}
-
-module_init(lparcfg_init);
-module_exit(lparcfg_cleanup);
-MODULE_DESCRIPTION("Interface for LPAR configuration data");
-MODULE_AUTHOR("Dave Engebretsen");
-MODULE_LICENSE("GPL");
index 914632ec587d46fea767a47375160b1b0c2a2ab1..492bca6137ebc26fc8ec98870e8b5a50708bfddf 100644 (file)
@@ -78,12 +78,12 @@ _GLOBAL(call_do_softirq)
        mtlr    r0
        blr
 
-_GLOBAL(call_handle_IRQ_event)
+_GLOBAL(call___do_IRQ)
        mflr    r0
        std     r0,16(r1)
-       stdu    r1,THREAD_SIZE-112(r6)
-       mr      r1,r6
-       bl      .handle_IRQ_event
+       stdu    r1,THREAD_SIZE-112(r5)
+       mr      r1,r5
+       bl      .__do_IRQ
        ld      r1,0(r1)
        ld      r0,16(r1)
        mtlr    r0
index 4fb1a9f5060deb66b78867755ba31c320afd71b8..c0fcd29918cec0b3fea13b26177877807f076e24 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/rtas.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
-#include <asm/systemcfg.h>
 
 #undef DEBUG_NVRAM
 
@@ -167,7 +166,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
        case IOC_NVRAM_GET_OFFSET: {
                int part, offset;
 
-               if (systemcfg->platform != PLATFORM_POWERMAC)
+               if (_machine != PLATFORM_POWERMAC)
                        return -EINVAL;
                if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
                        return -EFAULT;
@@ -450,7 +449,7 @@ static int nvram_setup_partition(void)
         * in our nvram, as Apple defined partitions use pretty much
         * all of the space
         */
-       if (systemcfg->platform == PLATFORM_POWERMAC)
+       if (_machine == PLATFORM_POWERMAC)
                return -ENOSPC;
 
        /* see if we have an OS partition that meets our needs.
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
deleted file mode 100644 (file)
index 3133c72..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- *      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/config.h>
-#include <linux/types.h>
-#include <linux/threads.h>
-#include <linux/module.h>
-
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-
-#include <asm/lppaca.h>
-#include <asm/iseries/it_lp_queue.h>
-#include <asm/paca.h>
-
-static union {
-       struct systemcfg        data;
-       u8                      page[PAGE_SIZE];
-} systemcfg_store __attribute__((__section__(".data.page.aligned")));
-struct systemcfg *systemcfg = &systemcfg_store.data;
-EXPORT_SYMBOL(systemcfg);
-
-
-/* This symbol is provided by the linker - let it fill in the paca
- * field correctly */
-extern unsigned long __toc_start;
-
-/* The Paca is an array with one entry per processor.  Each contains an 
- * lppaca, which contains the information shared between the
- * hypervisor and Linux.  Each also contains an ItLpRegSave area which
- * is used by the hypervisor to save registers.
- * On systems with hardware multi-threading, there are two threads
- * per processor.  The Paca array must contain an entry for each thread.
- * The VPD Areas will give a max logical processors = 2 * max physical
- * processors.  The processor VPD array needs one entry per physical
- * processor (not thread).
- */
-#define PACA_INIT_COMMON(number, start, asrr, asrv)                        \
-       .lock_token = 0x8000,                                               \
-       .paca_index = (number),         /* Paca Index */                    \
-       .default_decr = 0x00ff0000,     /* Initial Decr */                  \
-       .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,             \
-       .stab_real = (asrr),            /* Real pointer to segment table */ \
-       .stab_addr = (asrv),            /* Virt pointer to segment table */ \
-       .cpu_start = (start),           /* Processor start */               \
-       .hw_cpu_id = 0xffff,                                                \
-       .lppaca = {                                                         \
-               .desc = 0xd397d781,     /* "LpPa" */                        \
-               .size = sizeof(struct lppaca),                              \
-               .dyn_proc_status = 2,                                       \
-               .decr_val = 0x00ff0000,                                     \
-               .fpregs_in_use = 1,                                         \
-               .end_of_quantum = 0xfffffffffffffffful,                     \
-               .slb_count = 64,                                            \
-               .vmxregs_in_use = 0,                                        \
-       },                                                                  \
-
-#ifdef CONFIG_PPC_ISERIES
-#define PACA_INIT_ISERIES(number)                                          \
-       .lppaca_ptr = &paca[number].lppaca,                                 \
-       .reg_save_ptr = &paca[number].reg_save,                             \
-       .reg_save = {                                                       \
-               .xDesc = 0xd397d9e2,    /* "LpRS" */                        \
-               .xSize = sizeof(struct ItLpRegSave)                         \
-       }
-
-#define PACA_INIT(number)                                                  \
-{                                                                          \
-       PACA_INIT_COMMON(number, 0, 0, 0)                                   \
-       PACA_INIT_ISERIES(number)                                           \
-}
-
-#define BOOTCPU_PACA_INIT(number)                                          \
-{                                                                          \
-       PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab)                  \
-       PACA_INIT_ISERIES(number)                                           \
-}
-
-#else
-#define PACA_INIT(number)                                                  \
-{                                                                          \
-       PACA_INIT_COMMON(number, 0, 0, 0)                                   \
-}
-
-#define BOOTCPU_PACA_INIT(number)                                          \
-{                                                                          \
-       PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab)    \
-}
-#endif
-
-struct paca_struct paca[] = {
-       BOOTCPU_PACA_INIT(0),
-#if NR_CPUS > 1
-       PACA_INIT(  1), PACA_INIT(  2), PACA_INIT(  3),
-#if NR_CPUS > 4
-       PACA_INIT(  4), PACA_INIT(  5), PACA_INIT(  6), PACA_INIT(  7),
-#if NR_CPUS > 8
-       PACA_INIT(  8), PACA_INIT(  9), PACA_INIT( 10), PACA_INIT( 11),
-       PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15),
-       PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19),
-       PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23),
-       PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27),
-       PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31),
-#if NR_CPUS > 32
-       PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35),
-       PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39),
-       PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43),
-       PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47),
-       PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51),
-       PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55),
-       PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59),
-       PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63),
-#if NR_CPUS > 64
-       PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67),
-       PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71),
-       PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75),
-       PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79),
-       PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83),
-       PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87),
-       PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91),
-       PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95),
-       PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99),
-       PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103),
-       PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107),
-       PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111),
-       PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115),
-       PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119),
-       PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123),
-       PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127),
-#endif
-#endif
-#endif
-#endif
-#endif
-};
-EXPORT_SYMBOL(paca);
index 30247ff74972d3ef3a4048b3baca0d24141e5420..3cef1b8f57f01a4d70ff2f376a4cda1289bea7fa 100644 (file)
@@ -548,6 +548,11 @@ static int __init pcibios_init(void)
        if (ppc64_isabridge_dev != NULL)
                printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
+       /* map in PCI I/O space */
+       phbs_remap_io();
+#endif
+
        printk("PCI: Probing PCI hardware done\n");
 
        return 0;
@@ -1277,12 +1282,9 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
         * G5 machines... So when something asks for bus 0 io base
         * (bus 0 is HT root), we return the AGP one instead.
         */
-#ifdef CONFIG_PPC_PMAC
-       if (systemcfg->platform == PLATFORM_POWERMAC &&
-           machine_is_compatible("MacRISC4"))
+       if (machine_is_compatible("MacRISC4"))
                if (in_bus == 0)
                        in_bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
 
        /* That syscall isn't quite compatible with PCI domains, but it's
         * used on pre-domains setup. We return the first match
index 1a443a7ada4c868030d0cb4d2e0e14e1df28c257..12c4c9e9bbc7bc3bb9165d3d8b055d1538cff5e6 100644 (file)
@@ -43,7 +43,7 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
        u32 *regs;
        struct pci_dn *pdn;
 
-       if (phb->is_dynamic)
+       if (mem_init_done)
                pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
        else
                pdn = alloc_bootmem(sizeof(*pdn));
@@ -120,6 +120,14 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
        return NULL;
 }
 
+/** 
+ * pci_devs_phb_init_dynamic - setup pci devices under this PHB
+ * phb: pci-to-host bridge (top-level bridge connecting to cpu)
+ *
+ * This routine is called both during boot, (before the memory
+ * subsystem is set up, before kmalloc is valid) and during the 
+ * dynamic lpar operation of adding a PHB to a running system.
+ */
 void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
 {
        struct device_node * dn = (struct device_node *) phb->arch_data;
@@ -201,9 +209,14 @@ static struct notifier_block pci_dn_reconfig_nb = {
        .notifier_call = pci_dn_reconfig_notifier,
 };
 
-/*
- * Actually initialize the phbs.
- * The buswalk on this phb has not happened yet.
+/** 
+ * pci_devs_phb_init - Initialize phbs and pci devs under them.
+ * 
+ * This routine walks over all phb's (pci-host bridges) on the
+ * system, and sets up assorted pci-related structures 
+ * (including pci info in the device node structs) for each
+ * pci device found underneath.  This routine runs once,
+ * early in the boot sequence.
  */
 void __init pci_devs_phb_init(void)
 {
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
deleted file mode 100644 (file)
index 24e955e..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * arch/ppc64/kernel/proc_ppc64.c
- *
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include <asm/systemcfg.h>
-#include <asm/rtas.h>
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-
-static loff_t  page_map_seek( struct file *file, loff_t off, int whence);
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-                             loff_t *ppos);
-static int     page_map_mmap( struct file *file, struct vm_area_struct *vma );
-
-static struct file_operations page_map_fops = {
-       .llseek = page_map_seek,
-       .read   = page_map_read,
-       .mmap   = page_map_mmap
-};
-
-/*
- * Create the ppc64 and ppc64/rtas directories early. This allows us to
- * assume that they have been previously created in drivers.
- */
-static int __init proc_ppc64_create(void)
-{
-       struct proc_dir_entry *root;
-
-       root = proc_mkdir("ppc64", NULL);
-       if (!root)
-               return 1;
-
-       if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_CELL)))
-               return 0;
-
-       if (!proc_mkdir("rtas", root))
-               return 1;
-
-       if (!proc_symlink("rtas", NULL, "ppc64/rtas"))
-               return 1;
-
-       return 0;
-}
-core_initcall(proc_ppc64_create);
-
-static int __init proc_ppc64_init(void)
-{
-       struct proc_dir_entry *pde;
-
-       pde = create_proc_entry("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL);
-       if (!pde)
-               return 1;
-       pde->nlink = 1;
-       pde->data = systemcfg;
-       pde->size = PAGE_SIZE;
-       pde->proc_fops = &page_map_fops;
-
-       return 0;
-}
-__initcall(proc_ppc64_init);
-
-static loff_t page_map_seek( struct file *file, loff_t off, int whence)
-{
-       loff_t new;
-       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
-
-       switch(whence) {
-       case 0:
-               new = off;
-               break;
-       case 1:
-               new = file->f_pos + off;
-               break;
-       case 2:
-               new = dp->size + off;
-               break;
-       default:
-               return -EINVAL;
-       }
-       if ( new < 0 || new > dp->size )
-               return -EINVAL;
-       return (file->f_pos = new);
-}
-
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-                             loff_t *ppos)
-{
-       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
-       return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
-}
-
-static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
-{
-       struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
-
-       vma->vm_flags |= VM_SHM | VM_LOCKED;
-
-       if ((vma->vm_end - vma->vm_start) > dp->size)
-               return -EINVAL;
-
-       remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
-                                               dp->size, vma->vm_page_prot);
-       return 0;
-}
-
index 3402fbee62c74af1faf5ccd7013afc4199c4ce2b..fbad2c360784edaa0d181812fdf0f8af39730c7e 100644 (file)
@@ -318,7 +318,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
                }
 
                /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
-               if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
+               if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
                        char *name = get_property(ic->parent, "name", NULL);
                        if (name && !strcmp(name, "u3"))
                                np->intrs[intrcount].line += 128;
@@ -1065,7 +1065,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
        prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
        if (prop == NULL)
                return 0;
-       systemcfg->platform = *prop;
+       _machine = *prop;
 
        /* check if iommu is forced on or off */
        if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -1230,11 +1230,8 @@ void __init early_init_devtree(void *params)
        of_scan_flat_dt(early_init_dt_scan_memory, NULL);
        lmb_enforce_memory_limit(memory_limit);
        lmb_analyze();
-       systemcfg->physicalMemorySize = lmb_phys_mem_size();
        lmb_reserve(0, __pa(klimit));
 
-       DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
-
        /* Reserve LMB regions used by kernel, initrd, dt, etc... */
        early_reserve_mem();
 
@@ -1753,7 +1750,7 @@ static int of_finish_dynamic_node(struct device_node *node,
        /* We don't support that function on PowerMac, at least
         * not yet
         */
-       if (systemcfg->platform == PLATFORM_POWERMAC)
+       if (_machine == PLATFORM_POWERMAC)
                return -ENODEV;
 
        /* fix up new node's linux_phandle field */
index e4c880dab997bf9cc7baeb33efe3cd54bcca22fc..6375f40b23db8176b601b1ddb28f14993e6b5737 100644 (file)
@@ -1934,7 +1934,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
        /*
         * On pSeries, inform the firmware about our capabilities
         */
-       if (RELOC(of_platform) & PLATFORM_PSERIES)
+       if (RELOC(of_platform) == PLATFORM_PSERIES ||
+           RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
                prom_send_capabilities();
 
        /*
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
deleted file mode 100644 (file)
index 3c3f191..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * arch/ppc64/kernel/rtas_pci.c
- *
- * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
- * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * RTAS specific routines for PCI.
- * 
- * Based on code from pci.c, chrp_pci.c and pSeries_pci.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.
- *    
- * 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/kernel.h>
-#include <linux/threads.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/rtas.h>
-#include <asm/mpic.h>
-#include <asm/ppc-pci.h>
-
-/* RTAS tokens */
-static int read_pci_config;
-static int write_pci_config;
-static int ibm_read_pci_config;
-static int ibm_write_pci_config;
-
-static int config_access_valid(struct pci_dn *dn, int where)
-{
-       if (where < 256)
-               return 1;
-       if (where < 4096 && dn->pci_ext_config_space)
-               return 1;
-
-       return 0;
-}
-
-static int of_device_available(struct device_node * dn)
-{
-        char * status;
-
-        status = get_property(dn, "status", NULL);
-
-        if (!status)
-                return 1;
-
-        if (!strcmp(status, "okay"))
-                return 1;
-
-        return 0;
-}
-
-static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
-{
-       int returnval = -1;
-       unsigned long buid, addr;
-       int ret;
-       struct pci_dn *pdn;
-
-       if (!dn || !dn->data)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       pdn = dn->data;
-       if (!config_access_valid(pdn, where))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-
-       addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
-               (pdn->devfn << 8) | (where & 0xff);
-       buid = pdn->phb->buid;
-       if (buid) {
-               ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
-                               addr, buid >> 32, buid & 0xffffffff, size);
-       } else {
-               ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
-       }
-       *val = returnval;
-
-       if (ret)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       if (returnval == EEH_IO_ERROR_VALUE(size) &&
-           eeh_dn_check_failure (dn, NULL))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int rtas_pci_read_config(struct pci_bus *bus,
-                               unsigned int devfn,
-                               int where, int size, u32 *val)
-{
-       struct device_node *busdn, *dn;
-
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-
-       /* Search only direct children of the bus */
-       for (dn = busdn->child; dn; dn = dn->sibling)
-               if (dn->data && PCI_DN(dn)->devfn == devfn
-                   && of_device_available(dn))
-                       return rtas_read_config(dn, where, size, val);
-
-       return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
-{
-       unsigned long buid, addr;
-       int ret;
-       struct pci_dn *pdn;
-
-       if (!dn || !dn->data)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       pdn = dn->data;
-       if (!config_access_valid(pdn, where))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-
-       addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
-               (pdn->devfn << 8) | (where & 0xff);
-       buid = pdn->phb->buid;
-       if (buid) {
-               ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
-       } else {
-               ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
-       }
-
-       if (ret)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int rtas_pci_write_config(struct pci_bus *bus,
-                                unsigned int devfn,
-                                int where, int size, u32 val)
-{
-       struct device_node *busdn, *dn;
-
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-
-       /* Search only direct children of the bus */
-       for (dn = busdn->child; dn; dn = dn->sibling)
-               if (dn->data && PCI_DN(dn)->devfn == devfn
-                   && of_device_available(dn))
-                       return rtas_write_config(dn, where, size, val);
-       return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-struct pci_ops rtas_pci_ops = {
-       rtas_pci_read_config,
-       rtas_pci_write_config
-};
-
-int is_python(struct device_node *dev)
-{
-       char *model = (char *)get_property(dev, "model", NULL);
-
-       if (model && strstr(model, "Python"))
-               return 1;
-
-       return 0;
-}
-
-static int get_phb_reg_prop(struct device_node *dev,
-                           unsigned int addr_size_words,
-                           struct reg_property64 *reg)
-{
-       unsigned int *ui_ptr = NULL, len;
-
-       /* Found a PHB, now figure out where his registers are mapped. */
-       ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
-       if (ui_ptr == NULL)
-               return 1;
-
-       if (addr_size_words == 1) {
-               reg->address = ((struct reg_property32 *)ui_ptr)->address;
-               reg->size    = ((struct reg_property32 *)ui_ptr)->size;
-       } else {
-               *reg = *((struct reg_property64 *)ui_ptr);
-       }
-
-       return 0;
-}
-
-static void python_countermeasures(struct device_node *dev,
-                                  unsigned int addr_size_words)
-{
-       struct reg_property64 reg_struct;
-       void __iomem *chip_regs;
-       volatile u32 val;
-
-       if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
-               return;
-
-       /* Python's register file is 1 MB in size. */
-       chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
-
-       /* 
-        * Firmware doesn't always clear this bit which is critical
-        * for good performance - Anton
-        */
-
-#define PRG_CL_RESET_VALID 0x00010000
-
-       val = in_be32(chip_regs + 0xf6030);
-       if (val & PRG_CL_RESET_VALID) {
-               printk(KERN_INFO "Python workaround: ");
-               val &= ~PRG_CL_RESET_VALID;
-               out_be32(chip_regs + 0xf6030, val);
-               /*
-                * We must read it back for changes to
-                * take effect
-                */
-               val = in_be32(chip_regs + 0xf6030);
-               printk("reg0: %x\n", val);
-       }
-
-       iounmap(chip_regs);
-}
-
-void __init init_pci_config_tokens (void)
-{
-       read_pci_config = rtas_token("read-pci-config");
-       write_pci_config = rtas_token("write-pci-config");
-       ibm_read_pci_config = rtas_token("ibm,read-pci-config");
-       ibm_write_pci_config = rtas_token("ibm,write-pci-config");
-}
-
-unsigned long __devinit get_phb_buid (struct device_node *phb)
-{
-       int addr_cells;
-       unsigned int *buid_vals;
-       unsigned int len;
-       unsigned long buid;
-
-       if (ibm_read_pci_config == -1) return 0;
-
-       /* PHB's will always be children of the root node,
-        * or so it is promised by the current firmware. */
-       if (phb->parent == NULL)
-               return 0;
-       if (phb->parent->parent)
-               return 0;
-
-       buid_vals = (unsigned int *) get_property(phb, "reg", &len);
-       if (buid_vals == NULL)
-               return 0;
-
-       addr_cells = prom_n_addr_cells(phb);
-       if (addr_cells == 1) {
-               buid = (unsigned long) buid_vals[0];
-       } else {
-               buid = (((unsigned long)buid_vals[0]) << 32UL) |
-                       (((unsigned long)buid_vals[1]) & 0xffffffff);
-       }
-       return buid;
-}
-
-static int phb_set_bus_ranges(struct device_node *dev,
-                             struct pci_controller *phb)
-{
-       int *bus_range;
-       unsigned int len;
-
-       bus_range = (int *) get_property(dev, "bus-range", &len);
-       if (bus_range == NULL || len < 2 * sizeof(int)) {
-               return 1;
-       }
-       phb->first_busno =  bus_range[0];
-       phb->last_busno  =  bus_range[1];
-
-       return 0;
-}
-
-static int __devinit setup_phb(struct device_node *dev,
-                              struct pci_controller *phb,
-                              unsigned int addr_size_words)
-{
-       pci_setup_pci_controller(phb);
-
-       if (is_python(dev))
-               python_countermeasures(dev, addr_size_words);
-
-       if (phb_set_bus_ranges(dev, phb))
-               return 1;
-
-       phb->arch_data = dev;
-       phb->ops = &rtas_pci_ops;
-       phb->buid = get_phb_buid(dev);
-
-       return 0;
-}
-
-static void __devinit add_linux_pci_domain(struct device_node *dev,
-                                          struct pci_controller *phb,
-                                          struct property *of_prop)
-{
-       memset(of_prop, 0, sizeof(struct property));
-       of_prop->name = "linux,pci-domain";
-       of_prop->length = sizeof(phb->global_number);
-       of_prop->value = (unsigned char *)&of_prop[1];
-       memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
-       prom_add_property(dev, of_prop);
-}
-
-static struct pci_controller * __init alloc_phb(struct device_node *dev,
-                                               unsigned int addr_size_words)
-{
-       struct pci_controller *phb;
-       struct property *of_prop;
-
-       phb = alloc_bootmem(sizeof(struct pci_controller));
-       if (phb == NULL)
-               return NULL;
-
-       of_prop = alloc_bootmem(sizeof(struct property) +
-                               sizeof(phb->global_number));
-       if (!of_prop)
-               return NULL;
-
-       if (setup_phb(dev, phb, addr_size_words))
-               return NULL;
-
-       add_linux_pci_domain(dev, phb, of_prop);
-
-       return phb;
-}
-
-static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
-{
-       struct pci_controller *phb;
-
-       phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
-                                              GFP_KERNEL);
-       if (phb == NULL)
-               return NULL;
-
-       if (setup_phb(dev, phb, addr_size_words))
-               return NULL;
-
-       phb->is_dynamic = 1;
-
-       /* TODO: linux,pci-domain? */
-
-       return phb;
-}
-
-unsigned long __init find_and_init_phbs(void)
-{
-       struct device_node *node;
-       struct pci_controller *phb;
-       unsigned int root_size_cells = 0;
-       unsigned int index;
-       unsigned int *opprop = NULL;
-       struct device_node *root = of_find_node_by_path("/");
-
-       if (ppc64_interrupt_controller == IC_OPEN_PIC) {
-               opprop = (unsigned int *)get_property(root,
-                               "platform-open-pic", NULL);
-       }
-
-       root_size_cells = prom_n_size_cells(root);
-
-       index = 0;
-
-       for (node = of_get_next_child(root, NULL);
-            node != NULL;
-            node = of_get_next_child(root, node)) {
-               if (node->type == NULL || strcmp(node->type, "pci") != 0)
-                       continue;
-
-               phb = alloc_phb(node, root_size_cells);
-               if (!phb)
-                       continue;
-
-               pci_process_bridge_OF_ranges(phb, node, 0);
-               pci_setup_phb_io(phb, index == 0);
-#ifdef CONFIG_PPC_PSERIES
-               if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
-                       int addr = root_size_cells * (index + 2) - 1;
-                       mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
-               }
-#endif
-               index++;
-       }
-
-       of_node_put(root);
-       pci_devs_phb_init();
-
-       /*
-        * pci_probe_only and pci_assign_all_buses can be set via properties
-        * in chosen.
-        */
-       if (of_chosen) {
-               int *prop;
-
-               prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
-                                          NULL);
-               if (prop)
-                       pci_probe_only = *prop;
-
-               prop = (int *)get_property(of_chosen,
-                                          "linux,pci-assign-all-buses", NULL);
-               if (prop)
-                       pci_assign_all_buses = *prop;
-       }
-
-       return 0;
-}
-
-struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
-{
-       struct device_node *root = of_find_node_by_path("/");
-       unsigned int root_size_cells = 0;
-       struct pci_controller *phb;
-       int primary;
-
-       root_size_cells = prom_n_size_cells(root);
-
-       primary = list_empty(&hose_list);
-       phb = alloc_phb_dynamic(dn, root_size_cells);
-       if (!phb)
-               return NULL;
-
-       pci_process_bridge_OF_ranges(phb, dn, primary);
-
-       pci_setup_phb_io_dynamic(phb, primary);
-       of_node_put(root);
-
-       pci_devs_phb_init_dynamic(phb);
-       scan_phb(phb);
-
-       return phb;
-}
-EXPORT_SYMBOL(init_phb_dynamic);
-
-/* RPA-specific bits for removing PHBs */
-int pcibios_remove_root_bus(struct pci_controller *phb)
-{
-       struct pci_bus *b = phb->bus;
-       struct resource *res;
-       int rc, i;
-
-       res = b->resource[0];
-       if (!res->flags) {
-               printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
-                               b->name);
-               return 1;
-       }
-
-       rc = unmap_bus_range(b);
-       if (rc) {
-               printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
-                       __FUNCTION__, b->name);
-               return 1;
-       }
-
-       if (release_resource(res)) {
-               printk(KERN_ERR "%s: failed to release IO on bus %s\n",
-                               __FUNCTION__, b->name);
-               return 1;
-       }
-
-       for (i = 1; i < 3; ++i) {
-               res = b->resource[i];
-               if (!res->flags && i == 0) {
-                       printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
-                               __FUNCTION__, b->name);
-                       return 1;
-               }
-               if (res->flags && release_resource(res)) {
-                       printk(KERN_ERR
-                              "%s: failed to release IO %d on bus %s\n",
-                               __FUNCTION__, i, b->name);
-                       return 1;
-               }
-       }
-
-       list_del(&phb->list_node);
-       if (phb->is_dynamic)
-               kfree(phb);
-
-       return 0;
-}
-EXPORT_SYMBOL(pcibios_remove_root_bus);
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c
deleted file mode 100644 (file)
index 2edc947..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *  c 2001 PPC 64 Team, IBM Corp
- *
- *      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.
- *
- * scan-log-data driver for PPC64  Todd Inglett <tinglett@vnet.ibm.com>
- *
- * When ppc64 hardware fails the service processor dumps internal state
- * of the system.  After a reboot the operating system can access a dump
- * of this data using this driver.  A dump exists if the device-tree
- * /chosen/ibm,scan-log-data property exists.
- *
- * This driver exports /proc/ppc64/scan-log-dump which can be read.
- * The driver supports only sequential reads.
- *
- * The driver looks at a write to the driver for the single word "reset".
- * If given, the driver will reset the scanlog so the platform can free it.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <asm/rtas.h>
-#include <asm/prom.h>
-
-#define MODULE_VERS "1.0"
-#define MODULE_NAME "scanlog"
-
-/* Status returns from ibm,scan-log-dump */
-#define SCANLOG_COMPLETE 0
-#define SCANLOG_HWERROR -1
-#define SCANLOG_CONTINUE 1
-
-#define DEBUG(A...) do { if (scanlog_debug) printk(KERN_ERR "scanlog: " A); } while (0)
-
-static int scanlog_debug;
-static unsigned int ibm_scan_log_dump;                 /* RTAS token */
-static struct proc_dir_entry *proc_ppc64_scan_log_dump;        /* The proc file */
-
-static ssize_t scanlog_read(struct file *file, char __user *buf,
-                           size_t count, loff_t *ppos)
-{
-        struct inode * inode = file->f_dentry->d_inode;
-       struct proc_dir_entry *dp;
-       unsigned int *data;
-       int status;
-       unsigned long len, off;
-       unsigned int wait_time;
-
-        dp = PDE(inode);
-       data = (unsigned int *)dp->data;
-
-       if (!data) {
-               printk(KERN_ERR "scanlog: read failed no data\n");
-               return -EIO;
-       }
-
-       if (count > RTAS_DATA_BUF_SIZE)
-               count = RTAS_DATA_BUF_SIZE;
-
-       if (count < 1024) {
-               /* This is the min supported by this RTAS call.  Rather
-                * than do all the buffering we insist the user code handle
-                * larger reads.  As long as cp works... :)
-                */
-               printk(KERN_ERR "scanlog: cannot perform a small read (%ld)\n", count);
-               return -EINVAL;
-       }
-
-       if (!access_ok(VERIFY_WRITE, buf, count))
-               return -EFAULT;
-
-       for (;;) {
-               wait_time = 500;        /* default wait if no data */
-               spin_lock(&rtas_data_buf_lock);
-               memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE);
-               status = rtas_call(ibm_scan_log_dump, 2, 1, NULL,
-                                  (u32) __pa(rtas_data_buf), (u32) count);
-               memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE);
-               spin_unlock(&rtas_data_buf_lock);
-
-               DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n",
-                     status, data[0], data[1], data[2]);
-               switch (status) {
-                   case SCANLOG_COMPLETE:
-                       DEBUG("hit eof\n");
-                       return 0;
-                   case SCANLOG_HWERROR:
-                       DEBUG("hardware error reading scan log data\n");
-                       return -EIO;
-                   case SCANLOG_CONTINUE:
-                       /* We may or may not have data yet */
-                       len = data[1];
-                       off = data[2];
-                       if (len > 0) {
-                               if (copy_to_user(buf, ((char *)data)+off, len))
-                                       return -EFAULT;
-                               return len;
-                       }
-                       /* Break to sleep default time */
-                       break;
-                   default:
-                       if (status > 9900 && status <= 9905) {
-                               wait_time = rtas_extended_busy_delay_time(status);
-                       } else {
-                               printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status);
-                               return -EIO;
-                       }
-               }
-               /* Apparently no data yet.  Wait and try again. */
-               msleep_interruptible(wait_time);
-       }
-       /*NOTREACHED*/
-}
-
-static ssize_t scanlog_write(struct file * file, const char __user * buf,
-                            size_t count, loff_t *ppos)
-{
-       char stkbuf[20];
-       int status;
-
-       if (count > 19) count = 19;
-       if (copy_from_user (stkbuf, buf, count)) {
-               return -EFAULT;
-       }
-       stkbuf[count] = 0;
-
-       if (buf) {
-               if (strncmp(stkbuf, "reset", 5) == 0) {
-                       DEBUG("reset scanlog\n");
-                       status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0);
-                       DEBUG("rtas returns %d\n", status);
-               } else if (strncmp(stkbuf, "debugon", 7) == 0) {
-                       printk(KERN_ERR "scanlog: debug on\n");
-                       scanlog_debug = 1;
-               } else if (strncmp(stkbuf, "debugoff", 8) == 0) {
-                       printk(KERN_ERR "scanlog: debug off\n");
-                       scanlog_debug = 0;
-               }
-       }
-       return count;
-}
-
-static int scanlog_open(struct inode * inode, struct file * file)
-{
-       struct proc_dir_entry *dp = PDE(inode);
-       unsigned int *data = (unsigned int *)dp->data;
-
-       if (!data) {
-               printk(KERN_ERR "scanlog: open failed no data\n");
-               return -EIO;
-       }
-
-       if (data[0] != 0) {
-               /* This imperfect test stops a second copy of the
-                * data (or a reset while data is being copied)
-                */
-               return -EBUSY;
-       }
-
-       data[0] = 0;    /* re-init so we restart the scan */
-
-       return 0;
-}
-
-static int scanlog_release(struct inode * inode, struct file * file)
-{
-       struct proc_dir_entry *dp = PDE(inode);
-       unsigned int *data = (unsigned int *)dp->data;
-
-       if (!data) {
-               printk(KERN_ERR "scanlog: release failed no data\n");
-               return -EIO;
-       }
-       data[0] = 0;
-
-       return 0;
-}
-
-struct file_operations scanlog_fops = {
-       .owner          = THIS_MODULE,
-       .read           = scanlog_read,
-       .write          = scanlog_write,
-       .open           = scanlog_open,
-       .release        = scanlog_release,
-};
-
-int __init scanlog_init(void)
-{
-       struct proc_dir_entry *ent;
-
-       ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
-       if (ibm_scan_log_dump == RTAS_UNKNOWN_SERVICE) {
-               printk(KERN_ERR "scan-log-dump not implemented on this system\n");
-               return -EIO;
-       }
-
-        ent = create_proc_entry("ppc64/rtas/scan-log-dump",  S_IRUSR, NULL);
-       if (ent) {
-               ent->proc_fops = &scanlog_fops;
-               /* Ideally we could allocate a buffer < 4G */
-               ent->data = kmalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
-               if (!ent->data) {
-                       printk(KERN_ERR "Failed to allocate a buffer\n");
-                       remove_proc_entry("scan-log-dump", ent->parent);
-                       return -ENOMEM;
-               }
-               ((unsigned int *)ent->data)[0] = 0;
-       } else {
-               printk(KERN_ERR "Failed to create ppc64/scan-log-dump proc entry\n");
-               return -EIO;
-       }
-       proc_ppc64_scan_log_dump = ent;
-
-       return 0;
-}
-
-void __exit scanlog_cleanup(void)
-{
-       if (proc_ppc64_scan_log_dump) {
-               kfree(proc_ppc64_scan_log_dump->data);
-               remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
-       }
-}
-
-module_init(scanlog_init);
-module_exit(scanlog_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
deleted file mode 100644 (file)
index e99ec62..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-#include <linux/config.h>
-#include <linux/sysdev.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/percpu.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/nodemask.h>
-#include <linux/cpumask.h>
-#include <linux/notifier.h>
-
-#include <asm/current.h>
-#include <asm/processor.h>
-#include <asm/cputable.h>
-#include <asm/firmware.h>
-#include <asm/hvcall.h>
-#include <asm/prom.h>
-#include <asm/systemcfg.h>
-#include <asm/paca.h>
-#include <asm/lppaca.h>
-#include <asm/machdep.h>
-#include <asm/smp.h>
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-/* SMT stuff */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-/* default to snooze disabled */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
-
-static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
-                                     size_t count)
-{
-       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
-       ssize_t ret;
-       unsigned long snooze;
-
-       ret = sscanf(buf, "%lu", &snooze);
-       if (ret != 1)
-               return -EINVAL;
-
-       per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze;
-
-       return count;
-}
-
-static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf)
-{
-       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
-
-       return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id));
-}
-
-static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
-                  store_smt_snooze_delay);
-
-/* Only parse OF options if the matching cmdline option was not specified */
-static int smt_snooze_cmdline;
-
-static int __init smt_setup(void)
-{
-       struct device_node *options;
-       unsigned int *val;
-       unsigned int cpu;
-
-       if (!cpu_has_feature(CPU_FTR_SMT))
-               return 1;
-
-       options = find_path_device("/options");
-       if (!options)
-               return 1;
-
-       val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
-                                          NULL);
-       if (!smt_snooze_cmdline && val) {
-               for_each_cpu(cpu)
-                       per_cpu(smt_snooze_delay, cpu) = *val;
-       }
-
-       return 1;
-}
-__initcall(smt_setup);
-
-static int __init setup_smt_snooze_delay(char *str)
-{
-       unsigned int cpu;
-       int snooze;
-
-       if (!cpu_has_feature(CPU_FTR_SMT))
-               return 1;
-
-       smt_snooze_cmdline = 1;
-
-       if (get_option(&str, &snooze)) {
-               for_each_cpu(cpu)
-                       per_cpu(smt_snooze_delay, cpu) = snooze;
-       }
-
-       return 1;
-}
-__setup("smt-snooze-delay=", setup_smt_snooze_delay);
-
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-/*
- * Enabling PMCs will slow partition context switch times so we only do
- * it the first time we write to the PMCs.
- */
-
-static DEFINE_PER_CPU(char, pmcs_enabled);
-
-void ppc64_enable_pmcs(void)
-{
-       /* Only need to enable them once */
-       if (__get_cpu_var(pmcs_enabled))
-               return;
-
-       __get_cpu_var(pmcs_enabled) = 1;
-
-       if (ppc_md.enable_pmcs)
-               ppc_md.enable_pmcs();
-}
-EXPORT_SYMBOL(ppc64_enable_pmcs);
-
-/* XXX convert to rusty's on_one_cpu */
-static unsigned long run_on_cpu(unsigned long cpu,
-                               unsigned long (*func)(unsigned long),
-                               unsigned long arg)
-{
-       cpumask_t old_affinity = current->cpus_allowed;
-       unsigned long ret;
-
-       /* should return -EINVAL to userspace */
-       if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
-               return 0;
-
-       ret = func(arg);
-
-       set_cpus_allowed(current, old_affinity);
-
-       return ret;
-}
-
-#define SYSFS_PMCSETUP(NAME, ADDRESS) \
-static unsigned long read_##NAME(unsigned long junk) \
-{ \
-       return mfspr(ADDRESS); \
-} \
-static unsigned long write_##NAME(unsigned long val) \
-{ \
-       ppc64_enable_pmcs(); \
-       mtspr(ADDRESS, val); \
-       return 0; \
-} \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
-{ \
-       struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
-       unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
-       return sprintf(buf, "%lx\n", val); \
-} \
-static ssize_t __attribute_used__ \
-       store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
-{ \
-       struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
-       unsigned long val; \
-       int ret = sscanf(buf, "%lx", &val); \
-       if (ret != 1) \
-               return -EINVAL; \
-       run_on_cpu(cpu->sysdev.id, write_##NAME, val); \
-       return count; \
-}
-
-SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0);
-SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1);
-SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
-SYSFS_PMCSETUP(pmc1, SPRN_PMC1);
-SYSFS_PMCSETUP(pmc2, SPRN_PMC2);
-SYSFS_PMCSETUP(pmc3, SPRN_PMC3);
-SYSFS_PMCSETUP(pmc4, SPRN_PMC4);
-SYSFS_PMCSETUP(pmc5, SPRN_PMC5);
-SYSFS_PMCSETUP(pmc6, SPRN_PMC6);
-SYSFS_PMCSETUP(pmc7, SPRN_PMC7);
-SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
-SYSFS_PMCSETUP(purr, SPRN_PURR);
-
-static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0);
-static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1);
-static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
-static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1);
-static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2);
-static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3);
-static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4);
-static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5);
-static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6);
-static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7);
-static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8);
-static SYSDEV_ATTR(purr, 0600, show_purr, NULL);
-
-static void register_cpu_online(unsigned int cpu)
-{
-       struct cpu *c = &per_cpu(cpu_devices, cpu);
-       struct sys_device *s = &c->sysdev;
-
-#ifndef CONFIG_PPC_ISERIES
-       if (cpu_has_feature(CPU_FTR_SMT))
-               sysdev_create_file(s, &attr_smt_snooze_delay);
-#endif
-
-       /* PMC stuff */
-
-       sysdev_create_file(s, &attr_mmcr0);
-       sysdev_create_file(s, &attr_mmcr1);
-
-       if (cpu_has_feature(CPU_FTR_MMCRA))
-               sysdev_create_file(s, &attr_mmcra);
-
-       if (cur_cpu_spec->num_pmcs >= 1)
-               sysdev_create_file(s, &attr_pmc1);
-       if (cur_cpu_spec->num_pmcs >= 2)
-               sysdev_create_file(s, &attr_pmc2);
-       if (cur_cpu_spec->num_pmcs >= 3)
-               sysdev_create_file(s, &attr_pmc3);
-       if (cur_cpu_spec->num_pmcs >= 4)
-               sysdev_create_file(s, &attr_pmc4);
-       if (cur_cpu_spec->num_pmcs >= 5)
-               sysdev_create_file(s, &attr_pmc5);
-       if (cur_cpu_spec->num_pmcs >= 6)
-               sysdev_create_file(s, &attr_pmc6);
-       if (cur_cpu_spec->num_pmcs >= 7)
-               sysdev_create_file(s, &attr_pmc7);
-       if (cur_cpu_spec->num_pmcs >= 8)
-               sysdev_create_file(s, &attr_pmc8);
-  
-       if (cpu_has_feature(CPU_FTR_SMT))
-               sysdev_create_file(s, &attr_purr);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void unregister_cpu_online(unsigned int cpu)
-{
-       struct cpu *c = &per_cpu(cpu_devices, cpu);
-       struct sys_device *s = &c->sysdev;
-
-       BUG_ON(c->no_control);
-
-#ifndef CONFIG_PPC_ISERIES
-       if (cpu_has_feature(CPU_FTR_SMT))
-               sysdev_remove_file(s, &attr_smt_snooze_delay);
-#endif
-
-       /* PMC stuff */
-
-       sysdev_remove_file(s, &attr_mmcr0);
-       sysdev_remove_file(s, &attr_mmcr1);
-
-       if (cpu_has_feature(CPU_FTR_MMCRA))
-               sysdev_remove_file(s, &attr_mmcra);
-
-       if (cur_cpu_spec->num_pmcs >= 1)
-               sysdev_remove_file(s, &attr_pmc1);
-       if (cur_cpu_spec->num_pmcs >= 2)
-               sysdev_remove_file(s, &attr_pmc2);
-       if (cur_cpu_spec->num_pmcs >= 3)
-               sysdev_remove_file(s, &attr_pmc3);
-       if (cur_cpu_spec->num_pmcs >= 4)
-               sysdev_remove_file(s, &attr_pmc4);
-       if (cur_cpu_spec->num_pmcs >= 5)
-               sysdev_remove_file(s, &attr_pmc5);
-       if (cur_cpu_spec->num_pmcs >= 6)
-               sysdev_remove_file(s, &attr_pmc6);
-       if (cur_cpu_spec->num_pmcs >= 7)
-               sysdev_remove_file(s, &attr_pmc7);
-       if (cur_cpu_spec->num_pmcs >= 8)
-               sysdev_remove_file(s, &attr_pmc8);
-
-       if (cpu_has_feature(CPU_FTR_SMT))
-               sysdev_remove_file(s, &attr_purr);
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
-static int __devinit sysfs_cpu_notify(struct notifier_block *self,
-                                     unsigned long action, void *hcpu)
-{
-       unsigned int cpu = (unsigned int)(long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-               register_cpu_online(cpu);
-               break;
-#ifdef CONFIG_HOTPLUG_CPU
-       case CPU_DEAD:
-               unregister_cpu_online(cpu);
-               break;
-#endif
-       }
-       return NOTIFY_OK;
-}
-
-static struct notifier_block __devinitdata sysfs_cpu_nb = {
-       .notifier_call  = sysfs_cpu_notify,
-};
-
-/* NUMA stuff */
-
-#ifdef CONFIG_NUMA
-static struct node node_devices[MAX_NUMNODES];
-
-static void register_nodes(void)
-{
-       int i;
-
-       for (i = 0; i < MAX_NUMNODES; i++) {
-               if (node_online(i)) {
-                       int p_node = parent_node(i);
-                       struct node *parent = NULL;
-
-                       if (p_node != i)
-                               parent = &node_devices[p_node];
-
-                       register_node(&node_devices[i], i, parent);
-               }
-       }
-}
-#else
-static void register_nodes(void)
-{
-       return;
-}
-#endif
-
-/* Only valid if CPU is present. */
-static ssize_t show_physical_id(struct sys_device *dev, char *buf)
-{
-       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
-
-       return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id));
-}
-static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL);
-
-static int __init topology_init(void)
-{
-       int cpu;
-       struct node *parent = NULL;
-
-       register_nodes();
-
-       register_cpu_notifier(&sysfs_cpu_nb);
-
-       for_each_cpu(cpu) {
-               struct cpu *c = &per_cpu(cpu_devices, cpu);
-
-#ifdef CONFIG_NUMA
-               /* The node to which a cpu belongs can't be known
-                * until the cpu is made present.
-                */
-               parent = NULL;
-               if (cpu_present(cpu))
-                       parent = &node_devices[cpu_to_node(cpu)];
-#endif
-               /*
-                * For now, we just see if the system supports making
-                * the RTAS calls for CPU hotplug.  But, there may be a
-                * more comprehensive way to do this for an individual
-                * CPU.  For instance, the boot cpu might never be valid
-                * for hotplugging.
-                */
-               if (!ppc_md.cpu_die)
-                       c->no_control = 1;
-
-               if (cpu_online(cpu) || (c->no_control == 0)) {
-                       register_cpu(c, cpu, parent);
-
-                       sysdev_create_file(&c->sysdev, &attr_physical_id);
-               }
-
-               if (cpu_online(cpu))
-                       register_cpu_online(cpu);
-       }
-
-       return 0;
-}
-__initcall(topology_init);
index 4aacf521e3e445466e4133955bfe2b5accbf09b3..1bbacac44988168e58ce2d06888f195055d2697e 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/machdep.h>
 #include <asm/cputable.h>
 #include <asm/sections.h>
+#include <asm/systemcfg.h>
 #include <asm/vdso.h>
 
 #undef DEBUG
@@ -179,7 +180,7 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
         * Last page is systemcfg.
         */
        if ((vma->vm_end - address) <= PAGE_SIZE)
-               pg = virt_to_page(systemcfg);
+               pg = virt_to_page(_systemcfg);
        else
                pg = virt_to_page(vbase + offset);
 
@@ -604,7 +605,7 @@ void __init vdso_init(void)
                get_page(pg);
        }
 
-       get_page(virt_to_page(systemcfg));
+       get_page(virt_to_page(_systemcfg));
 }
 
 int in_gate_area_no_task(unsigned long addr)
index 9342d5bc7bb4e46d809490489f8dd51c4135d801..f5d49a1106545ca68c00840137434d20b92c0dc2 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 #include <linux/fs.h>
+#include <linux/platform_device.h>
 
 #include <linux/vmalloc.h>
 #include <asm/pgtable.h>
index a940b96433c7c5f90aeb9c0518ea3799c9560c20..e67b1d06611cfb84bf44ce65bf35bba4852f63a9 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 #include <linux/fs.h>
+#include <linux/platform_device.h>
 
 #include <asm/immap_cpm2.h>
 #include <asm/mpc8260.h>
index 5ef4e845a387237961799a9de29afb1c6c67263e..2e8f444696999312562430600ecb55d4c0f096aa 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 #include <linux/fs.h>
+#include <linux/platform_device.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
index d8c6e9cadcf583f83305d80f7b2e0f04c5675363..a3897fda71fa448c4f5d341e084da0ae87ad2569 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 #include <linux/fs.h>
+#include <linux/platform_device.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
index fcb66b9a0e289c1a16ad262beff5984dc42e6e08..e8593a60ee89d001e928adc737cbd3c638aa0de7 100644 (file)
@@ -306,7 +306,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
 {
        struct pci_controller *phb;
 
-       if (PCI_DN(dn)->phb) {
+       if (PCI_DN(dn) && PCI_DN(dn)->phb) {
                /* PHB already exists */
                return -EINVAL;
        }
index ccf20039e90975c932ca7ad97c79594395b26d3d..309eb557f9a340cb6b791b34021bcd8f65920a79 100644 (file)
@@ -156,7 +156,7 @@ config TCIC
 
 config PCMCIA_M8XX
         tristate "MPC8xx PCMCIA support"
-        depends on PCMCIA && PPC
+        depends on PCMCIA && PPC && 8xx 
         select PCCARD_NONSTATIC
         help
         Say Y here to include support for PowerPC 8xx series PCMCIA
index fe37541abbfe81b1f9fcf05fbd20bf6b31113611..bcecf5133b7ef46986f1242bebd0b36c1e3df9ba 100644 (file)
@@ -25,7 +25,7 @@ obj-$(CONFIG_PD6729)                          += pd6729.o
 obj-$(CONFIG_I82365)                           += i82365.o
 obj-$(CONFIG_I82092)                           += i82092.o
 obj-$(CONFIG_TCIC)                             += tcic.o
-obj-$(CONFIG_PCMCIA_M8XX)                              += m8xx_pcmcia.o
+obj-$(CONFIG_PCMCIA_M8XX)                      += m8xx_pcmcia.o
 obj-$(CONFIG_HD64465_PCMCIA)                   += hd64465_ss.o
 obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_core.o sa1100_cs.o
 obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_core.o sa1111_cs.o
@@ -47,10 +47,10 @@ au1x00_ss-$(CONFIG_MIPS_PB1200)                     += au1000_db1x00.o
 au1x00_ss-$(CONFIG_MIPS_PB1500)                        += au1000_pb1x00.o
 au1x00_ss-$(CONFIG_MIPS_DB1000)                        += au1000_db1x00.o
 au1x00_ss-$(CONFIG_MIPS_DB1100)                        += au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1200)                 += au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1200)                        += au1000_db1x00.o
 au1x00_ss-$(CONFIG_MIPS_DB1500)                        += au1000_db1x00.o
 au1x00_ss-$(CONFIG_MIPS_DB1550)                        += au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_XXS1500)               += au1000_xxs1500.o
+au1x00_ss-$(CONFIG_MIPS_XXS1500)               += au1000_xxs1500.o
 
 sa1111_cs-y                                    += sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)           += sa1100_neponset.o
index 24cfee1a412c9519efd3a5affe08d54226315497..abc13f28ba3f409396fe4b76d6caae9512b96cb3 100644 (file)
@@ -30,6 +30,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index b0e7908392a77d3de51a5d818001b9b3e260ed7c..f2c970b5f4ffa5ef2192b429208255acc10f3cc0 100644 (file)
@@ -22,6 +22,8 @@
 #define __ASM_AU1000_PCMCIA_H
 
 /* include the world */
+#include <linux/config.h>
+
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
index 86c0808d6a057920bfe07412cf1e73c9efff7c2a..fd5522ede867c6ea18421493e213aa6eaad7851a 100644 (file)
@@ -21,6 +21,7 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 01a895bc9a4795d8cd78ee6c9908f740ff3c761f..01874b0bb03be18c843b9903faa43abe59de9271 100644 (file)
@@ -27,7 +27,6 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
index 7ce455d01cc919a761ecd5de44bfc504c6246714..4ddd76239b34aff80f4783f9e2557baa51038326 100644 (file)
@@ -1366,6 +1366,7 @@ static int __init init_i82365(void)
     if (sockets == 0) {
        printk("not found.\n");
        platform_device_unregister(&i82365_device);
+       release_region(i365_base, 2);
        driver_unregister(&i82365_driver);
        return -ENODEV;
     }
index f8bed87cf2f14c6874fa70b5e0d0bde0eb7af9e4..6d9f71cfcb340d110f768ccc8628cd91f566e561 100644 (file)
@@ -39,7 +39,6 @@
 
 #include <asm/io.h>
 #include <asm/bitops.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 
 #include <linux/kernel.h>
@@ -50,6 +49,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/mpc8xx.h>
 #include <asm/8xx_immap.h>
@@ -546,29 +546,11 @@ static void m8xx_shutdown(void)
        free_irq(pcmcia_schlvl, NULL);
 }
 
-/* copied from tcic.c */
-
-static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-        int ret = 0;
-        if (level == SUSPEND_SAVE_STATE)
-                ret = pcmcia_socket_dev_suspend(dev, state);
-        return ret;
-}
-
-static int m8xx_drv_resume(struct device *dev, u32 level)
-{
-        int ret = 0;
-        if (level == RESUME_RESTORE_STATE)
-                ret = pcmcia_socket_dev_resume(dev);
-        return ret;
-}
-
 static struct device_driver m8xx_driver = {
         .name = "m8xx-pcmcia",
         .bus = &platform_bus_type,
-        .suspend = m8xx_drv_suspend,
-        .resume = m8xx_drv_resume,
+        .suspend = pcmcia_socket_dev_suspend,
+        .resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device m8xx_device = {
diff --git a/include/asm-powerpc/abs_addr.h b/include/asm-powerpc/abs_addr.h
new file mode 100644 (file)
index 0000000..1841510
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef _ASM_POWERPC_ABS_ADDR_H
+#define _ASM_POWERPC_ABS_ADDR_H
+
+#include <linux/config.h>
+
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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 <asm/types.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/firmware.h>
+
+struct mschunks_map {
+        unsigned long num_chunks;
+        unsigned long chunk_size;
+        unsigned long chunk_shift;
+        unsigned long chunk_mask;
+        u32 *mapping;
+};
+
+extern struct mschunks_map mschunks_map;
+
+/* Chunks are 256 KB */
+#define MSCHUNKS_CHUNK_SHIFT   (18)
+#define MSCHUNKS_CHUNK_SIZE    (1UL << MSCHUNKS_CHUNK_SHIFT)
+#define MSCHUNKS_OFFSET_MASK   (MSCHUNKS_CHUNK_SIZE - 1)
+
+static inline unsigned long chunk_to_addr(unsigned long chunk)
+{
+       return chunk << MSCHUNKS_CHUNK_SHIFT;
+}
+
+static inline unsigned long addr_to_chunk(unsigned long addr)
+{
+       return addr >> MSCHUNKS_CHUNK_SHIFT;
+}
+
+static inline unsigned long phys_to_abs(unsigned long pa)
+{
+       unsigned long chunk;
+
+       /* This is a no-op on non-iSeries */
+       if (!firmware_has_feature(FW_FEATURE_ISERIES))
+               return pa;
+
+       chunk = addr_to_chunk(pa);
+
+       if (chunk < mschunks_map.num_chunks)
+               chunk = mschunks_map.mapping[chunk];
+
+       return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK);
+}
+
+/* Convenience macros */
+#define virt_to_abs(va) phys_to_abs(__pa(va))
+#define abs_to_virt(aa) __va(aa)
+
+/*
+ * Converts Virtual Address to Real Address for
+ * Legacy iSeries Hypervisor calls
+ */
+#define iseries_hv_addr(virtaddr)      \
+       (0x8000000000000000 | virt_to_abs(virtaddr))
+
+#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
new file mode 100644 (file)
index 0000000..8b133ef
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _ASM_POWERPC_ASM_COMPAT_H
+#define _ASM_POWERPC_ASM_COMPAT_H
+
+#include <linux/config.h>
+#include <asm/types.h>
+
+#ifdef __ASSEMBLY__
+#  define stringify_in_c(...)  __VA_ARGS__
+#  define ASM_CONST(x)         x
+#else
+/* This version of stringify will deal with commas... */
+#  define __stringify_in_c(...)        #__VA_ARGS__
+#  define stringify_in_c(...)  __stringify_in_c(__VA_ARGS__) " "
+#  define __ASM_CONST(x)       x##UL
+#  define ASM_CONST(x)         __ASM_CONST(x)
+#endif
+
+#ifdef __powerpc64__
+
+/* operations for longs and pointers */
+#define PPC_LL         stringify_in_c(ld)
+#define PPC_STL                stringify_in_c(std)
+#define PPC_LCMPI      stringify_in_c(cmpdi)
+#define PPC_LONG       stringify_in_c(.llong)
+#define PPC_TLNEI      stringify_in_c(tdnei)
+#define PPC_LLARX      stringify_in_c(ldarx)
+#define PPC_STLCX      stringify_in_c(stdcx.)
+#define PPC_CNTLZL     stringify_in_c(cntlzd)
+
+#else /* 32-bit */
+
+/* operations for longs and pointers */
+#define PPC_LL         stringify_in_c(lwz)
+#define PPC_STL                stringify_in_c(stw)
+#define PPC_LCMPI      stringify_in_c(cmpwi)
+#define PPC_LONG       stringify_in_c(.long)
+#define PPC_TLNEI      stringify_in_c(twnei)
+#define PPC_LLARX      stringify_in_c(lwarx)
+#define PPC_STLCX      stringify_in_c(stwcx.)
+#define PPC_CNTLZL     stringify_in_c(cntlzw)
+
+#endif
+
+#ifdef CONFIG_IBM405_ERR77
+/* Erratum #77 on the 405 means we need a sync or dcbt before every
+ * stwcx.  The old ATOMIC_SYNC_FIX covered some but not all of this.
+ */
+#define PPC405_ERR77(ra,rb)    stringify_in_c(dcbt     ra, rb;)
+#define        PPC405_ERR77_SYNC       stringify_in_c(sync;)
+#else
+#define PPC405_ERR77(ra,rb)
+#define PPC405_ERR77_SYNC
+#endif
+
+#endif /* _ASM_POWERPC_ASM_COMPAT_H */
index ed4b345ed75d2fc6d9d317aaf96264e0acc8eca0..9c0b372a46e1ffb4f0160857ff0f21192f401692 100644 (file)
@@ -9,21 +9,13 @@ typedef struct { volatile int counter; } atomic_t;
 
 #ifdef __KERNEL__
 #include <asm/synch.h>
+#include <asm/asm-compat.h>
 
 #define ATOMIC_INIT(i)         { (i) }
 
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v,i)                (((v)->counter) = (i))
 
-/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
- * The old ATOMIC_SYNC_FIX covered some but not all of this.
- */
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb)    "dcbt " #ra "," #rb ";"
-#else
-#define PPC405_ERR77(ra,rb)
-#endif
-
 static __inline__ void atomic_add(int a, atomic_t *v)
 {
        int t;
@@ -205,5 +197,183 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
 #define smp_mb__before_atomic_inc()     smp_mb()
 #define smp_mb__after_atomic_inc()      smp_mb()
 
+#ifdef __powerpc64__
+
+typedef struct { volatile long counter; } atomic64_t;
+
+#define ATOMIC64_INIT(i)       { (i) }
+
+#define atomic64_read(v)       ((v)->counter)
+#define atomic64_set(v,i)      (((v)->counter) = (i))
+
+static __inline__ void atomic64_add(long a, atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+"1:    ldarx   %0,0,%3         # atomic64_add\n\
+       add     %0,%2,%0\n\
+       stdcx.  %0,0,%3 \n\
+       bne-    1b"
+       : "=&r" (t), "=m" (v->counter)
+       : "r" (a), "r" (&v->counter), "m" (v->counter)
+       : "cc");
+}
+
+static __inline__ long atomic64_add_return(long a, atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+       EIEIO_ON_SMP
+"1:    ldarx   %0,0,%2         # atomic64_add_return\n\
+       add     %0,%1,%0\n\
+       stdcx.  %0,0,%2 \n\
+       bne-    1b"
+       ISYNC_ON_SMP
+       : "=&r" (t)
+       : "r" (a), "r" (&v->counter)
+       : "cc", "memory");
+
+       return t;
+}
+
+#define atomic64_add_negative(a, v)    (atomic64_add_return((a), (v)) < 0)
+
+static __inline__ void atomic64_sub(long a, atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+"1:    ldarx   %0,0,%3         # atomic64_sub\n\
+       subf    %0,%2,%0\n\
+       stdcx.  %0,0,%3 \n\
+       bne-    1b"
+       : "=&r" (t), "=m" (v->counter)
+       : "r" (a), "r" (&v->counter), "m" (v->counter)
+       : "cc");
+}
+
+static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+       EIEIO_ON_SMP
+"1:    ldarx   %0,0,%2         # atomic64_sub_return\n\
+       subf    %0,%1,%0\n\
+       stdcx.  %0,0,%2 \n\
+       bne-    1b"
+       ISYNC_ON_SMP
+       : "=&r" (t)
+       : "r" (a), "r" (&v->counter)
+       : "cc", "memory");
+
+       return t;
+}
+
+static __inline__ void atomic64_inc(atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+"1:    ldarx   %0,0,%2         # atomic64_inc\n\
+       addic   %0,%0,1\n\
+       stdcx.  %0,0,%2 \n\
+       bne-    1b"
+       : "=&r" (t), "=m" (v->counter)
+       : "r" (&v->counter), "m" (v->counter)
+       : "cc");
+}
+
+static __inline__ long atomic64_inc_return(atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+       EIEIO_ON_SMP
+"1:    ldarx   %0,0,%1         # atomic64_inc_return\n\
+       addic   %0,%0,1\n\
+       stdcx.  %0,0,%1 \n\
+       bne-    1b"
+       ISYNC_ON_SMP
+       : "=&r" (t)
+       : "r" (&v->counter)
+       : "cc", "memory");
+
+       return t;
+}
+
+/*
+ * atomic64_inc_and_test - increment and test
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+static __inline__ void atomic64_dec(atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+"1:    ldarx   %0,0,%2         # atomic64_dec\n\
+       addic   %0,%0,-1\n\
+       stdcx.  %0,0,%2\n\
+       bne-    1b"
+       : "=&r" (t), "=m" (v->counter)
+       : "r" (&v->counter), "m" (v->counter)
+       : "cc");
+}
+
+static __inline__ long atomic64_dec_return(atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+       EIEIO_ON_SMP
+"1:    ldarx   %0,0,%1         # atomic64_dec_return\n\
+       addic   %0,%0,-1\n\
+       stdcx.  %0,0,%1\n\
+       bne-    1b"
+       ISYNC_ON_SMP
+       : "=&r" (t)
+       : "r" (&v->counter)
+       : "cc", "memory");
+
+       return t;
+}
+
+#define atomic64_sub_and_test(a, v)    (atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec_and_test(v)       (atomic64_dec_return((v)) == 0)
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
+{
+       long t;
+
+       __asm__ __volatile__(
+       EIEIO_ON_SMP
+"1:    ldarx   %0,0,%1         # atomic64_dec_if_positive\n\
+       addic.  %0,%0,-1\n\
+       blt-    2f\n\
+       stdcx.  %0,0,%1\n\
+       bne-    1b"
+       ISYNC_ON_SMP
+       "\n\
+2:"    : "=&r" (t)
+       : "r" (&v->counter)
+       : "cc", "memory");
+
+       return t;
+}
+
+#endif /* __powerpc64__ */
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_ATOMIC_H_ */
index dc25c53704d59c9dce802fe9c7b2a18bfc12d2fb..5727229b0444aee452dd73f79a850d8f18ac89a0 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <linux/compiler.h>
 #include <asm/atomic.h>
+#include <asm/asm-compat.h>
 #include <asm/synch.h>
 
 /*
 #define BITOP_WORD(nr)         ((nr) / BITS_PER_LONG)
 #define BITOP_LE_SWIZZLE       ((BITS_PER_LONG-1) & ~0x7)
 
-#ifdef CONFIG_PPC64
-#define LARXL          "ldarx"
-#define STCXL          "stdcx."
-#define CNTLZL         "cntlzd"
-#else
-#define LARXL          "lwarx"
-#define STCXL          "stwcx."
-#define CNTLZL         "cntlzw"
-#endif
-
 static __inline__ void set_bit(int nr, volatile unsigned long *addr)
 {
        unsigned long old;
@@ -69,10 +60,10 @@ static __inline__ void set_bit(int nr, volatile unsigned long *addr)
        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
        __asm__ __volatile__(
-"1:"   LARXL " %0,0,%3 # set_bit\n"
+"1:"   PPC_LLARX "%0,0,%3      # set_bit\n"
        "or     %0,%0,%2\n"
        PPC405_ERR77(0,%3)
-       STCXL " %0,0,%3\n"
+       PPC_STLCX "%0,0,%3\n"
        "bne-   1b"
        : "=&r"(old), "=m"(*p)
        : "r"(mask), "r"(p), "m"(*p)
@@ -86,10 +77,10 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
        __asm__ __volatile__(
-"1:"   LARXL " %0,0,%3 # set_bit\n"
+"1:"   PPC_LLARX "%0,0,%3      # clear_bit\n"
        "andc   %0,%0,%2\n"
        PPC405_ERR77(0,%3)
-       STCXL " %0,0,%3\n"
+       PPC_STLCX "%0,0,%3\n"
        "bne-   1b"
        : "=&r"(old), "=m"(*p)
        : "r"(mask), "r"(p), "m"(*p)
@@ -103,10 +94,10 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr)
        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
        __asm__ __volatile__(
-"1:"   LARXL " %0,0,%3 # set_bit\n"
+"1:"   PPC_LLARX "%0,0,%3      # change_bit\n"
        "xor    %0,%0,%2\n"
        PPC405_ERR77(0,%3)
-       STCXL " %0,0,%3\n"
+       PPC_STLCX "%0,0,%3\n"
        "bne-   1b"
        : "=&r"(old), "=m"(*p)
        : "r"(mask), "r"(p), "m"(*p)
@@ -122,10 +113,10 @@ static __inline__ int test_and_set_bit(unsigned long nr,
 
        __asm__ __volatile__(
        EIEIO_ON_SMP
-"1:"   LARXL " %0,0,%3         # test_and_set_bit\n"
+"1:"   PPC_LLARX "%0,0,%3              # test_and_set_bit\n"
        "or     %1,%0,%2 \n"
        PPC405_ERR77(0,%3)
-       STCXL " %1,0,%3 \n"
+       PPC_STLCX "%1,0,%3 \n"
        "bne-   1b"
        ISYNC_ON_SMP
        : "=&r" (old), "=&r" (t)
@@ -144,10 +135,10 @@ static __inline__ int test_and_clear_bit(unsigned long nr,
 
        __asm__ __volatile__(
        EIEIO_ON_SMP
-"1:"   LARXL " %0,0,%3         # test_and_clear_bit\n"
+"1:"   PPC_LLARX "%0,0,%3              # test_and_clear_bit\n"
        "andc   %1,%0,%2 \n"
        PPC405_ERR77(0,%3)
-       STCXL " %1,0,%3 \n"
+       PPC_STLCX "%1,0,%3 \n"
        "bne-   1b"
        ISYNC_ON_SMP
        : "=&r" (old), "=&r" (t)
@@ -166,10 +157,10 @@ static __inline__ int test_and_change_bit(unsigned long nr,
 
        __asm__ __volatile__(
        EIEIO_ON_SMP
-"1:"   LARXL " %0,0,%3         # test_and_change_bit\n"
+"1:"   PPC_LLARX "%0,0,%3              # test_and_change_bit\n"
        "xor    %1,%0,%2 \n"
        PPC405_ERR77(0,%3)
-       STCXL " %1,0,%3 \n"
+       PPC_STLCX "%1,0,%3 \n"
        "bne-   1b"
        ISYNC_ON_SMP
        : "=&r" (old), "=&r" (t)
@@ -184,9 +175,9 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
         unsigned long old;
 
        __asm__ __volatile__(
-"1:"   LARXL " %0,0,%3         # set_bit\n"
+"1:"   PPC_LLARX "%0,0,%3         # set_bits\n"
        "or     %0,%0,%2\n"
-       STCXL " %0,0,%3\n"
+       PPC_STLCX "%0,0,%3\n"
        "bne-   1b"
        : "=&r" (old), "=m" (*addr)
        : "r" (mask), "r" (addr), "m" (*addr)
@@ -268,7 +259,7 @@ static __inline__ int __ilog2(unsigned long x)
 {
        int lz;
 
-       asm (CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
+       asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
        return BITS_PER_LONG - 1 - lz;
 }
 
index d625ee55f9571e68503cbd43d01240de1875d22b..b001ecb3cd9956030f8520b6fad183eb3186eee7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _ASM_POWERPC_BUG_H
 #define _ASM_POWERPC_BUG_H
 
+#include <asm/asm-compat.h>
 /*
  * Define an illegal instr to trap on the bug.
  * We don't use 0 because that marks the end of a function
 
 #ifndef __ASSEMBLY__
 
-#ifdef __powerpc64__
-#define BUG_TABLE_ENTRY                ".llong"
-#define BUG_TRAP_OP            "tdnei"
-#else 
-#define BUG_TABLE_ENTRY                ".long"
-#define BUG_TRAP_OP            "twnei"
-#endif /* __powerpc64__ */
-
 struct bug_entry {
        unsigned long   bug_addr;
        long            line;
@@ -40,16 +33,16 @@ struct bug_entry *find_bug(unsigned long bugaddr);
        __asm__ __volatile__(                                            \
                "1:     twi 31,0,0\n"                                    \
                ".section __bug_table,\"a\"\n"                           \
-               "\t"BUG_TABLE_ENTRY"    1b,%0,%1,%2\n"                   \
+               "\t"PPC_LONG"   1b,%0,%1,%2\n"                   \
                ".previous"                                              \
                : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
 } while (0)
 
 #define BUG_ON(x) do {                                         \
        __asm__ __volatile__(                                   \
-               "1:     "BUG_TRAP_OP"   %0,0\n"                 \
+               "1:     "PPC_TLNEI"     %0,0\n"                 \
                ".section __bug_table,\"a\"\n"                  \
-               "\t"BUG_TABLE_ENTRY"    1b,%1,%2,%3\n"          \
+               "\t"PPC_LONG"   1b,%1,%2,%3\n"          \
                ".previous"                                     \
                : : "r" ((long)(x)), "i" (__LINE__),            \
                    "i" (__FILE__), "i" (__FUNCTION__));        \
@@ -57,9 +50,9 @@ struct bug_entry *find_bug(unsigned long bugaddr);
 
 #define WARN_ON(x) do {                                                \
        __asm__ __volatile__(                                   \
-               "1:     "BUG_TRAP_OP"   %0,0\n"                 \
+               "1:     "PPC_TLNEI"     %0,0\n"                 \
                ".section __bug_table,\"a\"\n"                  \
-               "\t"BUG_TABLE_ENTRY"    1b,%1,%2,%3\n"          \
+               "\t"PPC_LONG"   1b,%1,%2,%3\n"          \
                ".previous"                                     \
                : : "r" ((long)(x)),                            \
                    "i" (__LINE__ + BUG_WARNING_TRAP),          \
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
new file mode 100644 (file)
index 0000000..26ce502
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _ASM_POWERPC_CACHE_H
+#define _ASM_POWERPC_CACHE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+/* bytes per L1 cache line */
+#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+#define L1_CACHE_SHIFT         4
+#define MAX_COPY_PREFETCH      1
+#elif defined(CONFIG_PPC32)
+#define L1_CACHE_SHIFT         5
+#define MAX_COPY_PREFETCH      4
+#else /* CONFIG_PPC64 */
+#define L1_CACHE_SHIFT         7
+#endif
+
+#define        L1_CACHE_BYTES          (1 << L1_CACHE_SHIFT)
+
+#define        SMP_CACHE_BYTES         L1_CACHE_BYTES
+#define L1_CACHE_SHIFT_MAX     7 /* largest L1 which this arch supports */
+
+#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
+struct ppc64_caches {
+       u32     dsize;                  /* L1 d-cache size */
+       u32     dline_size;             /* L1 d-cache line size */
+       u32     log_dline_size;
+       u32     dlines_per_page;
+       u32     isize;                  /* L1 i-cache size */
+       u32     iline_size;             /* L1 i-cache line size */
+       u32     log_iline_size;
+       u32     ilines_per_page;
+};
+
+extern struct ppc64_caches ppc64_caches;
+#endif /* __powerpc64__ && ! __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_CACHE_H */
diff --git a/include/asm-powerpc/cacheflush.h b/include/asm-powerpc/cacheflush.h
new file mode 100644 (file)
index 0000000..8a740c8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  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.
+ */
+#ifndef _ASM_POWERPC_CACHEFLUSH_H
+#define _ASM_POWERPC_CACHEFLUSH_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <asm/cputable.h>
+
+/*
+ * No cache flushing is required when address mappings are changed,
+ * because the caches on PowerPCs are physically addressed.
+ */
+#define flush_cache_all()                      do { } while (0)
+#define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_range(vma, start, end)     do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
+#define flush_icache_page(vma, page)           do { } while (0)
+#define flush_cache_vmap(start, end)           do { } while (0)
+#define flush_cache_vunmap(start, end)         do { } while (0)
+
+extern void flush_dcache_page(struct page *page);
+#define flush_dcache_mmap_lock(mapping)                do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
+
+extern void __flush_icache_range(unsigned long, unsigned long);
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+       if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+               __flush_icache_range(start, stop);
+}
+
+extern void flush_icache_user_range(struct vm_area_struct *vma,
+                                   struct page *page, unsigned long addr,
+                                   int len);
+extern void __flush_dcache_icache(void *page_va);
+extern void flush_dcache_icache_page(struct page *page);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE)
+extern void __flush_dcache_icache_phys(unsigned long physaddr);
+#endif /* CONFIG_PPC32 && !CONFIG_BOOKE */
+
+extern void flush_dcache_range(unsigned long start, unsigned long stop);
+#ifdef CONFIG_PPC32
+extern void clean_dcache_range(unsigned long start, unsigned long stop);
+extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
+#endif /* CONFIG_PPC32 */
+#ifdef CONFIG_PPC64
+extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
+extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
+#endif
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+       do { \
+               memcpy(dst, src, len); \
+               flush_icache_user_range(vma, page, vaddr, len); \
+       } while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+       memcpy(dst, src, len)
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_POWERPC_CACHEFLUSH_H */
diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h
new file mode 100644 (file)
index 0000000..4db4360
--- /dev/null
@@ -0,0 +1,205 @@
+#ifndef _ASM_POWERPC_COMPAT_H
+#define _ASM_POWERPC_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#define COMPAT_USER_HZ 100
+
+typedef u32            compat_size_t;
+typedef s32            compat_ssize_t;
+typedef s32            compat_time_t;
+typedef s32            compat_clock_t;
+typedef s32            compat_pid_t;
+typedef u32            __compat_uid_t;
+typedef u32            __compat_gid_t;
+typedef u32            __compat_uid32_t;
+typedef u32            __compat_gid32_t;
+typedef u32            compat_mode_t;
+typedef u32            compat_ino_t;
+typedef u32            compat_dev_t;
+typedef s32            compat_off_t;
+typedef s64            compat_loff_t;
+typedef s16            compat_nlink_t;
+typedef u16            compat_ipc_pid_t;
+typedef s32            compat_daddr_t;
+typedef u32            compat_caddr_t;
+typedef __kernel_fsid_t        compat_fsid_t;
+typedef s32            compat_key_t;
+typedef s32            compat_timer_t;
+
+typedef s32            compat_int_t;
+typedef s32            compat_long_t;
+typedef u32            compat_uint_t;
+typedef u32            compat_ulong_t;
+
+struct compat_timespec {
+       compat_time_t   tv_sec;
+       s32             tv_nsec;
+};
+
+struct compat_timeval {
+       compat_time_t   tv_sec;
+       s32             tv_usec;
+};
+
+struct compat_stat {
+       compat_dev_t    st_dev;
+       compat_ino_t    st_ino;
+       compat_mode_t   st_mode;
+       compat_nlink_t  st_nlink;
+       __compat_uid32_t        st_uid;
+       __compat_gid32_t        st_gid;
+       compat_dev_t    st_rdev;
+       compat_off_t    st_size;
+       compat_off_t    st_blksize;
+       compat_off_t    st_blocks;
+       compat_time_t   st_atime;
+       u32             st_atime_nsec;
+       compat_time_t   st_mtime;
+       u32             st_mtime_nsec;
+       compat_time_t   st_ctime;
+       u32             st_ctime_nsec;
+       u32             __unused4[2];
+};
+
+struct compat_flock {
+       short           l_type;
+       short           l_whence;
+       compat_off_t    l_start;
+       compat_off_t    l_len;
+       compat_pid_t    l_pid;
+};
+
+#define F_GETLK64      12      /*  using 'struct flock64' */
+#define F_SETLK64      13
+#define F_SETLKW64     14
+
+struct compat_flock64 {
+       short           l_type;
+       short           l_whence;
+       compat_loff_t   l_start;
+       compat_loff_t   l_len;
+       compat_pid_t    l_pid;
+};
+
+struct compat_statfs {
+       int             f_type;
+       int             f_bsize;
+       int             f_blocks;
+       int             f_bfree;
+       int             f_bavail;
+       int             f_files;
+       int             f_ffree;
+       compat_fsid_t   f_fsid;
+       int             f_namelen;      /* SunOS ignores this field. */
+       int             f_frsize;
+       int             f_spare[5];
+};
+
+#define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
+#define COMPAT_RLIM_INFINITY           0xffffffff
+
+typedef u32            compat_old_sigset_t;
+
+#define _COMPAT_NSIG           64
+#define _COMPAT_NSIG_BPW       32
+
+typedef u32            compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX       0x7fffffff
+#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef        u32             compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+       return (void __user *)(unsigned long)uptr;
+}
+
+static inline void __user *compat_alloc_user_space(long len)
+{
+       struct pt_regs *regs = current->thread.regs;
+       unsigned long usp = regs->gpr[1];
+
+       /*
+        * We cant access below the stack pointer in the 32bit ABI and
+        * can access 288 bytes in the 64bit ABI
+        */
+       if (!(test_thread_flag(TIF_32BIT)))
+               usp -= 288;
+
+       return (void __user *) (usp - len);
+}
+
+/*
+ * ipc64_perm is actually 32/64bit clean but since the compat layer refers to
+ * it we may as well define it.
+ */
+struct compat_ipc64_perm {
+       compat_key_t key;
+       __compat_uid_t uid;
+       __compat_gid_t gid;
+       __compat_uid_t cuid;
+       __compat_gid_t cgid;
+       compat_mode_t mode;
+       unsigned int seq;
+       unsigned int __pad2;
+       unsigned long __unused1;        /* yes they really are 64bit pads */
+       unsigned long __unused2;
+};
+
+struct compat_semid64_ds {
+       struct compat_ipc64_perm sem_perm;
+       unsigned int __unused1;
+       compat_time_t sem_otime;
+       unsigned int __unused2;
+       compat_time_t sem_ctime;
+       compat_ulong_t sem_nsems;
+       compat_ulong_t __unused3;
+       compat_ulong_t __unused4;
+};
+
+struct compat_msqid64_ds {
+       struct compat_ipc64_perm msg_perm;
+       unsigned int __unused1;
+       compat_time_t msg_stime;
+       unsigned int __unused2;
+       compat_time_t msg_rtime;
+       unsigned int __unused3;
+       compat_time_t msg_ctime;
+       compat_ulong_t msg_cbytes;
+       compat_ulong_t msg_qnum;
+       compat_ulong_t msg_qbytes;
+       compat_pid_t msg_lspid;
+       compat_pid_t msg_lrpid;
+       compat_ulong_t __unused4;
+       compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+       struct compat_ipc64_perm shm_perm;
+       unsigned int __unused1;
+       compat_time_t shm_atime;
+       unsigned int __unused2;
+       compat_time_t shm_dtime;
+       unsigned int __unused3;
+       compat_time_t shm_ctime;
+       unsigned int __unused4;
+       compat_size_t shm_segsz;
+       compat_pid_t shm_cpid;
+       compat_pid_t shm_lpid;
+       compat_ulong_t shm_nattch;
+       compat_ulong_t __unused5;
+       compat_ulong_t __unused6;
+};
+
+#endif /* _ASM_POWERPC_COMPAT_H */
index 79a0556a0ab8ef09f2009c0e7de0789c9e09f0e8..04e2726002cf2d3fadd1bff2cc653b003e80e550 100644 (file)
@@ -2,7 +2,7 @@
 #define __ASM_POWERPC_CPUTABLE_H
 
 #include <linux/config.h>
-#include <asm/ppc_asm.h> /* for ASM_CONST */
+#include <asm/asm-compat.h>
 
 #define PPC_FEATURE_32                 0x80000000
 #define PPC_FEATURE_64                 0x40000000
 #define PPC_FEATURE_HAS_EFP_SINGLE     0x00400000
 #define PPC_FEATURE_HAS_EFP_DOUBLE     0x00200000
 #define PPC_FEATURE_NO_TB              0x00100000
+#define PPC_FEATURE_POWER4             0x00080000
+#define PPC_FEATURE_POWER5             0x00040000
+#define PPC_FEATURE_POWER5_PLUS                0x00020000
+#define PPC_FEATURE_CELL               0x00010000
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h
new file mode 100644 (file)
index 0000000..82cd4a9
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _ASM_POWERPC_CURRENT_H
+#define _ASM_POWERPC_CURRENT_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+struct task_struct;
+
+#ifdef __powerpc64__
+#include <asm/paca.h>
+
+#define current                (get_paca()->__current)
+
+#else
+
+/*
+ * We keep `current' in r2 for speed.
+ */
+register struct task_struct *current asm ("r2");
+
+#endif
+
+#endif /* _ASM_POWERPC_CURRENT_H */
diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h
new file mode 100644 (file)
index 0000000..d168a30
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *     eeh_event.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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
+ *
+ * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
+ */
+
+#ifndef ASM_PPC64_EEH_EVENT_H
+#define ASM_PPC64_EEH_EVENT_H
+
+/** EEH event -- structure holding pci controller data that describes
+ *  a change in the isolation status of a PCI slot.  A pointer
+ *  to this struct is passed as the data pointer in a notify callback.
+ */
+struct eeh_event {
+       struct list_head     list;
+       struct device_node      *dn;   /* struct device node */
+       struct pci_dev       *dev;  /* affected device */
+       int                  state;
+       int time_unavail;    /* milliseconds until device might be available */
+};
+
+/**
+ * eeh_send_failure_event - generate a PCI error event
+ * @dev pci device
+ *
+ * This routine builds a PCI error event which will be delivered
+ * to all listeners on the peh_notifier_chain.
+ *
+ * This routine can be called within an interrupt context;
+ * the actual event will be delivered in a normal context
+ * (from a workqueue).
+ */
+int eeh_send_failure_event (struct device_node *dn,
+                            struct pci_dev *dev,
+                            int reset_state,
+                            int time_unavail);
+
+#endif /* ASM_PPC64_EEH_EVENT_H */
index 806c142ae9ea9dfa15622514bff45b0ffcc76be9..12fabbcb04f04a7bcb7ec248c39fdbeedb0ea915 100644 (file)
@@ -43,6 +43,7 @@
 #define FW_FEATURE_ISERIES     (1UL<<21)
 
 enum {
+#ifdef CONFIG_PPC64
        FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE |
                FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY |
                FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM |
@@ -70,6 +71,11 @@ enum {
                FW_FEATURE_ISERIES_ALWAYS &
 #endif
                FW_FEATURE_POSSIBLE,
+
+#else /* CONFIG_PPC64 */
+       FW_FEATURE_POSSIBLE = 0,
+       FW_FEATURE_ALWAYS = 0,
+#endif
 };
 
 /* This is used to identify firmware features which are available
index 37c94e52ab6dd6a5bb0d41bbdfb2a2082479e0b5..f0319d50b129e034cebbbd2da463d0e8a1242723 100644 (file)
@@ -7,13 +7,14 @@
 #include <asm/errno.h>
 #include <asm/synch.h>
 #include <asm/uaccess.h>
-#include <asm/ppc_asm.h>
+#include <asm/asm-compat.h>
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
        SYNC_ON_SMP \
 "1:    lwarx   %0,0,%2\n" \
        insn \
+       PPC405_ERR77(0, %2) \
 "2:    stwcx.  %1,0,%2\n" \
        "bne-   1b\n" \
        "li     %1,0\n" \
@@ -23,7 +24,7 @@
        ".previous\n" \
        ".section __ex_table,\"a\"\n" \
        ".align 3\n" \
-       DATAL " 1b,4b,2b,4b\n" \
+       PPC_LONG "1b,4b,2b,4b\n" \
        ".previous" \
        : "=&r" (oldval), "=&r" (ret) \
        : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
new file mode 100644 (file)
index 0000000..d36da61
--- /dev/null
@@ -0,0 +1,173 @@
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
+
+#define HVSC                   .long 0x44000022
+
+#define H_Success      0
+#define H_Busy         1       /* Hardware busy -- retry later */
+#define H_Constrained  4       /* Resource request constrained to max allowed */
+#define H_LongBusyStartRange   9900  /* Start of long busy range */
+#define H_LongBusyOrder1msec   9900  /* Long busy, hint that 1msec is a good time to retry */
+#define H_LongBusyOrder10msec  9901  /* Long busy, hint that 10msec is a good time to retry */
+#define H_LongBusyOrder100msec 9902  /* Long busy, hint that 100msec is a good time to retry */
+#define H_LongBusyOrder1sec    9903  /* Long busy, hint that 1sec is a good time to retry */
+#define H_LongBusyOrder10sec   9904  /* Long busy, hint that 10sec is a good time to retry */
+#define H_LongBusyOrder100sec  9905  /* Long busy, hint that 100sec is a good time to retry */
+#define H_LongBusyEndRange     9905  /* End of long busy range */
+#define H_Hardware     -1      /* Hardware error */
+#define H_Function     -2      /* Function not supported */
+#define H_Privilege    -3      /* Caller not privileged */
+#define H_Parameter    -4      /* Parameter invalid, out-of-range or conflicting */
+#define H_Bad_Mode     -5      /* Illegal msr value */
+#define H_PTEG_Full    -6      /* PTEG is full */
+#define H_Not_Found    -7      /* PTE was not found" */
+#define H_Reserved_DABR        -8      /* DABR address is reserved by the hypervisor on this processor" */
+#define H_NoMem                 -9
+#define H_Authority            -10
+#define H_Permission           -11
+#define H_Dropped              -12
+#define H_SourceParm           -13
+#define H_DestParm             -14
+#define H_RemoteParm           -15
+#define H_Resource             -16
+
+/* Long Busy is a condition that can be returned by the firmware
+ * when a call cannot be completed now, but the identical call
+ * should be retried later.  This prevents calls blocking in the
+ * firmware for long periods of time. Annoyingly the firmware can return
+ * a range of return codes, hinting at how long we should wait before
+ * retrying.  If you don't care for the hint, the macro below is a good
+ * way to check for the long_busy return codes
+ */
+#define H_isLongBusy(x)  ((x >= H_LongBusyStartRange) && (x <= H_LongBusyEndRange))
+
+/* Flags */
+#define H_LARGE_PAGE           (1UL<<(63-16))
+#define H_EXACT                        (1UL<<(63-24))  /* Use exact PTE or return H_PTEG_FULL */
+#define H_R_XLATE              (1UL<<(63-25))  /* include a valid logical page num in the pte if the valid bit is set */
+#define H_READ_4               (1UL<<(63-26))  /* Return 4 PTEs */
+#define H_AVPN                 (1UL<<(63-32))  /* An avpn is provided as a sanity test */
+#define H_ANDCOND              (1UL<<(63-33))
+#define H_ICACHE_INVALIDATE    (1UL<<(63-40))  /* icbi, etc.  (ignored for IO pages) */
+#define H_ICACHE_SYNCHRONIZE   (1UL<<(63-41))  /* dcbst, icbi, etc (ignored for IO pages */
+#define H_ZERO_PAGE            (1UL<<(63-48))  /* zero the page before mapping (ignored for IO pages) */
+#define H_COPY_PAGE            (1UL<<(63-49))
+#define H_N                    (1UL<<(63-61))
+#define H_PP1                  (1UL<<(63-62))
+#define H_PP2                  (1UL<<(63-63))
+
+/* DABRX flags */
+#define H_DABRX_HYPERVISOR     (1UL<<(63-61))
+#define H_DABRX_KERNEL         (1UL<<(63-62))
+#define H_DABRX_USER           (1UL<<(63-63))
+
+/* pSeries hypervisor opcodes */
+#define H_REMOVE               0x04
+#define H_ENTER                        0x08
+#define H_READ                 0x0c
+#define H_CLEAR_MOD            0x10
+#define H_CLEAR_REF            0x14
+#define H_PROTECT              0x18
+#define H_GET_TCE              0x1c
+#define H_PUT_TCE              0x20
+#define H_SET_SPRG0            0x24
+#define H_SET_DABR             0x28
+#define H_PAGE_INIT            0x2c
+#define H_SET_ASR              0x30
+#define H_ASR_ON               0x34
+#define H_ASR_OFF              0x38
+#define H_LOGICAL_CI_LOAD      0x3c
+#define H_LOGICAL_CI_STORE     0x40
+#define H_LOGICAL_CACHE_LOAD   0x44
+#define H_LOGICAL_CACHE_STORE  0x48
+#define H_LOGICAL_ICBI         0x4c
+#define H_LOGICAL_DCBF         0x50
+#define H_GET_TERM_CHAR                0x54
+#define H_PUT_TERM_CHAR                0x58
+#define H_REAL_TO_LOGICAL      0x5c
+#define H_HYPERVISOR_DATA      0x60
+#define H_EOI                  0x64
+#define H_CPPR                 0x68
+#define H_IPI                  0x6c
+#define H_IPOLL                        0x70
+#define H_XIRR                 0x74
+#define H_PERFMON              0x7c
+#define H_MIGRATE_DMA          0x78
+#define H_REGISTER_VPA         0xDC
+#define H_CEDE                 0xE0
+#define H_CONFER               0xE4
+#define H_PROD                 0xE8
+#define H_GET_PPP              0xEC
+#define H_SET_PPP              0xF0
+#define H_PURR                 0xF4
+#define H_PIC                  0xF8
+#define H_REG_CRQ              0xFC
+#define H_FREE_CRQ             0x100
+#define H_VIO_SIGNAL           0x104
+#define H_SEND_CRQ             0x108
+#define H_COPY_RDMA             0x110
+#define H_SET_XDABR            0x134
+#define H_STUFF_TCE            0x138
+#define H_PUT_TCE_INDIRECT     0x13C
+#define H_VTERM_PARTNER_INFO   0x150
+#define H_REGISTER_VTERM       0x154
+#define H_FREE_VTERM           0x158
+#define H_POLL_PENDING         0x1D8
+
+#ifndef __ASSEMBLY__
+
+/* plpar_hcall() -- Generic call interface using above opcodes
+ *
+ * The actual call interface is a hypervisor call instruction with
+ * the opcode in R3 and input args in R4-R7.
+ * Status is returned in R3 with variable output values in R4-R11.
+ * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now
+ * and return only two out args which MUST ALWAYS BE PROVIDED.
+ */
+long plpar_hcall(unsigned long opcode,
+                unsigned long arg1,
+                unsigned long arg2,
+                unsigned long arg3,
+                unsigned long arg4,
+                unsigned long *out1,
+                unsigned long *out2,
+                unsigned long *out3);
+
+/* Same as plpar_hcall but for those opcodes that return no values
+ * other than status.  Slightly more efficient.
+ */
+long plpar_hcall_norets(unsigned long opcode, ...);
+
+/*
+ * Special hcall interface for ibmveth support.
+ * Takes 8 input parms. Returns a rc and stores the
+ * R4 return value in *out1.
+ */
+long plpar_hcall_8arg_2ret(unsigned long opcode,
+                          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 *out1);
+
+/* plpar_hcall_4out()
+ *
+ * same as plpar_hcall except with 4 output arguments.
+ *
+ */
+long plpar_hcall_4out(unsigned long opcode,
+                     unsigned long arg1,
+                     unsigned long arg2,
+                     unsigned long arg3,
+                     unsigned long arg4,
+                     unsigned long *out1,
+                     unsigned long *out2,
+                     unsigned long *out3,
+                     unsigned long *out4);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_POWERPC_HVCALL_H */
index c37b31b96337af1fd76f302a546edadb39ab5c84..26b89d859c56e24245a72cdad5e314a1612f5ef5 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/processor.h>
 
 extern void timer_interrupt(struct pt_regs *);
-extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
 
 #ifdef CONFIG_PPC_ISERIES
 
index b3935ea28fff181a4b3a30bb0d485b3eab15e9ad..c9fbcede0ef9faf5773db4d69663e8b7c3661d52 100644 (file)
@@ -429,7 +429,6 @@ extern u64 ppc64_interrupt_controller;
 #define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
 /* pedantic: these are long because they are used with set_bit --RR */
 extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
 extern atomic_t ppc_n_lost_interrupts;
 
 #define virt_irq_create_mapping(x)     (x)
@@ -488,8 +487,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS];
 
 extern void irq_ctx_init(void);
 extern void call_do_softirq(struct thread_info *tp);
-extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
-                       struct irqaction *action, struct thread_info *tp);
+extern int call___do_IRQ(int irq, struct pt_regs *regs,
+               struct thread_info *tp);
 
 #define __ARCH_HAS_DO_SOFTIRQ
 
diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h
new file mode 100644 (file)
index 0000000..c1bedab
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * lppaca.h
+ * Copyright (C) 2001  Mike Corrigan IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#ifndef _ASM_POWERPC_LPPACA_H
+#define _ASM_POWERPC_LPPACA_H
+
+//=============================================================================
+//
+//     This control block contains the data that is shared between the
+//     hypervisor (PLIC) and the OS.
+//
+//
+//----------------------------------------------------------------------------
+#include <asm/types.h>
+
+struct lppaca {
+//=============================================================================
+// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
+// NOTE: The xDynXyz fields are fields that will be dynamically changed by
+// PLIC when preparing to bring a processor online or when dispatching a
+// virtual processor!
+//=============================================================================
+       u32     desc;                   // Eye catcher 0xD397D781       x00-x03
+       u16     size;                   // Size of this struct          x04-x05
+       u16     reserved1;              // Reserved                     x06-x07
+       u16     reserved2:14;           // Reserved                     x08-x09
+       u8      shared_proc:1;          // Shared processor indicator   ...
+       u8      secondary_thread:1;     // Secondary thread indicator   ...
+       volatile u8 dyn_proc_status:8;  // Dynamic Status of this proc  x0A-x0A
+       u8      secondary_thread_count; // Secondary thread count       x0B-x0B
+       volatile u16 dyn_hv_phys_proc_index;// Dynamic HV Physical Proc Index0C-x0D
+       volatile u16 dyn_hv_log_proc_index;// Dynamic HV Logical Proc Indexx0E-x0F
+       u32     decr_val;               // Value for Decr programming   x10-x13
+       u32     pmc_val;                // Value for PMC regs           x14-x17
+       volatile u32 dyn_hw_node_id;    // Dynamic Hardware Node id     x18-x1B
+       volatile u32 dyn_hw_proc_id;    // Dynamic Hardware Proc Id     x1C-x1F
+       volatile u32 dyn_pir;           // Dynamic ProcIdReg value      x20-x23
+       u32     dsei_data;              // DSEI data                    x24-x27
+       u64     sprg3;                  // SPRG3 value                  x28-x2F
+       u8      reserved3[80];          // Reserved                     x30-x7F
+
+//=============================================================================
+// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
+//=============================================================================
+       // This Dword contains a byte for each type of interrupt that can occur.
+       // The IPI is a count while the others are just a binary 1 or 0.
+       union {
+               u64     any_int;
+               struct {
+                       u16     reserved;       // Reserved - cleared by #mpasmbl
+                       u8      xirr_int;       // Indicates xXirrValue is valid or Immed IO
+                       u8      ipi_cnt;        // IPI Count
+                       u8      decr_int;       // DECR interrupt occurred
+                       u8      pdc_int;        // PDC interrupt occurred
+                       u8      quantum_int;    // Interrupt quantum reached
+                       u8      old_plic_deferred_ext_int;      // Old PLIC has a deferred XIRR pending
+               } fields;
+       } int_dword;
+
+       // Whenever any fields in this Dword are set then PLIC will defer the
+       // processing of external interrupts.  Note that PLIC will store the
+       // XIRR directly into the xXirrValue field so that another XIRR will
+       // not be presented until this one clears.  The layout of the low
+       // 4-bytes of this Dword is upto SLIC - PLIC just checks whether the
+       // entire Dword is zero or not.  A non-zero value in the low order
+       // 2-bytes will result in SLIC being granted the highest thread
+       // priority upon return.  A 0 will return to SLIC as medium priority.
+       u64     plic_defer_ints_area;   // Entire Dword
+
+       // Used to pass the real SRR0/1 from PLIC to SLIC as well as to
+       // pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid.
+       u64     saved_srr0;             // Saved SRR0                   x10-x17
+       u64     saved_srr1;             // Saved SRR1                   x18-x1F
+
+       // Used to pass parms from the OS to PLIC for SetAsrAndRfid
+       u64     saved_gpr3;             // Saved GPR3                   x20-x27
+       u64     saved_gpr4;             // Saved GPR4                   x28-x2F
+       u64     saved_gpr5;             // Saved GPR5                   x30-x37
+
+       u8      reserved4;              // Reserved                     x38-x38
+       u8      cpuctls_task_attrs;     // Task attributes for cpuctls  x39-x39
+       u8      fpregs_in_use;          // FP regs in use               x3A-x3A
+       u8      pmcregs_in_use;         // PMC regs in use              x3B-x3B
+       volatile u32 saved_decr;        // Saved Decr Value             x3C-x3F
+       volatile u64 emulated_time_base;// Emulated TB for this thread  x40-x47
+       volatile u64 cur_plic_latency;  // Unaccounted PLIC latency     x48-x4F
+       u64     tot_plic_latency;       // Accumulated PLIC latency     x50-x57
+       u64     wait_state_cycles;      // Wait cycles for this proc    x58-x5F
+       u64     end_of_quantum;         // TB at end of quantum         x60-x67
+       u64     pdc_saved_sprg1;        // Saved SPRG1 for PMC int      x68-x6F
+       u64     pdc_saved_srr0;         // Saved SRR0 for PMC int       x70-x77
+       volatile u32 virtual_decr;      // Virtual DECR for shared procsx78-x7B
+       u16     slb_count;              // # of SLBs to maintain        x7C-x7D
+       u8      idle;                   // Indicate OS is idle          x7E
+       u8      vmxregs_in_use;         // VMX registers in use         x7F
+
+
+//=============================================================================
+// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
+//=============================================================================
+       // This is the yield_count.  An "odd" value (low bit on) means that
+       // the processor is yielded (either because of an OS yield or a PLIC
+       // preempt).  An even value implies that the processor is currently
+       // executing.
+       // NOTE: This value will ALWAYS be zero for dedicated processors and
+       // will NEVER be zero for shared processors (ie, initialized to a 1).
+       volatile u32 yield_count;       // PLIC increments each dispatchx00-x03
+       u8      reserved6[124];         // Reserved                     x04-x7F
+
+//=============================================================================
+// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
+//=============================================================================
+       u8      pmc_save_area[256];     // PMC interrupt Area           x00-xFF
+};
+
+#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
new file mode 100644 (file)
index 0000000..92c765c
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * include/asm-powerpc/paca.h
+ *
+ * This control block defines the PACA which defines the processor
+ * specific data for each logical processor on the system.
+ * There are some pointers defined that are utilized by PLIC.
+ *
+ * C 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ */
+#ifndef _ASM_POWERPC_PACA_H
+#define _ASM_POWERPC_PACA_H
+
+#include       <linux/config.h>
+#include       <asm/types.h>
+#include       <asm/lppaca.h>
+#include       <asm/iseries/it_lp_reg_save.h>
+#include       <asm/mmu.h>
+
+register struct paca_struct *local_paca asm("r13");
+#define get_paca()     local_paca
+
+struct task_struct;
+
+/*
+ * Defines the layout of the paca.
+ *
+ * This structure is not directly accessed by firmware or the service
+ * processor except for the first two pointers that point to the
+ * lppaca area and the ItLpRegSave area for this CPU.  Both the
+ * lppaca and ItLpRegSave objects are currently contained within the
+ * PACA but they do not need to be.
+ */
+struct paca_struct {
+       /*
+        * Because hw_cpu_id, unlike other paca fields, is accessed
+        * routinely from other CPUs (from the IRQ code), we stick to
+        * read-only (after boot) fields in the first cacheline to
+        * avoid cacheline bouncing.
+        */
+
+       /*
+        * MAGIC: These first two pointers can't be moved - they're
+        * accessed by the firmware
+        */
+       struct lppaca *lppaca_ptr;      /* Pointer to LpPaca for PLIC */
+       struct ItLpRegSave *reg_save_ptr; /* Pointer to LpRegSave for PLIC */
+
+       /*
+        * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c
+        * load lock_token and paca_index with a single lwz
+        * instruction.  They must travel together and be properly
+        * aligned.
+        */
+       u16 lock_token;                 /* Constant 0x8000, used in locks */
+       u16 paca_index;                 /* Logical processor number */
+
+       u32 default_decr;               /* Default decrementer value */
+       u64 kernel_toc;                 /* Kernel TOC address */
+       u64 stab_real;                  /* Absolute address of segment table */
+       u64 stab_addr;                  /* Virtual address of segment table */
+       void *emergency_sp;             /* pointer to emergency stack */
+       s16 hw_cpu_id;                  /* Physical processor number */
+       u8 cpu_start;                   /* At startup, processor spins until */
+                                       /* this becomes non-zero. */
+
+       /*
+        * Now, starting in cacheline 2, the exception save areas
+        */
+       /* used for most interrupts/exceptions */
+       u64 exgen[10] __attribute__((aligned(0x80)));
+       u64 exmc[10];           /* used for machine checks */
+       u64 exslb[10];          /* used for SLB/segment table misses
+                                * on the linear mapping */
+#ifdef CONFIG_PPC_64K_PAGES
+       pgd_t *pgdir;
+#endif /* CONFIG_PPC_64K_PAGES */
+
+       mm_context_t context;
+       u16 slb_cache[SLB_CACHE_ENTRIES];
+       u16 slb_cache_ptr;
+
+       /*
+        * then miscellaneous read-write fields
+        */
+       struct task_struct *__current;  /* Pointer to current */
+       u64 kstack;                     /* Saved Kernel stack addr */
+       u64 stab_rr;                    /* stab/slb round-robin counter */
+       u64 next_jiffy_update_tb;       /* TB value for next jiffy update */
+       u64 saved_r1;                   /* r1 save for RTAS calls */
+       u64 saved_msr;                  /* MSR saved here by enter_rtas */
+       u8 proc_enabled;                /* irq soft-enable flag */
+
+       /* not yet used */
+       u64 exdsi[8];           /* used for linear mapping hash table misses */
+
+       /*
+        * iSeries structure which the hypervisor knows about -
+        * this structure should not cross a page boundary.
+        * The vpa_init/register_vpa call is now known to fail if the
+        * lppaca structure crosses a page boundary.
+        * The lppaca is also used on POWER5 pSeries boxes.
+        * The lppaca is 640 bytes long, and cannot readily change
+        * since the hypervisor knows its layout, so a 1kB
+        * alignment will suffice to ensure that it doesn't
+        * cross a page boundary.
+        */
+       struct lppaca lppaca __attribute__((__aligned__(0x400)));
+#ifdef CONFIG_PPC_ISERIES
+       struct ItLpRegSave reg_save;
+#endif
+};
+
+extern struct paca_struct paca[];
+
+#endif /* _ASM_POWERPC_PACA_H */
index 13aacff755f383ab21c2f7c997fdf10187a21f25..9896fade98a74999cd9c298d029cfac5090f66fd 100644 (file)
@@ -26,6 +26,10 @@ extern unsigned long find_and_init_phbs(void);
 
 extern struct pci_dev *ppc64_isabridge_dev;    /* may be NULL if no ISA bus */
 
+/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
+#define BUID_HI(buid) ((buid) >> 32)
+#define BUID_LO(buid) ((buid) & 0xffffffff)
+
 /* PCI device_node operations */
 struct device_node;
 typedef void *(*traverse_func)(struct device_node *me, void *data);
@@ -36,10 +40,6 @@ void pci_devs_phb_init(void);
 void pci_devs_phb_init_dynamic(struct pci_controller *phb);
 void __devinit scan_phb(struct pci_controller *hose);
 
-/* PCI address cache management routines */
-void pci_addr_cache_insert_device(struct pci_dev *dev);
-void pci_addr_cache_remove_device(struct pci_dev *dev);
-
 /* From rtas_pci.h */
 void init_pci_config_tokens (void);
 unsigned long get_phb_buid (struct device_node *);
@@ -52,4 +52,48 @@ extern unsigned long pci_probe_only;
 extern unsigned long pci_assign_all_buses;
 extern int pci_read_irq_line(struct pci_dev *pci_dev);
 
+/* ---- EEH internal-use-only related routines ---- */
+#ifdef CONFIG_EEH
+/**
+ * rtas_set_slot_reset -- unfreeze a frozen slot
+ *
+ * Clear the EEH-frozen condition on a slot.  This routine
+ * does this by asserting the PCI #RST line for 1/8th of
+ * a second; this routine will sleep while the adapter is
+ * being reset.
+ */
+void rtas_set_slot_reset (struct pci_dn *);
+
+/** 
+ * eeh_restore_bars - Restore device configuration info.
+ *
+ * A reset of a PCI device will clear out its config space.
+ * This routines will restore the config space for this
+ * device, and is children, to values previously obtained
+ * from the firmware.
+ */
+void eeh_restore_bars(struct pci_dn *);
+
+/**
+ * rtas_configure_bridge -- firmware initialization of pci bridge
+ *
+ * Ask the firmware to configure all PCI bridges devices
+ * located behind the indicated node. Required after a
+ * pci device reset. Does essentially the same hing as
+ * eeh_restore_bars, but for brdges, and lets firmware 
+ * do the work.
+ */
+void rtas_configure_bridge(struct pci_dn *);
+
+int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
+
+/**
+ * mark and clear slots: find "partition endpoint" PE and set or 
+ * clear the flags for each subnode of the PE.
+ */
+void eeh_mark_slot (struct device_node *dn, int mode_flag);
+void eeh_clear_slot (struct device_node *dn, int mode_flag);
+
+#endif
+
 #endif /* _ASM_POWERPC_PPC_PCI_H */
index c534ca41224b6cea93d31fd29fdba6445da5dcbc..c27baa0563feaa4020b330a29b480f2748aac9e2 100644 (file)
@@ -6,8 +6,13 @@
 
 #include <linux/stringify.h>
 #include <linux/config.h>
+#include <asm/asm-compat.h>
 
-#ifdef __ASSEMBLY__
+#ifndef __ASSEMBLY__
+#error __FILE__ should only be used in assembler files
+#else
+
+#define SZL                    (BITS_PER_LONG/8)
 
 /*
  * Macros for storing registers into and loading registers from
@@ -184,12 +189,6 @@ n:
        oris    reg,reg,(label)@h;                      \
        ori     reg,reg,(label)@l;
 
-/* operations for longs and pointers */
-#define LDL    ld
-#define STL    std
-#define CMPI   cmpdi
-#define SZL    8
-
 /* offsets for stack frame layout */
 #define LRSAVE 16
 
@@ -203,12 +202,6 @@ n:
 
 #define OFF(name)      name@l
 
-/* operations for longs and pointers */
-#define LDL    lwz
-#define STL    stw
-#define CMPI   cmpwi
-#define SZL    4
-
 /* offsets for stack frame layout */
 #define LRSAVE 4
 
@@ -266,15 +259,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #endif
 
 
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb)    dcbt    ra, rb;
-#define        PPC405_ERR77_SYNC       sync;
-#else
-#define PPC405_ERR77(ra,rb)
-#define PPC405_ERR77_SYNC
-#endif
-
-
 #ifdef CONFIG_IBM440EP_ERR42
 #define PPC440EP_ERR42 isync
 #else
@@ -502,17 +486,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define N_SLINE        68
 #define N_SO   100
 
-#define ASM_CONST(x) x
-#else
-  #define __ASM_CONST(x) x##UL
-  #define ASM_CONST(x) __ASM_CONST(x)
-
-#ifdef CONFIG_PPC64
-#define DATAL  ".llong"
-#else
-#define DATAL  ".long"
-#endif
-
 #endif /*  __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_PPC_ASM_H */
index 1dc4bf7b52b302533b2909ff688d883816cf1b9a..f6f186b56b0f57966733f945db65fd42525232d5 100644 (file)
 #include <linux/compiler.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
-#ifdef CONFIG_PPC64
-#include <asm/systemcfg.h>
-#endif
 
-#ifdef CONFIG_PPC32
-/* 32-bit platform types */
-/* We only need to define a new _MACH_xxx for machines which are part of
- * a configuration which supports more than one type of different machine.
- * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
- * -- Tom
+/* We do _not_ want to define new machine types at all, those must die
+ * in favor of using the device-tree
+ * -- BenH.
  */
-#define _MACH_prep     0x00000001
-#define _MACH_Pmac     0x00000002      /* pmac or pmac clone (non-chrp) */
-#define _MACH_chrp     0x00000004      /* chrp machine */
 
-/* see residual.h for these */
+/* Platforms codes (to be obsoleted) */
+#define PLATFORM_PSERIES       0x0100
+#define PLATFORM_PSERIES_LPAR  0x0101
+#define PLATFORM_ISERIES_LPAR  0x0201
+#define PLATFORM_LPAR          0x0001
+#define PLATFORM_POWERMAC      0x0400
+#define PLATFORM_MAPLE         0x0500
+#define PLATFORM_PREP          0x0600
+#define PLATFORM_CHRP          0x0700
+#define PLATFORM_CELL          0x1000
+
+/* Compat platform codes for 32 bits */
+#define _MACH_prep     PLATFORM_PREP
+#define _MACH_Pmac     PLATFORM_POWERMAC
+#define _MACH_chrp     PLATFORM_CHRP
+
+/* PREP sub-platform types see residual.h for these */
 #define _PREP_Motorola 0x01    /* motorola prep */
 #define _PREP_Firm     0x02    /* firmworks prep */
 #define _PREP_IBM      0x00    /* ibm prep */
 #define _PREP_Bull     0x03    /* bull prep */
 
-/* these are arbitrary */
+/* CHRP sub-platform types. These are arbitrary */
 #define _CHRP_Motorola 0x04    /* motorola chrp, the cobra */
 #define _CHRP_IBM      0x05    /* IBM chrp, the longtrail and longtrail 2 */
 #define _CHRP_Pegasos  0x06    /* Genesi/bplan's Pegasos and Pegasos2 */
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#define platform_is_pseries()  (_machine == PLATFORM_PSERIES || \
+                                _machine == PLATFORM_PSERIES_LPAR)
+#define platform_is_lpar()     (!!(_machine & PLATFORM_LPAR))
+
+#if defined(CONFIG_PPC_MULTIPLATFORM)
 extern int _machine;
 
+#ifdef CONFIG_PPC32
+
 /* what kind of prep workstation we are */
 extern int _prep_type;
 extern int _chrp_type;
 
 /*
  * This is used to identify the board type from a given PReP board
- * vendor. Board revision is also made available.
+ * vendor. Board revision is also made available. This will be moved
+ * elsewhere soon
  */
 extern unsigned char ucSystemType;
 extern unsigned char ucBoardRev;
 extern unsigned char ucBoardRevMaj, ucBoardRevMin;
+
+#endif /* CONFIG_PPC32 */
+
+#elif defined(CONFIG_PPC_ISERIES)
+/*
+ * iSeries is soon to become MULTIPLATFORM hopefully ...
+ */
+#define _machine PLATFORM_ISERIES_LPAR
 #else
 #define _machine 0
 #endif /* CONFIG_PPC_MULTIPLATFORM */
-#endif /* CONFIG_PPC32 */
-
-#ifdef CONFIG_PPC64
-/* Platforms supported by PPC64 */
-#define PLATFORM_PSERIES      0x0100
-#define PLATFORM_PSERIES_LPAR 0x0101
-#define PLATFORM_ISERIES_LPAR 0x0201
-#define PLATFORM_LPAR         0x0001
-#define PLATFORM_POWERMAC     0x0400
-#define PLATFORM_MAPLE        0x0500
-#define PLATFORM_CELL         0x1000
-
-/* Compatibility with drivers coming from PPC32 world */
-#define _machine       (systemcfg->platform)
-#define _MACH_Pmac     PLATFORM_POWERMAC
-#endif
 
 /*
  * Default implementation of macro that returns current
index 489cf4c99c21470c7856856aa6f4a8c3377a4083..eb392d038ed7dacdaea492f65f6311494bed17cd 100644 (file)
 /* Pickup Book E specific registers. */
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 #include <asm/reg_booke.h>
-#endif
+#endif /* CONFIG_BOOKE || CONFIG_40x */
+
+#ifdef CONFIG_8xx
+#include <asm/reg_8xx.h>
+#endif /* CONFIG_8xx */
 
 #define MSR_SF_LG      63              /* Enable 64 bit mode */
 #define MSR_ISF_LG     61              /* Interrupt 64b mode valid on 630 */
 #define SPRN_RPA       0x3D6   /* Required Physical Address Register */
 #define SPRN_SDA       0x3BF   /* Sampled Data Address Register */
 #define SPRN_SDR1      0x019   /* MMU Hash Base Register */
+#define SPRN_ASR       0x118   /* Address Space Register */
 #define SPRN_SIA       0x3BB   /* Sampled Instruction Address Register */
 #define SPRN_SPRG0     0x110   /* Special Purpose Register General 0 */
 #define SPRN_SPRG1     0x111   /* Special Purpose Register General 1 */
diff --git a/include/asm-powerpc/reg_8xx.h b/include/asm-powerpc/reg_8xx.h
new file mode 100644 (file)
index 0000000..e8ea346
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Contains register definitions common to PowerPC 8xx CPUs.  Notice
+ */
+#ifndef _ASM_POWERPC_REG_8xx_H
+#define _ASM_POWERPC_REG_8xx_H
+
+/* Cache control on the MPC8xx is provided through some additional
+ * special purpose registers.
+ */
+#define SPRN_IC_CST    560     /* Instruction cache control/status */
+#define SPRN_IC_ADR    561     /* Address needed for some commands */
+#define SPRN_IC_DAT    562     /* Read-only data register */
+#define SPRN_DC_CST    568     /* Data cache control/status */
+#define SPRN_DC_ADR    569     /* Address needed for some commands */
+#define SPRN_DC_DAT    570     /* Read-only data register */
+
+/* Commands.  Only the first few are available to the instruction cache.
+*/
+#define        IDC_ENABLE      0x02000000      /* Cache enable */
+#define IDC_DISABLE    0x04000000      /* Cache disable */
+#define IDC_LDLCK      0x06000000      /* Load and lock */
+#define IDC_UNLINE     0x08000000      /* Unlock line */
+#define IDC_UNALL      0x0a000000      /* Unlock all */
+#define IDC_INVALL     0x0c000000      /* Invalidate all */
+
+#define DC_FLINE       0x0e000000      /* Flush data cache line */
+#define DC_SFWT                0x01000000      /* Set forced writethrough mode */
+#define DC_CFWT                0x03000000      /* Clear forced writethrough mode */
+#define DC_SLES                0x05000000      /* Set little endian swap mode */
+#define DC_CLES                0x07000000      /* Clear little endian swap mode */
+
+/* Status.
+*/
+#define IDC_ENABLED    0x80000000      /* Cache is enabled */
+#define IDC_CERR1      0x00200000      /* Cache error 1 */
+#define IDC_CERR2      0x00100000      /* Cache error 2 */
+#define IDC_CERR3      0x00080000      /* Cache error 3 */
+
+#define DC_DFWT                0x40000000      /* Data cache is forced write through */
+#define DC_LES         0x20000000      /* Caches are little endian mode */
+
+#endif /* _ASM_POWERPC_REG_8xx_H */
diff --git a/include/asm-powerpc/signal.h b/include/asm-powerpc/signal.h
new file mode 100644 (file)
index 0000000..694c8d2
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef _ASM_POWERPC_SIGNAL_H
+#define _ASM_POWERPC_SIGNAL_H
+
+#include <linux/types.h>
+#include <linux/config.h>
+
+#define _NSIG          64
+#define _NSIG_BPW      BITS_PER_LONG
+#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;            /* at least 32 bits */
+
+typedef struct {
+       unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+#define SIGBUS          7
+#define SIGFPE          8
+#define SIGKILL                 9
+#define SIGUSR1                10
+#define SIGSEGV                11
+#define SIGUSR2                12
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGSTKFLT      16
+#define SIGCHLD                17
+#define SIGCONT                18
+#define SIGSTOP                19
+#define SIGTSTP                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGURG         23
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGIO          29
+#define SIGPOLL                SIGIO
+/*
+#define SIGLOST                29
+*/
+#define SIGPWR         30
+#define SIGSYS         31
+#define        SIGUNUSED       31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN       32
+#define SIGRTMAX       _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP   0x00000001U
+#define SA_NOCLDWAIT   0x00000002U
+#define SA_SIGINFO     0x00000004U
+#define SA_ONSTACK     0x08000000U
+#define SA_RESTART     0x10000000U
+#define SA_NODEFER     0x40000000U
+#define SA_RESETHAND   0x80000000U
+
+#define SA_NOMASK      SA_NODEFER
+#define SA_ONESHOT     SA_RESETHAND
+#define SA_INTERRUPT   0x20000000u /* dummy -- ignored */
+
+#define SA_RESTORER    0x04000000U
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+#include <asm-generic/signal.h>
+
+struct old_sigaction {
+       __sighandler_t sa_handler;
+       old_sigset_t sa_mask;
+       unsigned long sa_flags;
+       __sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+       __sighandler_t sa_handler;
+       unsigned long sa_flags;
+       __sigrestore_t sa_restorer;
+       sigset_t sa_mask;               /* mask last for extensibility */
+};
+
+struct k_sigaction {
+       struct sigaction sa;
+};
+
+typedef struct sigaltstack {
+       void __user *ss_sp;
+       int ss_flags;
+       size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+struct pt_regs;
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+#endif /* __KERNEL__ */
+
+#ifndef __powerpc64__
+/*
+ * These are parameters to dbg_sigreturn syscall.  They enable or
+ * disable certain debugging things that can be done from signal
+ * handlers.  The dbg_sigreturn syscall *must* be called from a
+ * SA_SIGINFO signal so the ucontext can be passed to it.  It takes an
+ * array of struct sig_dbg_op, which has the debug operations to
+ * perform before returning from the signal.
+ */
+struct sig_dbg_op {
+       int dbg_type;
+       unsigned long dbg_value;
+};
+
+/* Enable or disable single-stepping.  The value sets the state. */
+#define SIG_DBG_SINGLE_STEPPING                1
+
+/* Enable or disable branch tracing.  The value sets the state. */
+#define SIG_DBG_BRANCH_TRACING         2
+#endif /* ! __powerpc64__ */
+
+#endif /* _ASM_POWERPC_SIGNAL_H */
index 1c95ab99deb361615522e453268d4ddedc49a489..58d2aab416f8f21f7574acedeefaeffcf43878b8 100644 (file)
 #define MAX_PHYSADDR_BITS       38
 #define MAX_PHYSMEM_BITS        36
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+extern void create_section_mapping(unsigned long start, unsigned long end);
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
 #endif /* CONFIG_SPARSEMEM */
 
 #endif /* _ASM_POWERPC_SPARSEMEM_H */
index 3536a5cd7a2d62fdcd3df5a58be8f4cafeb87714..5341b75c75cb6937ac3372e059346fa2dc606727 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 
 #include <asm/hw_irq.h>
-#include <asm/ppc_asm.h>
 #include <asm/atomic.h>
 
 /*
@@ -180,6 +179,7 @@ extern struct task_struct *_switch(struct thread_struct *prev,
 extern unsigned int rtas_data;
 extern int mem_init_done;      /* set on boot once kmalloc can be called */
 extern unsigned long memory_limit;
+extern unsigned long klimit;
 
 extern int powersave_nap;      /* set if nap mode can be used in idle loop */
 
diff --git a/include/asm-powerpc/systemcfg.h b/include/asm-powerpc/systemcfg.h
new file mode 100644 (file)
index 0000000..36b5cbe
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _SYSTEMCFG_H
+#define _SYSTEMCFG_H
+
+/*
+ * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Change Activity:
+ * 2002/09/30 : bergner  : Created
+ * End Change Activity
+ */
+
+/*
+ * If the major version changes we are incompatible.
+ * Minor version changes are a hint.
+ */
+#define SYSTEMCFG_MAJOR 1
+#define SYSTEMCFG_MINOR 1
+
+#ifndef __ASSEMBLY__
+
+#include <linux/unistd.h>
+
+#define SYSCALL_MAP_SIZE      ((__NR_syscalls + 31) / 32)
+
+struct systemcfg {
+       __u8  eye_catcher[16];          /* Eyecatcher: SYSTEMCFG:PPC64  0x00 */
+       struct {                        /* Systemcfg version numbers         */
+               __u32 major;            /* Major number                 0x10 */
+               __u32 minor;            /* Minor number                 0x14 */
+       } version;
+
+       __u32 platform;                 /* Platform flags               0x18 */
+       __u32 processor;                /* Processor type               0x1C */
+       __u64 processorCount;           /* # of physical processors     0x20 */
+       __u64 physicalMemorySize;       /* Size of real memory(B)       0x28 */
+       __u64 tb_orig_stamp;            /* Timebase at boot             0x30 */
+       __u64 tb_ticks_per_sec;         /* Timebase tics / sec          0x38 */
+       __u64 tb_to_xs;                 /* Inverse of TB to 2^20        0x40 */
+       __u64 stamp_xsec;               /*                              0x48 */
+       __u64 tb_update_count;          /* Timebase atomicity ctr       0x50 */
+       __u32 tz_minuteswest;           /* Minutes west of Greenwich    0x58 */
+       __u32 tz_dsttime;               /* Type of dst correction       0x5C */
+       /* next four are no longer used except to be exported to /proc */
+       __u32 dcache_size;              /* L1 d-cache size              0x60 */
+       __u32 dcache_line_size;         /* L1 d-cache line size         0x64 */
+       __u32 icache_size;              /* L1 i-cache size              0x68 */
+       __u32 icache_line_size;         /* L1 i-cache line size         0x6C */
+       __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of available syscalls 0x70 */
+       __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of available syscalls */
+};
+
+#ifdef __KERNEL__
+extern struct systemcfg *_systemcfg; /* to be renamed */
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _SYSTEMCFG_H */
diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h
new file mode 100644 (file)
index 0000000..d099d52
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ * Rewrite, cleanup:
+ * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _ASM_POWERPC_TCE_H
+#define _ASM_POWERPC_TCE_H
+
+/*
+ * Tces come in two formats, one for the virtual bus and a different
+ * format for PCI
+ */
+#define TCE_VB  0
+#define TCE_PCI 1
+
+/* TCE page size is 4096 bytes (1 << 12) */
+
+#define TCE_SHIFT      12
+#define TCE_PAGE_SIZE  (1 << TCE_SHIFT)
+#define TCE_PAGE_FACTOR        (PAGE_SHIFT - TCE_SHIFT)
+
+
+/* tce_entry
+ * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
+ * abstracted so layout is irrelevant.
+ */
+union tce_entry {
+       unsigned long te_word;
+       struct {
+               unsigned int  tb_cacheBits :6;  /* Cache hash bits - not used */
+               unsigned int  tb_rsvd      :6;
+               unsigned long tb_rpn       :40; /* Real page number */
+               unsigned int  tb_valid     :1;  /* Tce is valid (vb only) */
+               unsigned int  tb_allio     :1;  /* Tce is valid for all lps (vb only) */
+               unsigned int  tb_lpindex   :8;  /* LpIndex for user of TCE (vb only) */
+               unsigned int  tb_pciwr     :1;  /* Write allowed (pci only) */
+               unsigned int  tb_rdwr      :1;  /* Read allowed  (pci), Write allowed (vb) */
+       } te_bits;
+#define te_cacheBits te_bits.tb_cacheBits
+#define te_rpn       te_bits.tb_rpn
+#define te_valid     te_bits.tb_valid
+#define te_allio     te_bits.tb_allio
+#define te_lpindex   te_bits.tb_lpindex
+#define te_pciwr     te_bits.tb_pciwr
+#define te_rdwr      te_bits.tb_rdwr
+};
+
+
+#endif /* _ASM_POWERPC_TCE_H */
index 33af730f0d198e8e973231154b9787bfec934443..3872e924cdd6f7c6fca25a8983467d80e47dc79c 100644 (file)
@@ -120,14 +120,6 @@ struct exception_table_entry {
 
 extern long __put_user_bad(void);
 
-#ifdef __powerpc64__
-#define __EX_TABLE_ALIGN       "3"
-#define __EX_TABLE_TYPE                "llong"
-#else
-#define __EX_TABLE_ALIGN       "2"
-#define __EX_TABLE_TYPE                "long"
-#endif
-
 /*
  * We don't tell gcc that we are accessing memory, but this is OK
  * because we do not write to any memory gcc knows about, so there
@@ -142,11 +134,12 @@ extern long __put_user_bad(void);
                "       b 2b\n"                                 \
                ".previous\n"                                   \
                ".section __ex_table,\"a\"\n"                   \
-               "       .align " __EX_TABLE_ALIGN "\n"          \
-               "       ."__EX_TABLE_TYPE" 1b,3b\n"             \
+               "       .balign %5\n"                           \
+                       PPC_LONG "1b,3b\n"                      \
                ".previous"                                     \
                : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
+                 "i"(sizeof(unsigned long)))
 
 #ifdef __powerpc64__
 #define __put_user_asm2(x, ptr, retval)                                \
@@ -162,12 +155,13 @@ extern long __put_user_bad(void);
                "       b 3b\n"                                 \
                ".previous\n"                                   \
                ".section __ex_table,\"a\"\n"                   \
-               "       .align " __EX_TABLE_ALIGN "\n"          \
-               "       ." __EX_TABLE_TYPE " 1b,4b\n"           \
-               "       ." __EX_TABLE_TYPE " 2b,4b\n"           \
+               "       .balign %5\n"                           \
+                       PPC_LONG "1b,4b\n"                      \
+                       PPC_LONG "2b,4b\n"                      \
                ".previous"                                     \
                : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
+                 "i"(sizeof(unsigned long)))
 #endif /* __powerpc64__ */
 
 #define __put_user_size(x, ptr, size, retval)                  \
@@ -213,11 +207,12 @@ extern long __get_user_bad(void);
                "       b 2b\n"                         \
                ".previous\n"                           \
                ".section __ex_table,\"a\"\n"           \
-               "       .align "__EX_TABLE_ALIGN "\n"   \
-               "       ." __EX_TABLE_TYPE " 1b,3b\n"   \
+               "       .balign %5\n"                   \
+                       PPC_LONG "1b,3b\n"              \
                ".previous"                             \
                : "=r" (err), "=r" (x)                  \
-               : "b" (addr), "i" (-EFAULT), "0" (err))
+               : "b" (addr), "i" (-EFAULT), "0" (err), \
+                 "i"(sizeof(unsigned long)))
 
 #ifdef __powerpc64__
 #define __get_user_asm2(x, addr, err)                  \
@@ -235,12 +230,13 @@ extern long __get_user_bad(void);
                "       b 3b\n"                         \
                ".previous\n"                           \
                ".section __ex_table,\"a\"\n"           \
-               "       .align " __EX_TABLE_ALIGN "\n"  \
-               "       ." __EX_TABLE_TYPE " 1b,4b\n"   \
-               "       ." __EX_TABLE_TYPE " 2b,4b\n"   \
+               "       .balign %5\n"                   \
+                       PPC_LONG "1b,4b\n"              \
+                       PPC_LONG "2b,4b\n"              \
                ".previous"                             \
                : "=r" (err), "=&r" (x)                 \
-               : "b" (addr), "i" (-EFAULT), "0" (err))
+               : "b" (addr), "i" (-EFAULT), "0" (err), \
+                 "i"(sizeof(unsigned long)))
 #endif /* __powerpc64__ */
 
 #define __get_user_size(x, ptr, size, retval)                  \
index ace2072d4a833fd331ded2e13be7cf7bd1d8a556..43f7129984c723312c3ca394ccf32fe53d52a4e8 100644 (file)
@@ -7,7 +7,6 @@ struct pt_regs;
 extern int xmon(struct pt_regs *excp);
 extern void xmon_printf(const char *fmt, ...);
 extern void xmon_init(int);
-extern void xmon_map_scc(void);
 
 #endif
 #endif
diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
deleted file mode 100644 (file)
index 7a157d0..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * include/asm-ppc/cache.h
- */
-#ifdef __KERNEL__
-#ifndef __ARCH_PPC_CACHE_H
-#define __ARCH_PPC_CACHE_H
-
-#include <linux/config.h>
-
-/* bytes per L1 cache line */
-#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
-#define L1_CACHE_SHIFT 4
-#define MAX_COPY_PREFETCH      1
-#elif defined(CONFIG_PPC64BRIDGE)
-#define L1_CACHE_SHIFT 7
-#define MAX_COPY_PREFETCH      1
-#else
-#define L1_CACHE_SHIFT 5
-#define MAX_COPY_PREFETCH      4
-#endif
-
-#define        L1_CACHE_BYTES  (1 << L1_CACHE_SHIFT)
-
-#define        SMP_CACHE_BYTES L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX 7   /* largest L1 which this arch supports */
-
-#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-#define        L1_CACHE_PAGES          8
-
-#ifndef __ASSEMBLY__
-extern void clean_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_all(void);
-#endif /* __ASSEMBLY__ */
-
-/* prep registers for L2 */
-#define CACHECRBA       0x80000823      /* Cache configuration register address */
-#define L2CACHE_MASK   0x03    /* Mask for 2 L2 Cache bits */
-#define L2CACHE_512KB  0x00    /* 512KB */
-#define L2CACHE_256KB  0x01    /* 256KB */
-#define L2CACHE_1MB    0x02    /* 1MB */
-#define L2CACHE_NONE   0x03    /* NONE */
-#define L2CACHE_PARITY  0x08    /* Mask for L2 Cache Parity Protected bit */
-
-#ifdef CONFIG_8xx
-/* Cache control on the MPC8xx is provided through some additional
- * special purpose registers.
- */
-#define SPRN_IC_CST    560     /* Instruction cache control/status */
-#define SPRN_IC_ADR    561     /* Address needed for some commands */
-#define SPRN_IC_DAT    562     /* Read-only data register */
-#define SPRN_DC_CST    568     /* Data cache control/status */
-#define SPRN_DC_ADR    569     /* Address needed for some commands */
-#define SPRN_DC_DAT    570     /* Read-only data register */
-
-/* Commands.  Only the first few are available to the instruction cache.
-*/
-#define        IDC_ENABLE      0x02000000      /* Cache enable */
-#define IDC_DISABLE    0x04000000      /* Cache disable */
-#define IDC_LDLCK      0x06000000      /* Load and lock */
-#define IDC_UNLINE     0x08000000      /* Unlock line */
-#define IDC_UNALL      0x0a000000      /* Unlock all */
-#define IDC_INVALL     0x0c000000      /* Invalidate all */
-
-#define DC_FLINE       0x0e000000      /* Flush data cache line */
-#define DC_SFWT                0x01000000      /* Set forced writethrough mode */
-#define DC_CFWT                0x03000000      /* Clear forced writethrough mode */
-#define DC_SLES                0x05000000      /* Set little endian swap mode */
-#define DC_CLES                0x07000000      /* Clear little endian swap mode */
-
-/* Status.
-*/
-#define IDC_ENABLED    0x80000000      /* Cache is enabled */
-#define IDC_CERR1      0x00200000      /* Cache error 1 */
-#define IDC_CERR2      0x00100000      /* Cache error 2 */
-#define IDC_CERR3      0x00080000      /* Cache error 3 */
-
-#define DC_DFWT                0x40000000      /* Data cache is forced write through */
-#define DC_LES         0x20000000      /* Caches are little endian mode */
-#endif /* CONFIG_8xx */
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/cacheflush.h b/include/asm-ppc/cacheflush.h
deleted file mode 100644 (file)
index 6a243ef..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * include/asm-ppc/cacheflush.h
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-#ifdef __KERNEL__
-#ifndef _PPC_CACHEFLUSH_H
-#define _PPC_CACHEFLUSH_H
-
-#include <linux/mm.h>
-
-/*
- * No cache flushing is required when address mappings are
- * changed, because the caches on PowerPCs are physically
- * addressed.  -- paulus
- * Also, when SMP we use the coherency (M) bit of the
- * BATs and PTEs.  -- Cort
- */
-#define flush_cache_all()              do { } while (0)
-#define flush_cache_mm(mm)             do { } while (0)
-#define flush_cache_range(vma, a, b)   do { } while (0)
-#define flush_cache_page(vma, p, pfn)  do { } while (0)
-#define flush_icache_page(vma, page)   do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-extern void flush_dcache_page(struct page *page);
-#define flush_dcache_mmap_lock(mapping)                do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
-
-extern void flush_icache_range(unsigned long, unsigned long);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
-               struct page *page, unsigned long addr, int len);
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
-     flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-       memcpy(dst, src, len)
-
-extern void __flush_dcache_icache(void *page_va);
-extern void __flush_dcache_icache_phys(unsigned long physaddr);
-extern void flush_dcache_icache_page(struct page *page);
-#endif /* _PPC_CACHEFLUSH_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h
deleted file mode 100644 (file)
index 8d41501..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_CURRENT_H
-#define _PPC_CURRENT_H
-
-/*
- * We keep `current' in r2 for speed.
- */
-register struct task_struct *current asm ("r2");
-
-#endif /* !(_PPC_CURRENT_H) */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h
deleted file mode 100644 (file)
index caf6ede..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef _ASMPPC_SIGNAL_H
-#define _ASMPPC_SIGNAL_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#endif /* __KERNEL__ */
-
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-
-/* Most things should be clean enough to redefine this at will, if care
-   is taken to make libc match.  */
-
-#define _NSIG          64
-#define _NSIG_BPW      32
-#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t;            /* at least 32 bits */
-
-typedef struct {
-       unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-#define SIGBUS          7
-#define SIGFPE          8
-#define SIGKILL                 9
-#define SIGUSR1                10
-#define SIGSEGV                11
-#define SIGUSR2                12
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGSTKFLT      16
-#define SIGCHLD                17
-#define SIGCONT                18
-#define SIGSTOP                19
-#define SIGTSTP                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGURG         23
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGIO          29
-#define SIGPOLL                SIGIO
-/*
-#define SIGLOST                29
-*/
-#define SIGPWR         30
-#define SIGSYS         31
-#define        SIGUNUSED       31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN       32
-#define SIGRTMAX       _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP   0x00000001
-#define SA_NOCLDWAIT   0x00000002
-#define SA_SIGINFO     0x00000004
-#define SA_ONSTACK     0x08000000
-#define SA_RESTART     0x10000000
-#define SA_NODEFER     0x40000000
-#define SA_RESETHAND   0x80000000
-
-#define SA_NOMASK      SA_NODEFER
-#define SA_ONESHOT     SA_RESETHAND
-#define SA_INTERRUPT   0x20000000 /* dummy -- ignored */
-
-#define SA_RESTORER    0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    2048
-#define SIGSTKSZ       8192
-
-#include <asm-generic/signal.h>
-
-struct old_sigaction {
-       __sighandler_t sa_handler;
-       old_sigset_t sa_mask;
-       unsigned long sa_flags;
-       __sigrestore_t sa_restorer;
-};
-
-struct sigaction {
-       __sighandler_t sa_handler;
-       unsigned long sa_flags;
-       __sigrestore_t sa_restorer;
-       sigset_t sa_mask;               /* mask last for extensibility */
-};
-
-struct k_sigaction {
-       struct sigaction sa;
-};
-
-typedef struct sigaltstack {
-       void __user *ss_sp;
-       int ss_flags;
-       size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
-#include <asm/sigcontext.h>
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
-/*
- * These are parameters to dbg_sigreturn syscall.  They enable or
- * disable certain debugging things that can be done from signal
- * handlers.  The dbg_sigreturn syscall *must* be called from a
- * SA_SIGINFO signal so the ucontext can be passed to it.  It takes an
- * array of struct sig_dbg_op, which has the debug operations to
- * perform before returning from the signal.
- */
-struct sig_dbg_op {
-       int dbg_type;
-       unsigned long dbg_value;
-};
-
-/* Enable or disable single-stepping.  The value sets the state. */
-#define SIG_DBG_SINGLE_STEPPING                1
-
-/* Enable or disable branch tracing.  The value sets the state. */
-#define SIG_DBG_BRANCH_TRACING         2
-
-#endif
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-ppc64/abs_addr.h
deleted file mode 100644 (file)
index dc3fc3f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _ABS_ADDR_H
-#define _ABS_ADDR_H
-
-#include <linux/config.h>
-
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * 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 <asm/types.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/firmware.h>
-
-struct mschunks_map {
-        unsigned long num_chunks;
-        unsigned long chunk_size;
-        unsigned long chunk_shift;
-        unsigned long chunk_mask;
-        u32 *mapping;
-};
-
-extern struct mschunks_map mschunks_map;
-
-/* Chunks are 256 KB */
-#define MSCHUNKS_CHUNK_SHIFT   (18)
-#define MSCHUNKS_CHUNK_SIZE    (1UL << MSCHUNKS_CHUNK_SHIFT)
-#define MSCHUNKS_OFFSET_MASK   (MSCHUNKS_CHUNK_SIZE - 1)
-
-static inline unsigned long chunk_to_addr(unsigned long chunk)
-{
-       return chunk << MSCHUNKS_CHUNK_SHIFT;
-}
-
-static inline unsigned long addr_to_chunk(unsigned long addr)
-{
-       return addr >> MSCHUNKS_CHUNK_SHIFT;
-}
-
-static inline unsigned long phys_to_abs(unsigned long pa)
-{
-       unsigned long chunk;
-
-       /* This is a no-op on non-iSeries */
-       if (!firmware_has_feature(FW_FEATURE_ISERIES))
-               return pa;
-
-       chunk = addr_to_chunk(pa);
-
-       if (chunk < mschunks_map.num_chunks)
-               chunk = mschunks_map.mapping[chunk];
-
-       return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK);
-}
-
-/* Convenience macros */
-#define virt_to_abs(va) phys_to_abs(__pa(va))
-#define abs_to_virt(aa) __va(aa)
-
-/*
- * Converts Virtual Address to Real Address for
- * Legacy iSeries Hypervisor calls
- */
-#define iseries_hv_addr(virtaddr)      \
-       (0x8000000000000000 | virt_to_abs(virtaddr))
-
-#endif /* _ABS_ADDR_H */
diff --git a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h
deleted file mode 100644 (file)
index 92140a7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-#ifndef __ARCH_PPC64_CACHE_H
-#define __ARCH_PPC64_CACHE_H
-
-#include <asm/types.h>
-
-/* bytes per L1 cache line */
-#define L1_CACHE_SHIFT 7
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX 7   /* largest L1 which this arch supports */
-
-#ifndef __ASSEMBLY__
-
-struct ppc64_caches {
-       u32     dsize;                  /* L1 d-cache size */
-       u32     dline_size;             /* L1 d-cache line size */
-       u32     log_dline_size;
-       u32     dlines_per_page;
-       u32     isize;                  /* L1 i-cache size */
-       u32     iline_size;             /* L1 i-cache line size */
-       u32     log_iline_size;
-       u32     ilines_per_page;
-};
-
-extern struct ppc64_caches ppc64_caches;
-
-#endif
-
-#endif
diff --git a/include/asm-ppc64/cacheflush.h b/include/asm-ppc64/cacheflush.h
deleted file mode 100644 (file)
index ffbc08b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef _PPC64_CACHEFLUSH_H
-#define _PPC64_CACHEFLUSH_H
-
-#include <linux/mm.h>
-#include <asm/cputable.h>
-
-/*
- * No cache flushing is required when address mappings are
- * changed, because the caches on PowerPCs are physically
- * addressed.
- */
-#define flush_cache_all()                      do { } while (0)
-#define flush_cache_mm(mm)                     do { } while (0)
-#define flush_cache_range(vma, start, end)     do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
-#define flush_icache_page(vma, page)           do { } while (0)
-#define flush_cache_vmap(start, end)           do { } while (0)
-#define flush_cache_vunmap(start, end)         do { } while (0)
-
-extern void flush_dcache_page(struct page *page);
-#define flush_dcache_mmap_lock(mapping)                do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
-
-extern void __flush_icache_range(unsigned long, unsigned long);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
-                                   struct page *page, unsigned long addr,
-                                   int len);
-
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
-extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
-     flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-       memcpy(dst, src, len)
-
-extern void __flush_dcache_icache(void *page_va);
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-       if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-               __flush_icache_range(start, stop);
-}
-
-#endif /* _PPC64_CACHEFLUSH_H */
diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
deleted file mode 100644 (file)
index 6ec62cd..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-#ifndef _ASM_PPC64_COMPAT_H
-#define _ASM_PPC64_COMPAT_H
-/*
- * Architecture specific compatibility types
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-
-#define COMPAT_USER_HZ 100
-
-typedef u32            compat_size_t;
-typedef s32            compat_ssize_t;
-typedef s32            compat_time_t;
-typedef s32            compat_clock_t;
-typedef s32            compat_pid_t;
-typedef u32            __compat_uid_t;
-typedef u32            __compat_gid_t;
-typedef u32            __compat_uid32_t;
-typedef u32            __compat_gid32_t;
-typedef u32            compat_mode_t;
-typedef u32            compat_ino_t;
-typedef u32            compat_dev_t;
-typedef s32            compat_off_t;
-typedef s64            compat_loff_t;
-typedef s16            compat_nlink_t;
-typedef u16            compat_ipc_pid_t;
-typedef s32            compat_daddr_t;
-typedef u32            compat_caddr_t;
-typedef __kernel_fsid_t        compat_fsid_t;
-typedef s32            compat_key_t;
-typedef s32            compat_timer_t;
-
-typedef s32            compat_int_t;
-typedef s32            compat_long_t;
-typedef u32            compat_uint_t;
-typedef u32            compat_ulong_t;
-
-struct compat_timespec {
-       compat_time_t   tv_sec;
-       s32             tv_nsec;
-};
-
-struct compat_timeval {
-       compat_time_t   tv_sec;
-       s32             tv_usec;
-};
-
-struct compat_stat {
-       compat_dev_t    st_dev;
-       compat_ino_t    st_ino;
-       compat_mode_t   st_mode;
-       compat_nlink_t  st_nlink;       
-       __compat_uid32_t        st_uid;
-       __compat_gid32_t        st_gid;
-       compat_dev_t    st_rdev;
-       compat_off_t    st_size;
-       compat_off_t    st_blksize;
-       compat_off_t    st_blocks;
-       compat_time_t   st_atime;
-       u32             st_atime_nsec;
-       compat_time_t   st_mtime;
-       u32             st_mtime_nsec;
-       compat_time_t   st_ctime;
-       u32             st_ctime_nsec;
-       u32             __unused4[2];
-};
-
-struct compat_flock {
-       short           l_type;
-       short           l_whence;
-       compat_off_t    l_start;
-       compat_off_t    l_len;
-       compat_pid_t    l_pid;
-};
-
-#define F_GETLK64      12      /*  using 'struct flock64' */
-#define F_SETLK64      13
-#define F_SETLKW64     14
-
-struct compat_flock64 {
-       short           l_type;
-       short           l_whence;
-       compat_loff_t   l_start;
-       compat_loff_t   l_len;
-       compat_pid_t    l_pid;
-};
-
-struct compat_statfs {
-       int             f_type;
-       int             f_bsize;
-       int             f_blocks;
-       int             f_bfree;
-       int             f_bavail;
-       int             f_files;
-       int             f_ffree;
-       compat_fsid_t   f_fsid;
-       int             f_namelen;      /* SunOS ignores this field. */
-       int             f_frsize;
-       int             f_spare[5];
-};
-
-#define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
-#define COMPAT_RLIM_INFINITY           0xffffffff
-
-typedef u32            compat_old_sigset_t;
-
-#define _COMPAT_NSIG           64
-#define _COMPAT_NSIG_BPW       32
-
-typedef u32            compat_sigset_word;
-
-#define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
-
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately comverted them already.
- */
-typedef        u32             compat_uptr_t;
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-       return (void __user *)(unsigned long)uptr;
-}
-
-static inline void __user *compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = current->thread.regs;
-       unsigned long usp = regs->gpr[1];
-
-       /*
-        * We cant access below the stack pointer in the 32bit ABI and
-        * can access 288 bytes in the 64bit ABI
-        */
-       if (!(test_thread_flag(TIF_32BIT)))
-               usp -= 288;
-
-       return (void __user *) (usp - len);
-}
-
-/*
- * ipc64_perm is actually 32/64bit clean but since the compat layer refers to
- * it we may as well define it.
- */
-struct compat_ipc64_perm {
-       compat_key_t key;
-       __compat_uid_t uid;
-       __compat_gid_t gid;
-       __compat_uid_t cuid;
-       __compat_gid_t cgid;
-       compat_mode_t mode;
-       unsigned int seq;
-       unsigned int __pad2;
-       unsigned long __unused1;        /* yes they really are 64bit pads */
-       unsigned long __unused2;
-};
-
-struct compat_semid64_ds {
-       struct compat_ipc64_perm sem_perm;
-       unsigned int __unused1;
-       compat_time_t sem_otime;
-       unsigned int __unused2;
-       compat_time_t sem_ctime;
-       compat_ulong_t sem_nsems;
-       compat_ulong_t __unused3;
-       compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
-       struct compat_ipc64_perm msg_perm;
-       unsigned int __unused1;
-       compat_time_t msg_stime;
-       unsigned int __unused2;
-       compat_time_t msg_rtime;
-       unsigned int __unused3;
-       compat_time_t msg_ctime;
-       compat_ulong_t msg_cbytes;
-       compat_ulong_t msg_qnum;
-       compat_ulong_t msg_qbytes;
-       compat_pid_t msg_lspid;
-       compat_pid_t msg_lrpid;
-       compat_ulong_t __unused4;
-       compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
-       struct compat_ipc64_perm shm_perm;
-       unsigned int __unused1;
-       compat_time_t shm_atime;
-       unsigned int __unused2;
-       compat_time_t shm_dtime;
-       unsigned int __unused3;
-       compat_time_t shm_ctime;
-       unsigned int __unused4;
-       compat_size_t shm_segsz;
-       compat_pid_t shm_cpid;
-       compat_pid_t shm_lpid;
-       compat_ulong_t shm_nattch;
-       compat_ulong_t __unused5;
-       compat_ulong_t __unused6;
-};
-
-#endif /* _ASM_PPC64_COMPAT_H */
diff --git a/include/asm-ppc64/current.h b/include/asm-ppc64/current.h
deleted file mode 100644 (file)
index 52ddc60..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _PPC64_CURRENT_H
-#define _PPC64_CURRENT_H
-
-#include <asm/paca.h>
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#define get_current()   (get_paca()->__current)
-#define current         get_current()
-
-#endif /* !(_PPC64_CURRENT_H) */
index 40c8eb57493eb124170ad721cbdf378813f23a05..89f26ab31908df6e72932291568340243ba7b4b3 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * eeh.h
  * Copyright (C) 2001  Dave Engebretsen & Todd Inglett IBM Corporation.
  *
@@ -6,12 +6,12 @@
  * 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
@@ -27,8 +27,6 @@
 
 struct pci_dev;
 struct device_node;
-struct device_node;
-struct notifier_block;
 
 #ifdef CONFIG_EEH
 
@@ -37,6 +35,10 @@ struct notifier_block;
 #define EEH_MODE_NOCHECK       (1<<1)
 #define EEH_MODE_ISOLATED      (1<<2)
 
+/* Max number of EEH freezes allowed before we consider the device
+ * to be permanently disabled. */
+#define EEH_MAX_ALLOWED_FREEZES 5
+
 void __init eeh_init(void);
 unsigned long eeh_check_failure(const volatile void __iomem *token,
                                unsigned long val);
@@ -59,36 +61,14 @@ void eeh_add_device_late(struct pci_dev *);
  * eeh_remove_device - undo EEH setup for the indicated pci device
  * @dev: pci device to be removed
  *
- * This routine should be when a device is removed from a running
- * system (e.g. by hotplug or dlpar).
+ * This routine should be called when a device is removed from
+ * a running system (e.g. by hotplug or dlpar).  It unregisters
+ * the PCI device from the EEH subsystem.  I/O errors affecting
+ * this device will no longer be detected after this call; thus,
+ * i/o errors affecting this slot may leave this device unusable.
  */
 void eeh_remove_device(struct pci_dev *);
 
-#define EEH_DISABLE            0
-#define EEH_ENABLE             1
-#define EEH_RELEASE_LOADSTORE  2
-#define EEH_RELEASE_DMA                3
-
-/**
- * Notifier event flags.
- */
-#define EEH_NOTIFY_FREEZE  1
-
-/** EEH event -- structure holding pci slot data that describes
- *  a change in the isolation status of a PCI slot.  A pointer
- *  to this struct is passed as the data pointer in a notify callback.
- */
-struct eeh_event {
-       struct list_head     list;
-       struct pci_dev       *dev;
-       struct device_node   *dn;
-       int                  reset_state;
-};
-
-/** Register to find out about EEH events. */
-int eeh_register_notifier(struct notifier_block *nb);
-int eeh_unregister_notifier(struct notifier_block *nb);
-
 /**
  * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
  *
@@ -129,7 +109,7 @@ static inline void eeh_remove_device(struct pci_dev *dev) { }
 #define EEH_IO_ERROR_VALUE(size) (-1UL)
 #endif /* CONFIG_EEH */
 
-/* 
+/*
  * MMIO read/write operations with EEH support.
  */
 static inline u8 eeh_readb(const volatile void __iomem *addr)
diff --git a/include/asm-ppc64/hvcall.h b/include/asm-ppc64/hvcall.h
deleted file mode 100644 (file)
index ab7c3cf..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#ifndef _PPC64_HVCALL_H
-#define _PPC64_HVCALL_H
-
-#define HVSC                   .long 0x44000022
-
-#define H_Success      0
-#define H_Busy         1       /* Hardware busy -- retry later */
-#define H_Constrained  4       /* Resource request constrained to max allowed */
-#define H_LongBusyStartRange   9900  /* Start of long busy range */
-#define H_LongBusyOrder1msec   9900  /* Long busy, hint that 1msec is a good time to retry */
-#define H_LongBusyOrder10msec  9901  /* Long busy, hint that 10msec is a good time to retry */
-#define H_LongBusyOrder100msec 9902  /* Long busy, hint that 100msec is a good time to retry */
-#define H_LongBusyOrder1sec    9903  /* Long busy, hint that 1sec is a good time to retry */
-#define H_LongBusyOrder10sec   9904  /* Long busy, hint that 10sec is a good time to retry */
-#define H_LongBusyOrder100sec  9905  /* Long busy, hint that 100sec is a good time to retry */
-#define H_LongBusyEndRange     9905  /* End of long busy range */
-#define H_Hardware     -1      /* Hardware error */
-#define H_Function     -2      /* Function not supported */
-#define H_Privilege    -3      /* Caller not privileged */
-#define H_Parameter    -4      /* Parameter invalid, out-of-range or conflicting */
-#define H_Bad_Mode     -5      /* Illegal msr value */
-#define H_PTEG_Full    -6      /* PTEG is full */
-#define H_Not_Found    -7      /* PTE was not found" */
-#define H_Reserved_DABR        -8      /* DABR address is reserved by the hypervisor on this processor" */
-#define H_NoMem                 -9
-#define H_Authority            -10
-#define H_Permission           -11
-#define H_Dropped              -12
-#define H_SourceParm           -13
-#define H_DestParm             -14
-#define H_RemoteParm           -15
-#define H_Resource             -16
-
-/* Long Busy is a condition that can be returned by the firmware
- * when a call cannot be completed now, but the identical call
- * should be retried later.  This prevents calls blocking in the
- * firmware for long periods of time. Annoyingly the firmware can return
- * a range of return codes, hinting at how long we should wait before
- * retrying.  If you don't care for the hint, the macro below is a good
- * way to check for the long_busy return codes
- */
-#define H_isLongBusy(x)  ((x >= H_LongBusyStartRange) && (x <= H_LongBusyEndRange))
-
-/* Flags */
-#define H_LARGE_PAGE           (1UL<<(63-16))
-#define H_EXACT                        (1UL<<(63-24))  /* Use exact PTE or return H_PTEG_FULL */
-#define H_R_XLATE              (1UL<<(63-25))  /* include a valid logical page num in the pte if the valid bit is set */
-#define H_READ_4               (1UL<<(63-26))  /* Return 4 PTEs */
-#define H_AVPN                 (1UL<<(63-32))  /* An avpn is provided as a sanity test */
-#define H_ANDCOND              (1UL<<(63-33))
-#define H_ICACHE_INVALIDATE    (1UL<<(63-40))  /* icbi, etc.  (ignored for IO pages) */
-#define H_ICACHE_SYNCHRONIZE   (1UL<<(63-41))  /* dcbst, icbi, etc (ignored for IO pages */
-#define H_ZERO_PAGE            (1UL<<(63-48))  /* zero the page before mapping (ignored for IO pages) */
-#define H_COPY_PAGE            (1UL<<(63-49))
-#define H_N                    (1UL<<(63-61))
-#define H_PP1                  (1UL<<(63-62))
-#define H_PP2                  (1UL<<(63-63))
-
-/* DABRX flags */
-#define H_DABRX_HYPERVISOR     (1UL<<(63-61))
-#define H_DABRX_KERNEL         (1UL<<(63-62))
-#define H_DABRX_USER           (1UL<<(63-63))
-
-/* pSeries hypervisor opcodes */
-#define H_REMOVE               0x04
-#define H_ENTER                        0x08
-#define H_READ                 0x0c
-#define H_CLEAR_MOD            0x10
-#define H_CLEAR_REF            0x14
-#define H_PROTECT              0x18
-#define H_GET_TCE              0x1c
-#define H_PUT_TCE              0x20
-#define H_SET_SPRG0            0x24
-#define H_SET_DABR             0x28
-#define H_PAGE_INIT            0x2c
-#define H_SET_ASR              0x30
-#define H_ASR_ON               0x34
-#define H_ASR_OFF              0x38
-#define H_LOGICAL_CI_LOAD      0x3c
-#define H_LOGICAL_CI_STORE     0x40
-#define H_LOGICAL_CACHE_LOAD   0x44
-#define H_LOGICAL_CACHE_STORE  0x48
-#define H_LOGICAL_ICBI         0x4c
-#define H_LOGICAL_DCBF         0x50
-#define H_GET_TERM_CHAR                0x54
-#define H_PUT_TERM_CHAR                0x58
-#define H_REAL_TO_LOGICAL      0x5c
-#define H_HYPERVISOR_DATA      0x60
-#define H_EOI                  0x64
-#define H_CPPR                 0x68
-#define H_IPI                  0x6c
-#define H_IPOLL                        0x70
-#define H_XIRR                 0x74
-#define H_PERFMON              0x7c
-#define H_MIGRATE_DMA          0x78
-#define H_REGISTER_VPA         0xDC
-#define H_CEDE                 0xE0
-#define H_CONFER               0xE4
-#define H_PROD                 0xE8
-#define H_GET_PPP              0xEC
-#define H_SET_PPP              0xF0
-#define H_PURR                 0xF4
-#define H_PIC                  0xF8
-#define H_REG_CRQ              0xFC
-#define H_FREE_CRQ             0x100
-#define H_VIO_SIGNAL           0x104
-#define H_SEND_CRQ             0x108
-#define H_COPY_RDMA             0x110
-#define H_SET_XDABR            0x134
-#define H_STUFF_TCE            0x138
-#define H_PUT_TCE_INDIRECT     0x13C
-#define H_VTERM_PARTNER_INFO   0x150
-#define H_REGISTER_VTERM       0x154
-#define H_FREE_VTERM           0x158
-#define H_POLL_PENDING         0x1D8
-
-#ifndef __ASSEMBLY__
-
-/* plpar_hcall() -- Generic call interface using above opcodes
- *
- * The actual call interface is a hypervisor call instruction with
- * the opcode in R3 and input args in R4-R7.
- * Status is returned in R3 with variable output values in R4-R11.
- * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now
- * and return only two out args which MUST ALWAYS BE PROVIDED.
- */
-long plpar_hcall(unsigned long opcode,
-                unsigned long arg1,
-                unsigned long arg2,
-                unsigned long arg3,
-                unsigned long arg4,
-                unsigned long *out1,
-                unsigned long *out2,
-                unsigned long *out3);
-
-/* Same as plpar_hcall but for those opcodes that return no values
- * other than status.  Slightly more efficient.
- */
-long plpar_hcall_norets(unsigned long opcode, ...);
-
-/* 
- * Special hcall interface for ibmveth support.
- * Takes 8 input parms. Returns a rc and stores the
- * R4 return value in *out1.
- */
-long plpar_hcall_8arg_2ret(unsigned long opcode,
-                          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 *out1);
-/* plpar_hcall_4out()
- *
- * same as plpar_hcall except with 4 output arguments.  
- * 
- */
-long plpar_hcall_4out(unsigned long opcode,
-                     unsigned long arg1,
-                     unsigned long arg2,
-                     unsigned long arg3,
-                     unsigned long arg4,
-                     unsigned long *out1,
-                     unsigned long *out2,
-                     unsigned long *out3,
-                     unsigned long *out4);
-
-#endif /* __ASSEMBLY__ */
-#endif /* _PPC64_HVCALL_H */
diff --git a/include/asm-ppc64/lppaca.h b/include/asm-ppc64/lppaca.h
deleted file mode 100644 (file)
index 9e2a6c0..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * lppaca.h
- * Copyright (C) 2001  Mike Corrigan IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _ASM_LPPACA_H
-#define _ASM_LPPACA_H
-
-//=============================================================================
-//
-//     This control block contains the data that is shared between the
-//     hypervisor (PLIC) and the OS.
-//
-//
-//----------------------------------------------------------------------------
-#include <asm/types.h>
-
-struct lppaca
-{
-//=============================================================================
-// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
-// NOTE: The xDynXyz fields are fields that will be dynamically changed by
-// PLIC when preparing to bring a processor online or when dispatching a
-// virtual processor!
-//=============================================================================
-       u32     desc;                   // Eye catcher 0xD397D781       x00-x03
-       u16     size;                   // Size of this struct          x04-x05
-       u16     reserved1;              // Reserved                     x06-x07
-       u16     reserved2:14;           // Reserved                     x08-x09
-       u8      shared_proc:1;          // Shared processor indicator   ...
-       u8      secondary_thread:1;     // Secondary thread indicator   ...
-       volatile u8 dyn_proc_status:8;  // Dynamic Status of this proc  x0A-x0A
-       u8      secondary_thread_count; // Secondary thread count       x0B-x0B
-       volatile u16 dyn_hv_phys_proc_index;// Dynamic HV Physical Proc Index0C-x0D
-       volatile u16 dyn_hv_log_proc_index;// Dynamic HV Logical Proc Indexx0E-x0F
-       u32     decr_val;               // Value for Decr programming   x10-x13
-       u32     pmc_val;                // Value for PMC regs           x14-x17
-       volatile u32 dyn_hw_node_id;    // Dynamic Hardware Node id     x18-x1B
-       volatile u32 dyn_hw_proc_id;    // Dynamic Hardware Proc Id     x1C-x1F
-       volatile u32 dyn_pir;           // Dynamic ProcIdReg value      x20-x23
-       u32     dsei_data;              // DSEI data                    x24-x27
-       u64     sprg3;                  // SPRG3 value                  x28-x2F
-       u8      reserved3[80];          // Reserved                     x30-x7F
-
-//=============================================================================
-// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
-//=============================================================================
-       // This Dword contains a byte for each type of interrupt that can occur.
-       // The IPI is a count while the others are just a binary 1 or 0.
-       union {
-               u64     any_int;
-               struct {
-                       u16     reserved;       // Reserved - cleared by #mpasmbl
-                       u8      xirr_int;       // Indicates xXirrValue is valid or Immed IO
-                       u8      ipi_cnt;        // IPI Count
-                       u8      decr_int;       // DECR interrupt occurred
-                       u8      pdc_int;        // PDC interrupt occurred
-                       u8      quantum_int;    // Interrupt quantum reached
-                       u8      old_plic_deferred_ext_int;      // Old PLIC has a deferred XIRR pending
-               } fields;
-       } int_dword;
-
-       // Whenever any fields in this Dword are set then PLIC will defer the
-       // processing of external interrupts.  Note that PLIC will store the
-       // XIRR directly into the xXirrValue field so that another XIRR will
-       // not be presented until this one clears.  The layout of the low
-       // 4-bytes of this Dword is upto SLIC - PLIC just checks whether the
-       // entire Dword is zero or not.  A non-zero value in the low order
-       // 2-bytes will result in SLIC being granted the highest thread
-       // priority upon return.  A 0 will return to SLIC as medium priority.
-       u64     plic_defer_ints_area;   // Entire Dword
-
-       // Used to pass the real SRR0/1 from PLIC to SLIC as well as to
-       // pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid.
-       u64     saved_srr0;             // Saved SRR0                   x10-x17
-       u64     saved_srr1;             // Saved SRR1                   x18-x1F
-
-       // Used to pass parms from the OS to PLIC for SetAsrAndRfid
-       u64     saved_gpr3;             // Saved GPR3                   x20-x27
-       u64     saved_gpr4;             // Saved GPR4                   x28-x2F
-       u64     saved_gpr5;             // Saved GPR5                   x30-x37
-
-       u8      reserved4;              // Reserved                     x38-x38
-       u8      cpuctls_task_attrs;     // Task attributes for cpuctls  x39-x39
-       u8      fpregs_in_use;          // FP regs in use               x3A-x3A
-       u8      pmcregs_in_use;         // PMC regs in use              x3B-x3B
-       volatile u32 saved_decr;        // Saved Decr Value             x3C-x3F
-       volatile u64 emulated_time_base;// Emulated TB for this thread  x40-x47
-       volatile u64 cur_plic_latency;  // Unaccounted PLIC latency     x48-x4F
-       u64     tot_plic_latency;       // Accumulated PLIC latency     x50-x57
-       u64     wait_state_cycles;      // Wait cycles for this proc    x58-x5F
-       u64     end_of_quantum;         // TB at end of quantum         x60-x67
-       u64     pdc_saved_sprg1;        // Saved SPRG1 for PMC int      x68-x6F
-       u64     pdc_saved_srr0;         // Saved SRR0 for PMC int       x70-x77
-       volatile u32 virtual_decr;      // Virtual DECR for shared procsx78-x7B
-       u16     slb_count;              // # of SLBs to maintain        x7C-x7D
-       u8      idle;                   // Indicate OS is idle          x7E
-       u8      vmxregs_in_use;         // VMX registers in use         x7F
-
-
-//=============================================================================
-// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
-//=============================================================================
-       // This is the yield_count.  An "odd" value (low bit on) means that
-       // the processor is yielded (either because of an OS yield or a PLIC
-       // preempt).  An even value implies that the processor is currently
-       // executing.
-       // NOTE: This value will ALWAYS be zero for dedicated processors and
-       // will NEVER be zero for shared processors (ie, initialized to a 1).
-       volatile u32 yield_count;       // PLIC increments each dispatchx00-x03
-       u8      reserved6[124];         // Reserved                     x04-x7F
-
-//=============================================================================
-// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
-//=============================================================================
-       u8      pmc_save_area[256];     // PMC interrupt Area           x00-xFF
-};
-
-#endif /* _ASM_LPPACA_H */
index 4c18a5cb69f59f493bdc091e1df6ec2641974f5c..1a7e0afa2dc6175a79d62f0db40101eb99ba8f0c 100644 (file)
@@ -14,7 +14,7 @@
 #define _PPC64_MMU_H_
 
 #include <linux/config.h>
-#include <asm/ppc_asm.h> /* for ASM_CONST */
+#include <asm/asm-compat.h>
 #include <asm/page.h>
 
 /*
@@ -224,9 +224,12 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                             unsigned long pstart, unsigned long mode,
                             int psize);
 
+extern void htab_initialize(void);
+extern void htab_initialize_secondary(void);
 extern void hpte_init_native(void);
 extern void hpte_init_lpar(void);
 extern void hpte_init_iSeries(void);
+extern void mm_init_ppc64(void);
 
 extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
                                     unsigned long va, unsigned long prpn,
@@ -245,6 +248,7 @@ extern long iSeries_hpte_insert(unsigned long hpte_group,
 
 extern void stabs_alloc(void);
 extern void slb_initialize(void);
+extern void stab_initialize(unsigned long stab);
 
 #endif /* __ASSEMBLY__ */
 
index 80a708e7093a62d9646930e57be4aa9ac6ddfa3c..15e777ce0f4ab66fe61f64ff4fed055c4a86d7fc 100644 (file)
@@ -33,6 +33,9 @@ extern int numa_cpu_lookup_table[];
 extern char *numa_memory_lookup_table;
 extern cpumask_t numa_cpumask_lookup_table[];
 extern int nr_cpus_in_node[];
+#ifdef CONFIG_MEMORY_HOTPLUG
+extern unsigned long max_pfn;
+#endif
 
 /* 16MB regions */
 #define MEMORY_INCREMENT_SHIFT 24
@@ -45,6 +48,11 @@ static inline int pa_to_nid(unsigned long pa)
 {
        int nid;
 
+#ifdef CONFIG_MEMORY_HOTPLUG
+       /* kludge hot added sections default to node 0 */
+       if (pa >= (max_pfn << PAGE_SHIFT))
+               return 0;
+#endif
        nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT];
 
 #ifdef DEBUG_NUMA
diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
deleted file mode 100644 (file)
index bccacd6..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#ifndef _PPC64_PACA_H
-#define _PPC64_PACA_H
-
-/*
- * include/asm-ppc64/paca.h
- *
- * This control block defines the PACA which defines the processor 
- * specific data for each logical processor on the system.  
- * There are some pointers defined that are utilized by PLIC.
- *
- * C 2001 PPC 64 Team, IBM Corp
- *
- * 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/config.h>
-#include       <asm/types.h>
-#include       <asm/lppaca.h>
-#include       <asm/iseries/it_lp_reg_save.h>
-#include       <asm/mmu.h>
-
-register struct paca_struct *local_paca asm("r13");
-#define get_paca()     local_paca
-
-struct task_struct;
-
-/*
- * Defines the layout of the paca.
- *
- * This structure is not directly accessed by firmware or the service
- * processor except for the first two pointers that point to the
- * lppaca area and the ItLpRegSave area for this CPU.  Both the
- * lppaca and ItLpRegSave objects are currently contained within the
- * PACA but they do not need to be.
- */
-struct paca_struct {
-       /*
-        * Because hw_cpu_id, unlike other paca fields, is accessed
-        * routinely from other CPUs (from the IRQ code), we stick to
-        * read-only (after boot) fields in the first cacheline to
-        * avoid cacheline bouncing.
-        */
-
-       /*
-        * MAGIC: These first two pointers can't be moved - they're
-        * accessed by the firmware
-        */
-       struct lppaca *lppaca_ptr;      /* Pointer to LpPaca for PLIC */
-       struct ItLpRegSave *reg_save_ptr; /* Pointer to LpRegSave for PLIC */
-
-       /*
-        * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c
-        * load lock_token and paca_index with a single lwz
-        * instruction.  They must travel together and be properly
-        * aligned.
-        */
-       u16 lock_token;                 /* Constant 0x8000, used in locks */
-       u16 paca_index;                 /* Logical processor number */
-
-       u32 default_decr;               /* Default decrementer value */
-       u64 kernel_toc;                 /* Kernel TOC address */
-       u64 stab_real;                  /* Absolute address of segment table */
-       u64 stab_addr;                  /* Virtual address of segment table */
-       void *emergency_sp;             /* pointer to emergency stack */
-       s16 hw_cpu_id;                  /* Physical processor number */
-       u8 cpu_start;                   /* At startup, processor spins until */
-                                       /* this becomes non-zero. */
-
-       /*
-        * Now, starting in cacheline 2, the exception save areas
-        */
-       /* used for most interrupts/exceptions */
-       u64 exgen[10] __attribute__((aligned(0x80)));
-       u64 exmc[10];           /* used for machine checks */
-       u64 exslb[10];          /* used for SLB/segment table misses
-                                * on the linear mapping */
-#ifdef CONFIG_PPC_64K_PAGES
-       pgd_t *pgdir;
-#endif /* CONFIG_PPC_64K_PAGES */
-
-       mm_context_t context;
-       u16 slb_cache[SLB_CACHE_ENTRIES];
-       u16 slb_cache_ptr;
-
-       /*
-        * then miscellaneous read-write fields
-        */
-       struct task_struct *__current;  /* Pointer to current */
-       u64 kstack;                     /* Saved Kernel stack addr */
-       u64 stab_rr;                    /* stab/slb round-robin counter */
-       u64 next_jiffy_update_tb;       /* TB value for next jiffy update */
-       u64 saved_r1;                   /* r1 save for RTAS calls */
-       u64 saved_msr;                  /* MSR saved here by enter_rtas */
-       u8 proc_enabled;                /* irq soft-enable flag */
-
-       /* not yet used */
-       u64 exdsi[8];           /* used for linear mapping hash table misses */
-
-       /*
-        * iSeries structure which the hypervisor knows about -
-        * this structure should not cross a page boundary.
-        * The vpa_init/register_vpa call is now known to fail if the
-        * lppaca structure crosses a page boundary.
-        * The lppaca is also used on POWER5 pSeries boxes.
-        * The lppaca is 640 bytes long, and cannot readily change
-        * since the hypervisor knows its layout, so a 1kB
-        * alignment will suffice to ensure that it doesn't
-        * cross a page boundary.
-        */
-       struct lppaca lppaca __attribute__((__aligned__(0x400)));
-#ifdef CONFIG_PPC_ISERIES
-       struct ItLpRegSave reg_save;
-#endif
-};
-
-extern struct paca_struct paca[];
-
-#endif /* _PPC64_PACA_H */
index 82ce187e5be83271bd0778e756af9caceb550200..e32f1187aa29730c0ab75f2253e089667ece11f3 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/config.h>
-#include <asm/ppc_asm.h> /* for ASM_CONST */
+#include <asm/asm-compat.h>
 
 /*
  * We support either 4k or 64k software page size. When using 64k pages
index 60cf8c838af0df1e36e6d68fdd9c3c3d5c6616af..efbdaece0cf022fdd10bb2228368448240836af6 100644 (file)
@@ -63,7 +63,6 @@ struct pci_dn {
        int     devfn;                  /* for pci devices */
        int     eeh_mode;               /* See eeh.h for possible EEH_MODEs */
        int     eeh_config_addr;
-       int     eeh_capable;            /* from firmware */
        int     eeh_check_count;        /* # times driver ignored error */
        int     eeh_freeze_count;       /* # times this device froze up. */
        int     eeh_is_bridge;          /* device is pci-to-pci bridge */
index 98da0e4262bd2f02a6d07c3df5d2c68eb3f495f3..dcf3622d19462110dda6332b30f9234feb8f16cc 100644 (file)
@@ -10,8 +10,8 @@ extern kmem_cache_t *pgtable_cache[];
 
 #ifdef CONFIG_PPC_64K_PAGES
 #define PTE_CACHE_NUM  0
-#define PMD_CACHE_NUM  0
-#define PGD_CACHE_NUM  1
+#define PMD_CACHE_NUM  1
+#define PGD_CACHE_NUM  2
 #else
 #define PTE_CACHE_NUM  0
 #define PMD_CACHE_NUM  1
index 76bb0266d67c1d2a6c241fe41d7129f003f00e24..ddfe186589fa3c805f0f926f459828c036073d2f 100644 (file)
@@ -204,6 +204,8 @@ extern void of_detach_node(const struct device_node *);
 extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
        unsigned long, unsigned long);
 extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern void early_init_devtree(void *);
 extern int device_is_compatible(struct device_node *device, const char *);
 extern int machine_is_compatible(const char *compat);
 extern unsigned char *get_property(struct device_node *node, const char *name,
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
deleted file mode 100644 (file)
index 432df7d..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _ASMPPC64_SIGNAL_H
-#define _ASMPPC64_SIGNAL_H
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <asm/siginfo.h>
-
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-
-#define _NSIG          64
-#define _NSIG_BPW      64
-#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t;            /* at least 32 bits */
-
-typedef struct {
-       unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-#define SIGBUS          7
-#define SIGFPE          8
-#define SIGKILL                 9
-#define SIGUSR1                10
-#define SIGSEGV                11
-#define SIGUSR2                12
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGSTKFLT      16
-#define SIGCHLD                17
-#define SIGCONT                18
-#define SIGSTOP                19
-#define SIGTSTP                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGURG         23
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGIO          29
-#define SIGPOLL                SIGIO
-/*
-#define SIGLOST                29
-*/
-#define SIGPWR         30
-#define SIGSYS         31
-#define        SIGUNUSED       31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN       32
-#define SIGRTMAX       _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP   0x00000001u
-#define SA_NOCLDWAIT   0x00000002u
-#define SA_SIGINFO     0x00000004u
-#define SA_ONSTACK     0x08000000u
-#define SA_RESTART     0x10000000u
-#define SA_NODEFER     0x40000000u
-#define SA_RESETHAND   0x80000000u
-
-#define SA_NOMASK      SA_NODEFER
-#define SA_ONESHOT     SA_RESETHAND
-#define SA_INTERRUPT   0x20000000u /* dummy -- ignored */
-
-#define SA_RESTORER    0x04000000u
-
-/* 
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    2048
-#define SIGSTKSZ       8192
-
-#include <asm-generic/signal.h>
-
-struct old_sigaction {
-       __sighandler_t sa_handler;
-       old_sigset_t sa_mask;
-       unsigned long sa_flags;
-       __sigrestore_t sa_restorer;
-};
-
-struct sigaction {
-       __sighandler_t sa_handler;
-       unsigned long sa_flags;
-       __sigrestore_t sa_restorer;
-       sigset_t sa_mask;               /* mask last for extensibility */
-};
-
-struct k_sigaction {
-       struct sigaction sa;
-};
-
-typedef struct sigaltstack {
-       void __user *ss_sp;
-       int ss_flags;
-       size_t ss_size;
-} stack_t;
-
-struct pt_regs;
-struct timespec;
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-#endif /* _ASMPPC64_SIGNAL_H */
index 0cdd66c9f4b7ea611a645646e8ccf3f75614ca86..bf9a6aba19c927d997a15566c034a96f7dfe4453 100644 (file)
@@ -149,6 +149,8 @@ struct thread_struct;
 extern struct task_struct * _switch(struct thread_struct *prev,
                                    struct thread_struct *next);
 
+extern unsigned long klimit;
+
 extern int powersave_nap;      /* set if nap mode can be used in idle loop */
 
 /*
diff --git a/include/asm-ppc64/systemcfg.h b/include/asm-ppc64/systemcfg.h
deleted file mode 100644 (file)
index 9b86b53..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _SYSTEMCFG_H
-#define _SYSTEMCFG_H
-
-/* 
- * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/* Change Activity:
- * 2002/09/30 : bergner  : Created
- * End Change Activity 
- */
-
-/*
- * If the major version changes we are incompatible.
- * Minor version changes are a hint.
- */
-#define SYSTEMCFG_MAJOR 1
-#define SYSTEMCFG_MINOR 1
-
-#ifndef __ASSEMBLY__
-
-#include <linux/unistd.h>
-
-#define SYSCALL_MAP_SIZE      ((__NR_syscalls + 31) / 32)
-
-struct systemcfg {
-       __u8  eye_catcher[16];          /* Eyecatcher: SYSTEMCFG:PPC64  0x00 */
-       struct {                        /* Systemcfg version numbers         */
-               __u32 major;            /* Major number                 0x10 */
-               __u32 minor;            /* Minor number                 0x14 */
-       } version;
-
-       __u32 platform;                 /* Platform flags               0x18 */
-       __u32 processor;                /* Processor type               0x1C */
-       __u64 processorCount;           /* # of physical processors     0x20 */
-       __u64 physicalMemorySize;       /* Size of real memory(B)       0x28 */
-       __u64 tb_orig_stamp;            /* Timebase at boot             0x30 */
-       __u64 tb_ticks_per_sec;         /* Timebase tics / sec          0x38 */
-       __u64 tb_to_xs;                 /* Inverse of TB to 2^20        0x40 */
-       __u64 stamp_xsec;               /*                              0x48 */
-       __u64 tb_update_count;          /* Timebase atomicity ctr       0x50 */
-       __u32 tz_minuteswest;           /* Minutes west of Greenwich    0x58 */
-       __u32 tz_dsttime;               /* Type of dst correction       0x5C */
-       /* next four are no longer used except to be exported to /proc */
-       __u32 dcache_size;              /* L1 d-cache size              0x60 */
-       __u32 dcache_line_size;         /* L1 d-cache line size         0x64 */
-       __u32 icache_size;              /* L1 i-cache size              0x68 */
-       __u32 icache_line_size;         /* L1 i-cache line size         0x6C */
-       __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of available syscalls 0x70 */
-       __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of available syscalls */
-};
-
-#ifdef __KERNEL__
-extern struct systemcfg *systemcfg;
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _SYSTEMCFG_H */
diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h
deleted file mode 100644 (file)
index d40b6b4..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- * Rewrite, cleanup:
- * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _ASM_TCE_H
-#define _ASM_TCE_H
-
-/*
- * Tces come in two formats, one for the virtual bus and a different
- * format for PCI
- */
-#define TCE_VB  0
-#define TCE_PCI 1
-
-/* TCE page size is 4096 bytes (1 << 12) */
-
-#define TCE_SHIFT      12
-#define TCE_PAGE_SIZE  (1 << TCE_SHIFT)
-#define TCE_PAGE_FACTOR        (PAGE_SHIFT - TCE_SHIFT)
-
-
-/* tce_entry
- * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
- * abstracted so layout is irrelevant.
- */
-union tce_entry {
-       unsigned long te_word;
-       struct {
-               unsigned int  tb_cacheBits :6;  /* Cache hash bits - not used */
-               unsigned int  tb_rsvd      :6;
-               unsigned long tb_rpn       :40; /* Real page number */
-               unsigned int  tb_valid     :1;  /* Tce is valid (vb only) */
-               unsigned int  tb_allio     :1;  /* Tce is valid for all lps (vb only) */
-               unsigned int  tb_lpindex   :8;  /* LpIndex for user of TCE (vb only) */
-               unsigned int  tb_pciwr     :1;  /* Write allowed (pci only) */
-               unsigned int  tb_rdwr      :1;  /* Read allowed  (pci), Write allowed (vb) */
-       } te_bits;
-#define te_cacheBits te_bits.tb_cacheBits
-#define te_rpn       te_bits.tb_rpn
-#define te_valid     te_bits.tb_valid
-#define te_allio     te_bits.tb_allio
-#define te_lpindex   te_bits.tb_lpindex
-#define te_pciwr     te_bits.tb_pciwr
-#define te_rdwr      te_bits.tb_rdwr
-};
-
-
-#endif
index 1bf3c39d61092209bd66c51e9ba53e7bd24b7d04..80789a59b4dbc6553a21b6f8075f803ad76fc5be 100644 (file)
@@ -1499,7 +1499,7 @@ void do_notify_parent(struct task_struct *tsk, int sig)
 
        psig = tsk->parent->sighand;
        spin_lock_irqsave(&psig->siglock, flags);
-       if (sig == SIGCHLD &&
+       if (!tsk->ptrace && sig == SIGCHLD &&
            (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
             (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
                /*