aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/common/locomo.c4
-rw-r--r--arch/arm/common/scoop.c2
-rw-r--r--arch/arm/kernel/apm.c1
-rw-r--r--arch/arm/kernel/smp.c4
-rw-r--r--arch/arm/mach-footbridge/common.c24
-rw-r--r--arch/arm/mach-pxa/Kconfig6
-rw-r--r--arch/arm/mach-pxa/Makefile5
-rw-r--r--arch/arm/mach-pxa/akita-ioexp.c223
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c228
-rw-r--r--arch/arm/mach-pxa/sharpsl.h8
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c109
-rw-r--r--arch/arm/mach-pxa/spitz.c49
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c233
-rw-r--r--arch/frv/kernel/pm.c1
-rw-r--r--arch/i386/Kconfig2
-rw-r--r--arch/i386/kernel/acpi/boot.c17
-rw-r--r--arch/i386/kernel/apm.c1
-rw-r--r--arch/i386/kernel/cpu/amd.c12
-rw-r--r--arch/i386/kernel/cpu/common.c40
-rw-r--r--arch/i386/kernel/cpu/intel.c50
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c46
-rw-r--r--arch/i386/kernel/cpu/mtrr/main.c8
-rw-r--r--arch/i386/kernel/cpu/proc.c7
-rw-r--r--arch/i386/kernel/crash.c7
-rw-r--r--arch/i386/kernel/entry.S7
-rw-r--r--arch/i386/kernel/smpboot.c73
-rw-r--r--arch/i386/kernel/srat.c4
-rw-r--r--arch/i386/kernel/timers/timer_pit.c5
-rw-r--r--arch/i386/mm/init.c3
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/m68k/fpsp040/skeleton.S6
-rw-r--r--arch/m68k/ifpsp060/iskeleton.S6
-rw-r--r--arch/m68k/kernel/asm-offsets.c10
-rw-r--r--arch/m68k/kernel/entry.S78
-rw-r--r--arch/m68k/kernel/ptrace.c15
-rw-r--r--arch/mips/au1000/common/power.c1
-rw-r--r--arch/mips/au1000/common/usbdev.c4
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/configs/pseries_defconfig206
-rw-r--r--arch/powerpc/kernel/Makefile20
-rw-r--r--arch/powerpc/kernel/asm-offsets.c6
-rw-r--r--arch/powerpc/kernel/dma_64.c (renamed from arch/ppc64/kernel/dma.c)0
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S2
-rw-r--r--arch/powerpc/kernel/iomap.c (renamed from arch/ppc64/kernel/iomap.c)0
-rw-r--r--arch/powerpc/kernel/iommu.c (renamed from arch/ppc64/kernel/iommu.c)0
-rw-r--r--arch/powerpc/kernel/irq.c9
-rw-r--r--arch/powerpc/kernel/kprobes.c (renamed from arch/ppc64/kernel/kprobes.c)0
-rw-r--r--arch/powerpc/kernel/lparcfg.c51
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c (renamed from arch/ppc64/kernel/machine_kexec.c)63
-rw-r--r--arch/powerpc/kernel/module_64.c (renamed from arch/ppc64/kernel/module.c)0
-rw-r--r--arch/powerpc/kernel/pci_64.c (renamed from arch/ppc64/kernel/pci.c)0
-rw-r--r--arch/powerpc/kernel/pci_direct_iommu.c (renamed from arch/ppc64/kernel/pci_direct_iommu.c)0
-rw-r--r--arch/powerpc/kernel/pci_dn.c (renamed from arch/ppc64/kernel/pci_dn.c)0
-rw-r--r--arch/powerpc/kernel/pci_iommu.c (renamed from arch/ppc64/kernel/pci_iommu.c)0
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c7
-rw-r--r--arch/powerpc/kernel/prom.c2
-rw-r--r--arch/powerpc/kernel/rtas-rtc.c105
-rw-r--r--arch/powerpc/kernel/setup_32.c4
-rw-r--r--arch/powerpc/kernel/setup_64.c5
-rw-r--r--arch/powerpc/kernel/signal_32.c7
-rw-r--r--arch/powerpc/kernel/signal_64.c6
-rw-r--r--arch/powerpc/kernel/vdso32/datapage.S3
-rw-r--r--arch/powerpc/kernel/vdso32/gettimeofday.S12
-rw-r--r--arch/powerpc/kernel/vdso64/datapage.S1
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S31
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c2
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c2
-rw-r--r--arch/powerpc/platforms/iseries/irq.c25
-rw-r--r--arch/powerpc/platforms/iseries/setup.c6
-rw-r--r--arch/powerpc/platforms/powermac/time.c9
-rw-r--r--arch/powerpc/platforms/pseries/Makefile5
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c (renamed from arch/ppc64/kernel/hvconsole.c)0
-rw-r--r--arch/powerpc/platforms/pseries/hvcserver.c (renamed from arch/ppc64/kernel/hvcserver.c)0
-rw-r--r--arch/powerpc/platforms/pseries/setup.c26
-rw-r--r--arch/powerpc/xmon/xmon.c1
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S2
-rw-r--r--arch/ppc/mm/fsl_booke_mmu.c2
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c17
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc8555_cds.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.h2
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c2
-rw-r--r--arch/ppc/platforms/pmac_feature.c8
-rw-r--r--arch/ppc/platforms/pq2ads.c2
-rw-r--r--arch/ppc/syslib/ipic.h2
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc83xx_sys.c2
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc85xx_sys.c2
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.h2
-rw-r--r--arch/ppc/syslib/ppc85xx_common.c2
-rw-r--r--arch/ppc/syslib/ppc85xx_common.h2
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.h2
-rw-r--r--arch/ppc/syslib/ppc_sys.c2
-rw-r--r--arch/ppc/syslib/pq2_devices.c2
-rw-r--r--arch/ppc/syslib/pq2_sys.c2
-rw-r--r--arch/ppc64/Kconfig520
-rw-r--r--arch/ppc64/kernel/Makefile41
-rw-r--r--arch/ppc64/kernel/asm-offsets.c195
-rw-r--r--arch/ppc64/kernel/btext.c792
-rw-r--r--arch/ppc64/kernel/head.S2007
-rw-r--r--arch/ppc64/kernel/misc.S940
-rw-r--r--arch/ppc64/kernel/ppc_ksyms.c76
-rw-r--r--arch/ppc64/kernel/prom.c1954
-rw-r--r--arch/ppc64/kernel/prom_init.c2051
-rw-r--r--arch/ppc64/kernel/rtc.c358
-rw-r--r--arch/ppc64/kernel/semaphore.c136
-rw-r--r--arch/ppc64/kernel/vdso.c625
-rw-r--r--arch/ppc64/kernel/vmlinux.lds.S151
-rw-r--r--arch/ppc64/xmon/privinst.h64
-rw-r--r--arch/sparc/lib/atomic32.c34
-rw-r--r--arch/sparc/lib/bitext.c1
-rw-r--r--arch/um/Kconfig10
-rw-r--r--arch/um/Kconfig.i38610
-rw-r--r--arch/um/Makefile-i3861
-rw-r--r--arch/um/drivers/chan_kern.c5
-rw-r--r--arch/um/drivers/chan_user.c2
-rw-r--r--arch/um/drivers/daemon_user.c6
-rw-r--r--arch/um/drivers/fd.c9
-rw-r--r--arch/um/drivers/mcast_user.c20
-rw-r--r--arch/um/drivers/port_user.c9
-rw-r--r--arch/um/drivers/pty.c11
-rw-r--r--arch/um/drivers/tty.c9
-rw-r--r--arch/um/drivers/xterm.c9
-rw-r--r--arch/um/include/chan_user.h4
-rw-r--r--arch/um/include/um_uaccess.h19
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h10
-rw-r--r--arch/um/kernel/skas/uaccess.c8
-rw-r--r--arch/um/kernel/trap_kern.c9
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h8
-rw-r--r--arch/um/kernel/tt/uaccess.c8
-rw-r--r--arch/v850/Kconfig8
-rw-r--r--arch/v850/kernel/irq.c715
-rw-r--r--arch/x86_64/Kconfig57
-rw-r--r--arch/x86_64/Kconfig.debug9
-rw-r--r--arch/x86_64/defconfig98
-rw-r--r--arch/x86_64/ia32/ia32_aout.c3
-rw-r--r--arch/x86_64/ia32/ia32_binfmt.c4
-rw-r--r--arch/x86_64/kernel/Makefile1
-rw-r--r--arch/x86_64/kernel/aperture.c2
-rw-r--r--arch/x86_64/kernel/apic.c10
-rw-r--r--arch/x86_64/kernel/e820.c3
-rw-r--r--arch/x86_64/kernel/entry.S3
-rw-r--r--arch/x86_64/kernel/head.S37
-rw-r--r--arch/x86_64/kernel/head64.c14
-rw-r--r--arch/x86_64/kernel/i8259.c4
-rw-r--r--arch/x86_64/kernel/io_apic.c80
-rw-r--r--arch/x86_64/kernel/mce.c17
-rw-r--r--arch/x86_64/kernel/mce_amd.c538
-rw-r--r--arch/x86_64/kernel/mpparse.c23
-rw-r--r--arch/x86_64/kernel/pci-gart.c8
-rw-r--r--arch/x86_64/kernel/process.c47
-rw-r--r--arch/x86_64/kernel/reboot.c7
-rw-r--r--arch/x86_64/kernel/setup.c89
-rw-r--r--arch/x86_64/kernel/setup64.c2
-rw-r--r--arch/x86_64/kernel/signal.c17
-rw-r--r--arch/x86_64/kernel/smp.c7
-rw-r--r--arch/x86_64/kernel/smpboot.c111
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c14
-rw-r--r--arch/x86_64/kernel/traps.c44
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S2
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c3
-rw-r--r--arch/x86_64/lib/clear_page.S38
-rw-r--r--arch/x86_64/lib/copy_page.S87
-rw-r--r--arch/x86_64/lib/memcpy.S93
-rw-r--r--arch/x86_64/lib/memset.S94
-rw-r--r--arch/x86_64/mm/fault.c19
-rw-r--r--arch/x86_64/mm/init.c129
-rw-r--r--arch/x86_64/mm/k8topology.c1
-rw-r--r--arch/x86_64/mm/numa.c122
-rw-r--r--arch/x86_64/mm/srat.c6
184 files changed, 2902 insertions, 11789 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3df7cbd924a1..70b007e66926 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -702,6 +702,8 @@ menu "Device Drivers"
702 702
703source "drivers/base/Kconfig" 703source "drivers/base/Kconfig"
704 704
705source "drivers/connector/Kconfig"
706
705if ALIGNMENT_TRAP 707if ALIGNMENT_TRAP
706source "drivers/mtd/Kconfig" 708source "drivers/mtd/Kconfig"
707endif 709endif
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 557e52c1c869..1b7eaab02b9e 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -623,8 +623,6 @@ static int locomo_resume(struct platform_device *dev)
623 locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD); 623 locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
624 624
625 spin_unlock_irqrestore(&lchip->lock, flags); 625 spin_unlock_irqrestore(&lchip->lock, flags);
626
627 dev->power.saved_state = NULL;
628 kfree(save); 626 kfree(save);
629 627
630 return 0; 628 return 0;
@@ -775,7 +773,7 @@ static int locomo_probe(struct platform_device *dev)
775 773
776static int locomo_remove(struct platform_device *dev) 774static int locomo_remove(struct platform_device *dev)
777{ 775{
778 struct locomo *lchip = platform__get_drvdata(dev); 776 struct locomo *lchip = platform_get_drvdata(dev);
779 777
780 if (lchip) { 778 if (lchip) {
781 __locomo_remove(lchip); 779 __locomo_remove(lchip);
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 32924c6714fe..0c3cbd9a388b 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -153,7 +153,7 @@ int __init scoop_probe(struct platform_device *pdev)
153 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base); 153 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
154 154
155 SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; 155 SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
156 reset_scoop(dev); 156 reset_scoop(&pdev->dev);
157 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; 157 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
158 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; 158 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
159 159
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index b0bbd1e62ebb..a2843be05557 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -20,6 +20,7 @@
20#include <linux/apm_bios.h> 20#include <linux/apm_bios.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/pm_legacy.h>
23#include <linux/device.h> 24#include <linux/device.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/list.h> 26#include <linux/list.h>
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e55ea952f7aa..373c0959bc2f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -256,9 +256,7 @@ void __cpuexit cpu_die(void)
256asmlinkage void __cpuinit secondary_start_kernel(void) 256asmlinkage void __cpuinit secondary_start_kernel(void)
257{ 257{
258 struct mm_struct *mm = &init_mm; 258 struct mm_struct *mm = &init_mm;
259 unsigned int cpu; 259 unsigned int cpu = smp_processor_id();
260
261 cpu = smp_processor_id();
262 260
263 printk("CPU%u: Booted secondary processor\n", cpu); 261 printk("CPU%u: Booted secondary processor\n", cpu);
264 262
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index dc09fd200c16..bbe6e4a0bf6a 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -132,14 +132,14 @@ void __init footbridge_init_irq(void)
132static struct map_desc fb_common_io_desc[] __initdata = { 132static struct map_desc fb_common_io_desc[] __initdata = {
133 { 133 {
134 .virtual = ARMCSR_BASE, 134 .virtual = ARMCSR_BASE,
135 .pfn = DC21285_ARMCSR_BASE, 135 .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE),
136 .length = ARMCSR_SIZE, 136 .length = ARMCSR_SIZE,
137 .type = MT_DEVICE 137 .type = MT_DEVICE,
138 }, { 138 }, {
139 .virtual = XBUS_BASE, 139 .virtual = XBUS_BASE,
140 .pfn = __phys_to_pfn(0x40000000), 140 .pfn = __phys_to_pfn(0x40000000),
141 .length = XBUS_SIZE, 141 .length = XBUS_SIZE,
142 .type = MT_DEVICE 142 .type = MT_DEVICE,
143 } 143 }
144}; 144};
145 145
@@ -153,28 +153,28 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
153 .virtual = PCIMEM_BASE, 153 .virtual = PCIMEM_BASE,
154 .pfn = __phys_to_pfn(DC21285_PCI_MEM), 154 .pfn = __phys_to_pfn(DC21285_PCI_MEM),
155 .length = PCIMEM_SIZE, 155 .length = PCIMEM_SIZE,
156 .type = MT_DEVICE 156 .type = MT_DEVICE,
157 }, { 157 }, {
158 .virtual = PCICFG0_BASE, 158 .virtual = PCICFG0_BASE,
159 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG), 159 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
160 .length = PCICFG0_SIZE, 160 .length = PCICFG0_SIZE,
161 .type = MT_DEVICE 161 .type = MT_DEVICE,
162 }, { 162 }, {
163 .virtual = PCICFG1_BASE, 163 .virtual = PCICFG1_BASE,
164 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG), 164 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
165 .length = PCICFG1_SIZE, 165 .length = PCICFG1_SIZE,
166 .type = MT_DEVICE 166 .type = MT_DEVICE,
167 }, { 167 }, {
168 .virtual = PCIIACK_BASE, 168 .virtual = PCIIACK_BASE,
169 .pfn = __phys_to_pfn(DC21285_PCI_IACK), 169 .pfn = __phys_to_pfn(DC21285_PCI_IACK),
170 .length = PCIIACK_SIZE, 170 .length = PCIIACK_SIZE,
171 .type = MT_DEVICE 171 .type = MT_DEVICE,
172 }, { 172 }, {
173 .virtual = PCIO_BASE, 173 .virtual = PCIO_BASE,
174 .pfn = __phys_to_pfn(DC21285_PCI_IO), 174 .pfn = __phys_to_pfn(DC21285_PCI_IO),
175 .length = PCIO_SIZE, 175 .length = PCIO_SIZE,
176 .type = MT_DEVICE 176 .type = MT_DEVICE,
177 } 177 },
178#endif 178#endif
179}; 179};
180 180
@@ -187,13 +187,13 @@ static struct map_desc co285_io_desc[] __initdata = {
187 .virtual = PCIO_BASE, 187 .virtual = PCIO_BASE,
188 .pfn = __phys_to_pfn(DC21285_PCI_IO), 188 .pfn = __phys_to_pfn(DC21285_PCI_IO),
189 .length = PCIO_SIZE, 189 .length = PCIO_SIZE,
190 .type = MT_DEVICE 190 .type = MT_DEVICE,
191 }, { 191 }, {
192 .virtual = PCIMEM_BASE, 192 .virtual = PCIMEM_BASE,
193 .pfn = __phys_to_pfn(DC21285_PCI_MEM), 193 .pfn = __phys_to_pfn(DC21285_PCI_MEM),
194 .length = PCIMEM_SIZE, 194 .length = PCIMEM_SIZE,
195 .type = MT_DEVICE 195 .type = MT_DEVICE,
196 } 196 },
197#endif 197#endif
198}; 198};
199 199
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e201aa9765b9..cd506646801a 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -72,6 +72,12 @@ config MACH_HUSKY
72 depends PXA_SHARPSL_25x 72 depends PXA_SHARPSL_25x
73 select PXA_SHARP_C7xx 73 select PXA_SHARP_C7xx
74 74
75config MACH_AKITA
76 bool "Enable Sharp SL-1000 (Akita) Support"
77 depends PXA_SHARPSL_27x
78 select PXA_SHARP_Cxx00
79 select MACH_SPITZ
80
75config MACH_SPITZ 81config MACH_SPITZ
76 bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" 82 bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
77 depends PXA_SHARPSL_27x 83 depends PXA_SHARPSL_27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index d210bd5032ce..32526a0a6f86 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,8 +11,9 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o 14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o 15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
16obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
16obj-$(CONFIG_MACH_POODLE) += poodle.o 17obj-$(CONFIG_MACH_POODLE) += poodle.o
17obj-$(CONFIG_MACH_TOSA) += tosa.o 18obj-$(CONFIG_MACH_TOSA) += tosa.o
18 19
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
new file mode 100644
index 000000000000..f6d73cc01f78
--- /dev/null
+++ b/arch/arm/mach-pxa/akita-ioexp.c
@@ -0,0 +1,223 @@
1/*
2 * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
3 * (uses a Maxim MAX7310 8 Port IO Expander)
4 *
5 * Copyright 2005 Openedhand Ltd.
6 *
7 * Author: Richard Purdie <richard@openedhand.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/i2c.h>
20#include <linux/slab.h>
21#include <linux/workqueue.h>
22#include <asm/arch/akita.h>
23
24/* MAX7310 Regiser Map */
25#define MAX7310_INPUT 0x00
26#define MAX7310_OUTPUT 0x01
27#define MAX7310_POLINV 0x02
28#define MAX7310_IODIR 0x03 /* 1 = Input, 0 = Output */
29#define MAX7310_TIMEOUT 0x04
30
31/* Addresses to scan */
32static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
33
34/* I2C Magic */
35I2C_CLIENT_INSMOD;
36
37static int max7310_write(struct i2c_client *client, int address, int data);
38static struct i2c_client max7310_template;
39static void akita_ioexp_work(void *private_);
40
41static struct device *akita_ioexp_device;
42static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
43DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);
44
45
46/*
47 * MAX7310 Access
48 */
49static int max7310_config(struct device *dev, int iomode, int polarity)
50{
51 int ret;
52 struct i2c_client *client = to_i2c_client(dev);
53
54 ret = max7310_write(client, MAX7310_POLINV, polarity);
55 if (ret < 0)
56 return ret;
57 ret = max7310_write(client, MAX7310_IODIR, iomode);
58 return ret;
59}
60
61static int max7310_set_ouputs(struct device *dev, int outputs)
62{
63 struct i2c_client *client = to_i2c_client(dev);
64
65 return max7310_write(client, MAX7310_OUTPUT, outputs);
66}
67
68/*
69 * I2C Functions
70 */
71static int max7310_write(struct i2c_client *client, int address, int value)
72{
73 u8 data[2];
74
75 data[0] = address & 0xff;
76 data[1] = value & 0xff;
77
78 if (i2c_master_send(client, data, 2) == 2)
79 return 0;
80 return -1;
81}
82
83static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
84{
85 struct i2c_client *new_client;
86 int err;
87
88 if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
89 return -ENOMEM;
90
91 max7310_template.adapter = adapter;
92 max7310_template.addr = address;
93
94 memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
95
96 if ((err = i2c_attach_client(new_client))) {
97 kfree(new_client);
98 return err;
99 }
100
101 max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
102 akita_ioexp_device = &new_client->dev;
103 schedule_work(&akita_ioexp);
104
105 return 0;
106}
107
108static int max7310_attach_adapter(struct i2c_adapter *adapter)
109{
110 return i2c_probe(adapter, &addr_data, max7310_detect);
111}
112
113static int max7310_detach_client(struct i2c_client *client)
114{
115 int err;
116
117 akita_ioexp_device = NULL;
118
119 if ((err = i2c_detach_client(client)))
120 return err;
121
122 kfree(client);
123 return 0;
124}
125
126static struct i2c_driver max7310_i2c_driver = {
127 .owner = THIS_MODULE,
128 .name = "akita-max7310",
129 .id = I2C_DRIVERID_AKITAIOEXP,
130 .flags = I2C_DF_NOTIFY,
131 .attach_adapter = max7310_attach_adapter,
132 .detach_client = max7310_detach_client,
133};
134
135static struct i2c_client max7310_template = {
136 name: "akita-max7310",
137 flags: I2C_CLIENT_ALLOW_USE,
138 driver: &max7310_i2c_driver,
139};
140
141void akita_set_ioexp(struct device *dev, unsigned char bit)
142{
143 ioexp_output_value |= bit;
144
145 if (akita_ioexp_device)
146 schedule_work(&akita_ioexp);
147 return;
148}
149
150void akita_reset_ioexp(struct device *dev, unsigned char bit)
151{
152 ioexp_output_value &= ~bit;
153
154 if (akita_ioexp_device)
155 schedule_work(&akita_ioexp);
156 return;
157}
158
159EXPORT_SYMBOL(akita_set_ioexp);
160EXPORT_SYMBOL(akita_reset_ioexp);
161
162static void akita_ioexp_work(void *private_)
163{
164 if (akita_ioexp_device)
165 max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
166}
167
168
169#ifdef CONFIG_PM
170static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
171{
172 flush_scheduled_work();
173 return 0;
174}
175
176static int akita_ioexp_resume(struct platform_device *pdev)
177{
178 schedule_work(&akita_ioexp);
179 return 0;
180}
181#else
182#define akita_ioexp_suspend NULL
183#define akita_ioexp_resume NULL
184#endif
185
186static int __init akita_ioexp_probe(struct platform_device *pdev)
187{
188 return i2c_add_driver(&max7310_i2c_driver);
189}
190
191static int akita_ioexp_remove(struct platform_device *pdev)
192{
193 i2c_del_driver(&max7310_i2c_driver);
194 return 0;
195}
196
197static struct platform_driver akita_ioexp_driver = {
198 .probe = akita_ioexp_probe,
199 .remove = akita_ioexp_remove,
200 .suspend = akita_ioexp_suspend,
201 .resume = akita_ioexp_resume,
202 .driver = {
203 .name = "akita-ioexp",
204 },
205};
206
207static int __init akita_ioexp_init(void)
208{
209 return platform_driver_register(&akita_ioexp_driver);
210}
211
212static void __exit akita_ioexp_exit(void)
213{
214 platform_driver_unregister(&akita_ioexp_driver);
215}
216
217MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
218MODULE_DESCRIPTION("Akita IO-Expander driver");
219MODULE_LICENSE("GPL");
220
221fs_initcall(akita_ioexp_init);
222module_exit(akita_ioexp_exit);
223
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
new file mode 100644
index 000000000000..599be14754f9
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -0,0 +1,228 @@
1/*
2 * Battery and Power Management code for the Sharp SL-C7xx
3 *
4 * Copyright (c) 2005 Richard Purdie
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/stat.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <asm/apm.h>
20#include <asm/irq.h>
21#include <asm/mach-types.h>
22#include <asm/hardware.h>
23#include <asm/hardware/scoop.h>
24
25#include <asm/arch/sharpsl.h>
26#include <asm/arch/corgi.h>
27#include <asm/arch/pxa-regs.h>
28#include "sharpsl.h"
29
30static void corgi_charger_init(void)
31{
32 pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
33 pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
34 pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
35 pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
36}
37
38static void corgi_charge_led(int val)
39{
40 if (val == SHARPSL_LED_ERROR) {
41 dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
42 } else if (val == SHARPSL_LED_ON) {
43 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
44 GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
45 } else {
46 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
47 GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
48 }
49}
50
51static void corgi_measure_temp(int on)
52{
53 if (on)
54 GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
55 else
56 GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
57}
58
59static void corgi_charge(int on)
60{
61 if (on) {
62 if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
63 GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
64 GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
65 } else {
66 GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
67 GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
68 }
69 } else {
70 GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
71 GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
72 }
73}
74
75static void corgi_discharge(int on)
76{
77 if (on)
78 GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
79 else
80 GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
81}
82
83static void corgi_presuspend(void)
84{
85 int i;
86 unsigned long wakeup_mask;
87
88 /* charging , so CHARGE_ON bit is HIGH during OFF. */
89 if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
90 PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
91 else
92 PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
93
94 if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
95 PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
96 else
97 PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
98
99 if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
100 PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
101 else
102 PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
103
104 /* Resume on keyboard power key */
105 PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
106
107 wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
108
109 if (!machine_is_corgi())
110 wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
111
112 PWER = wakeup_mask | PWER_RTC;
113 PRER = wakeup_mask;
114 PFER = wakeup_mask;
115
116 for (i = 0; i <=15; i++) {
117 if (PRER & PFER & GPIO_bit(i)) {
118 if (GPLR0 & GPIO_bit(i) )
119 PRER &= ~GPIO_bit(i);
120 else
121 PFER &= ~GPIO_bit(i);
122 }
123 }
124}
125
126static void corgi_postsuspend(void)
127{
128}
129
130/*
131 * Check what brought us out of the suspend.
132 * Return: 0 to sleep, otherwise wake
133 */
134static int corgi_should_wakeup(unsigned int resume_on_alarm)
135{
136 int is_resume = 0;
137
138 dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
139
140 if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
141 if (STATUS_AC_IN()) {
142 /* charge on */
143 dev_dbg(sharpsl_pm.dev, "ac insert\n");
144 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
145 } else {
146 /* charge off */
147 dev_dbg(sharpsl_pm.dev, "ac remove\n");
148 CHARGE_LED_OFF();
149 CHARGE_OFF();
150 sharpsl_pm.charge_mode = CHRG_OFF;
151 }
152 }
153
154 if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL)))
155 dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
156
157 if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT))
158 is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
159
160 if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP))
161 is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
162
163 if (resume_on_alarm && (PEDR & PWER_RTC))
164 is_resume |= PWER_RTC;
165
166 dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
167 return is_resume;
168}
169
170static unsigned long corgi_charger_wakeup(void)
171{
172 return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
173}
174
175static int corgi_acin_status(void)
176{
177 return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
178}
179
180static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
181 .init = corgi_charger_init,
182 .gpio_batlock = CORGI_GPIO_BAT_COVER,
183 .gpio_acin = CORGI_GPIO_AC_IN,
184 .gpio_batfull = CORGI_GPIO_CHRG_FULL,
185 .status_acin = corgi_acin_status,
186 .discharge = corgi_discharge,
187 .charge = corgi_charge,
188 .chargeled = corgi_charge_led,
189 .measure_temp = corgi_measure_temp,
190 .presuspend = corgi_presuspend,
191 .postsuspend = corgi_postsuspend,
192 .charger_wakeup = corgi_charger_wakeup,
193 .should_wakeup = corgi_should_wakeup,
194 .bat_levels = 40,
195 .bat_levels_noac = spitz_battery_levels_noac,
196 .bat_levels_acin = spitz_battery_levels_acin,
197 .status_high_acin = 188,
198 .status_low_acin = 178,
199 .status_high_noac = 185,
200 .status_low_noac = 175,
201};
202
203static struct platform_device *corgipm_device;
204
205static int __devinit corgipm_init(void)
206{
207 int ret;
208
209 corgipm_device = platform_device_alloc("sharpsl-pm", -1);
210 if (!corgipm_device)
211 return -ENOMEM;
212
213 corgipm_device->dev.platform_data = &corgi_pm_machinfo;
214 ret = platform_device_add(corgipm_device);
215
216 if (ret)
217 platform_device_put(corgipm_device);
218
219 return ret;
220}
221
222static void corgipm_exit(void)
223{
224 platform_device_unregister(corgipm_device);
225}
226
227module_init(corgipm_init);
228module_exit(corgipm_exit);
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 4879c0f7da72..b0c40a1d6671 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -115,7 +115,7 @@ extern struct battery_thresh spitz_battery_levels_noac[];
115#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR) 115#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
116#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1) 116#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
117#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0) 117#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
118#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin() 118#define STATUS_AC_IN() sharpsl_pm.machinfo->status_acin()
119#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock) 119#define STATUS_BATT_LOCKED() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
120#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull) 120#define STATUS_CHRG_FULL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
121#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal) 121#define STATUS_FATAL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 6c9e871c53d8..c10be00fb526 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -21,7 +21,7 @@
21#include <linux/apm_bios.h> 21#include <linux/apm_bios.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/hardware.h> 26#include <asm/hardware.h>
27#include <asm/hardware/scoop.h> 27#include <asm/hardware/scoop.h>
@@ -45,15 +45,15 @@
45#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ 45#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
46#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ 46#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
47#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ 47#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
48#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */ 48#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */
49#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ 49#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
50#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ 50#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
51#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ 51#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
52 52
53#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ 53#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
54#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ 54#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
55#define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */ 55#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */
56#define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */ 56#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */
57#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ 57#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
58#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ 58#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
59 59
@@ -160,9 +160,10 @@ struct battery_thresh spitz_battery_levels_noac[] = {
160/* 160/*
161 * Prototypes 161 * Prototypes
162 */ 162 */
163static int sharpsl_read_MainBattery(void); 163static int sharpsl_read_main_battery(void);
164static int sharpsl_off_charge_battery(void); 164static int sharpsl_off_charge_battery(void);
165static int sharpsl_check_battery(int mode); 165static int sharpsl_check_battery_temp(void);
166static int sharpsl_check_battery_voltage(void);
166static int sharpsl_ac_check(void); 167static int sharpsl_ac_check(void);
167static int sharpsl_fatal_check(void); 168static int sharpsl_fatal_check(void);
168static int sharpsl_average_value(int ad); 169static int sharpsl_average_value(int ad);
@@ -228,7 +229,7 @@ static void sharpsl_battery_thread(void *private_)
228 if (!sharpsl_pm.machinfo) 229 if (!sharpsl_pm.machinfo)
229 return; 230 return;
230 231
231 sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE); 232 sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE);
232 233
233 /* Corgi cannot confirm when battery fully charged so periodically kick! */ 234 /* Corgi cannot confirm when battery fully charged so periodically kick! */
234 if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) 235 if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
@@ -236,7 +237,7 @@ static void sharpsl_battery_thread(void *private_)
236 schedule_work(&toggle_charger); 237 schedule_work(&toggle_charger);
237 238
238 while(1) { 239 while(1) {
239 voltage = sharpsl_read_MainBattery(); 240 voltage = sharpsl_read_main_battery();
240 if (voltage > 0) break; 241 if (voltage > 0) break;
241 if (i++ > 5) { 242 if (i++ > 5) {
242 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; 243 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
@@ -317,10 +318,10 @@ static void sharpsl_charge_toggle(void *private_)
317{ 318{
318 dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); 319 dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
319 320
320 if (STATUS_AC_IN == 0) { 321 if (STATUS_AC_IN() == 0) {
321 sharpsl_charge_off(); 322 sharpsl_charge_off();
322 return; 323 return;
323 } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) { 324 } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
324 sharpsl_charge_error(); 325 sharpsl_charge_error();
325 return; 326 return;
326 } 327 }
@@ -335,7 +336,7 @@ static void sharpsl_charge_toggle(void *private_)
335 336
336static void sharpsl_ac_timer(unsigned long data) 337static void sharpsl_ac_timer(unsigned long data)
337{ 338{
338 int acin = STATUS_AC_IN; 339 int acin = STATUS_AC_IN();
339 340
340 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin); 341 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
341 342
@@ -364,7 +365,7 @@ static void sharpsl_chrg_full_timer(unsigned long data)
364 365
365 sharpsl_pm.full_count++; 366 sharpsl_pm.full_count++;
366 367
367 if (STATUS_AC_IN == 0) { 368 if (STATUS_AC_IN() == 0) {
368 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); 369 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
369 if (sharpsl_pm.charge_mode == CHRG_ON) 370 if (sharpsl_pm.charge_mode == CHRG_ON)
370 sharpsl_charge_off(); 371 sharpsl_charge_off();
@@ -399,12 +400,12 @@ static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
399{ 400{
400 int is_fatal = 0; 401 int is_fatal = 0;
401 402
402 if (STATUS_BATT_LOCKED == 0) { 403 if (STATUS_BATT_LOCKED() == 0) {
403 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); 404 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
404 is_fatal = 1; 405 is_fatal = 1;
405 } 406 }
406 407
407 if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) { 408 if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) {
408 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); 409 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
409 is_fatal = 1; 410 is_fatal = 1;
410 } 411 }
@@ -461,12 +462,12 @@ static int read_max1111(int channel)
461 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); 462 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
462} 463}
463 464
464static int sharpsl_read_MainBattery(void) 465static int sharpsl_read_main_battery(void)
465{ 466{
466 return read_max1111(BATT_AD); 467 return read_max1111(BATT_AD);
467} 468}
468 469
469static int sharpsl_read_Temp(void) 470static int sharpsl_read_temp(void)
470{ 471{
471 int temp; 472 int temp;
472 473
@@ -480,7 +481,7 @@ static int sharpsl_read_Temp(void)
480 return temp; 481 return temp;
481} 482}
482 483
483static int sharpsl_read_jkvad(void) 484static int sharpsl_read_acin(void)
484{ 485{
485 return read_max1111(JK_VAD); 486 return read_max1111(JK_VAD);
486} 487}
@@ -522,16 +523,14 @@ static int get_select_val(int *val)
522 return (sum/3); 523 return (sum/3);
523} 524}
524 525
525/* mode 0 - Check temperature and voltage 526static int sharpsl_check_battery_temp(void)
526 * 1 - Check temperature only */
527static int sharpsl_check_battery(int mode)
528{ 527{
529 int val, i, buff[5]; 528 int val, i, buff[5];
530 529
531 /* Check battery temperature */ 530 /* Check battery temperature */
532 for (i=0; i<5; i++) { 531 for (i=0; i<5; i++) {
533 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); 532 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
534 buff[i] = sharpsl_read_Temp(); 533 buff[i] = sharpsl_read_temp();
535 } 534 }
536 535
537 val = get_select_val(buff); 536 val = get_select_val(buff);
@@ -539,8 +538,13 @@ static int sharpsl_check_battery(int mode)
539 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); 538 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
540 if (val > SHARPSL_CHARGE_ON_TEMP) 539 if (val > SHARPSL_CHARGE_ON_TEMP)
541 return -1; 540 return -1;
542 if (mode == 1) 541
543 return 0; 542 return 0;
543}
544
545static int sharpsl_check_battery_voltage(void)
546{
547 int val, i, buff[5];
544 548
545 /* disable charge, enable discharge */ 549 /* disable charge, enable discharge */
546 CHARGE_OFF(); 550 CHARGE_OFF();
@@ -552,7 +556,7 @@ static int sharpsl_check_battery(int mode)
552 556
553 /* Check battery voltage */ 557 /* Check battery voltage */
554 for (i=0; i<5; i++) { 558 for (i=0; i<5; i++) {
555 buff[i] = sharpsl_read_MainBattery(); 559 buff[i] = sharpsl_read_main_battery();
556 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 560 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
557 } 561 }
558 562
@@ -575,14 +579,14 @@ static int sharpsl_ac_check(void)
575 int temp, i, buff[5]; 579 int temp, i, buff[5];
576 580
577 for (i=0; i<5; i++) { 581 for (i=0; i<5; i++) {
578 buff[i] = sharpsl_read_jkvad(); 582 buff[i] = sharpsl_read_acin();
579 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD); 583 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
580 } 584 }
581 585
582 temp = get_select_val(buff); 586 temp = get_select_val(buff);
583 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp); 587 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
584 588
585 if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) { 589 if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
586 dev_err(sharpsl_pm.dev, "Error: AC check failed.\n"); 590 dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
587 return -1; 591 return -1;
588 } 592 }
@@ -591,7 +595,7 @@ static int sharpsl_ac_check(void)
591} 595}
592 596
593#ifdef CONFIG_PM 597#ifdef CONFIG_PM
594static int sharpsl_pm_suspend(struct device *dev, pm_message_t state) 598static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
595{ 599{
596 sharpsl_pm.flags |= SHARPSL_SUSPENDED; 600 sharpsl_pm.flags |= SHARPSL_SUSPENDED;
597 flush_scheduled_work(); 601 flush_scheduled_work();
@@ -604,7 +608,7 @@ static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
604 return 0; 608 return 0;
605} 609}
606 610
607static int sharpsl_pm_resume(struct device *dev) 611static int sharpsl_pm_resume(struct platform_device *pdev)
608{ 612{
609 /* Clear the reset source indicators as they break the bootloader upon reboot */ 613 /* Clear the reset source indicators as they break the bootloader upon reboot */
610 RCSR = 0x0f; 614 RCSR = 0x0f;
@@ -622,7 +626,7 @@ static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable
622 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); 626 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
623 /* not charging and AC-IN! */ 627 /* not charging and AC-IN! */
624 628
625 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) { 629 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) {
626 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); 630 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
627 sharpsl_pm.charge_mode = CHRG_OFF; 631 sharpsl_pm.charge_mode = CHRG_OFF;
628 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 632 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
@@ -671,7 +675,7 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
671 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); 675 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
672 } 676 }
673 677
674 if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) ) 678 if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) )
675 { 679 {
676 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); 680 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
677 corgi_goto_sleep(alarm_time, alarm_enable, state); 681 corgi_goto_sleep(alarm_time, alarm_enable, state);
@@ -711,7 +715,7 @@ static int sharpsl_fatal_check(void)
711 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); 715 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
712 716
713 /* Check AC-Adapter */ 717 /* Check AC-Adapter */
714 acin = STATUS_AC_IN; 718 acin = STATUS_AC_IN();
715 719
716 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 720 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
717 CHARGE_OFF(); 721 CHARGE_OFF();
@@ -725,7 +729,7 @@ static int sharpsl_fatal_check(void)
725 729
726 /* Check battery : check inserting battery ? */ 730 /* Check battery : check inserting battery ? */
727 for (i=0; i<5; i++) { 731 for (i=0; i<5; i++) {
728 buff[i] = sharpsl_read_MainBattery(); 732 buff[i] = sharpsl_read_main_battery();
729 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 733 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
730 } 734 }
731 735
@@ -739,7 +743,7 @@ static int sharpsl_fatal_check(void)
739 } 743 }
740 744
741 temp = get_select_val(buff); 745 temp = get_select_val(buff);
742 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery()); 746 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery());
743 747
744 if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) || 748 if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
745 (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT))) 749 (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
@@ -771,7 +775,7 @@ static int sharpsl_off_charge_battery(void)
771 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); 775 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
772 776
773 /* AC Check */ 777 /* AC Check */
774 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0)) 778 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
775 return sharpsl_off_charge_error(); 779 return sharpsl_off_charge_error();
776 780
777 /* Start Charging */ 781 /* Start Charging */
@@ -793,7 +797,7 @@ static int sharpsl_off_charge_battery(void)
793 797
794 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); 798 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
795 799
796 if (sharpsl_check_battery(0) < 0) 800 if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
797 return sharpsl_off_charge_error(); 801 return sharpsl_off_charge_error();
798 802
799 CHARGE_OFF(); 803 CHARGE_OFF();
@@ -811,7 +815,7 @@ static int sharpsl_off_charge_battery(void)
811 /* Check for timeout */ 815 /* Check for timeout */
812 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) 816 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
813 return 1; 817 return 1;
814 if (STATUS_CHRG_FULL) { 818 if (STATUS_CHRG_FULL()) {
815 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n"); 819 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
816 sharpsl_pm.full_count++; 820 sharpsl_pm.full_count++;
817 CHARGE_OFF(); 821 CHARGE_OFF();
@@ -840,7 +844,7 @@ static int sharpsl_off_charge_battery(void)
840 sharpsl_pm.full_count++; 844 sharpsl_pm.full_count++;
841 return 1; 845 return 1;
842 } 846 }
843 if (STATUS_CHRG_FULL) { 847 if (STATUS_CHRG_FULL()) {
844 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); 848 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
845 CHARGE_LED_OFF(); 849 CHARGE_LED_OFF();
846 CHARGE_OFF(); 850 CHARGE_OFF();
@@ -886,13 +890,13 @@ static struct pm_ops sharpsl_pm_ops = {
886 .finish = pxa_pm_finish, 890 .finish = pxa_pm_finish,
887}; 891};
888 892
889static int __init sharpsl_pm_probe(struct device *dev) 893static int __init sharpsl_pm_probe(struct platform_device *pdev)
890{ 894{
891 if (!dev->platform_data) 895 if (!pdev->dev.platform_data)
892 return -EINVAL; 896 return -EINVAL;
893 897
894 sharpsl_pm.dev = dev; 898 sharpsl_pm.dev = &pdev->dev;
895 sharpsl_pm.machinfo = dev->platform_data; 899 sharpsl_pm.machinfo = pdev->dev.platform_data;
896 sharpsl_pm.charge_mode = CHRG_OFF; 900 sharpsl_pm.charge_mode = CHRG_OFF;
897 sharpsl_pm.flags = 0; 901 sharpsl_pm.flags = 0;
898 902
@@ -935,8 +939,8 @@ static int __init sharpsl_pm_probe(struct device *dev)
935 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); 939 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
936 } 940 }
937 941
938 device_create_file(dev, &dev_attr_battery_percentage); 942 device_create_file(&pdev->dev, &dev_attr_battery_percentage);
939 device_create_file(dev, &dev_attr_battery_voltage); 943 device_create_file(&pdev->dev, &dev_attr_battery_voltage);
940 944
941 apm_get_power_status = sharpsl_apm_get_power_status; 945 apm_get_power_status = sharpsl_apm_get_power_status;
942 946
@@ -947,12 +951,12 @@ static int __init sharpsl_pm_probe(struct device *dev)
947 return 0; 951 return 0;
948} 952}
949 953
950static int sharpsl_pm_remove(struct device *dev) 954static int sharpsl_pm_remove(struct platform_device *pdev)
951{ 955{
952 pm_set_ops(NULL); 956 pm_set_ops(NULL);
953 957
954 device_remove_file(dev, &dev_attr_battery_percentage); 958 device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
955 device_remove_file(dev, &dev_attr_battery_voltage); 959 device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
956 960
957 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); 961 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
958 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); 962 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
@@ -969,23 +973,24 @@ static int sharpsl_pm_remove(struct device *dev)
969 return 0; 973 return 0;
970} 974}
971 975
972static struct device_driver sharpsl_pm_driver = { 976static struct platform_driver sharpsl_pm_driver = {
973 .name = "sharpsl-pm",
974 .bus = &platform_bus_type,
975 .probe = sharpsl_pm_probe, 977 .probe = sharpsl_pm_probe,
976 .remove = sharpsl_pm_remove, 978 .remove = sharpsl_pm_remove,
977 .suspend = sharpsl_pm_suspend, 979 .suspend = sharpsl_pm_suspend,
978 .resume = sharpsl_pm_resume, 980 .resume = sharpsl_pm_resume,
981 .driver = {
982 .name = "sharpsl-pm",
983 },
979}; 984};
980 985
981static int __devinit sharpsl_pm_init(void) 986static int __devinit sharpsl_pm_init(void)
982{ 987{
983 return driver_register(&sharpsl_pm_driver); 988 return platform_driver_register(&sharpsl_pm_driver);
984} 989}
985 990
986static void sharpsl_pm_exit(void) 991static void sharpsl_pm_exit(void)
987{ 992{
988 driver_unregister(&sharpsl_pm_driver); 993 platform_driver_unregister(&sharpsl_pm_driver);
989} 994}
990 995
991late_initcall(sharpsl_pm_init); 996late_initcall(sharpsl_pm_init);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4e9a699ee428..2df1b56615b1 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -345,6 +345,16 @@ static void spitz_irda_transceiver_mode(struct device *dev, int mode)
345 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); 345 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
346} 346}
347 347
348#ifdef CONFIG_MACH_AKITA
349static void akita_irda_transceiver_mode(struct device *dev, int mode)
350{
351 if (mode & IR_OFF)
352 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
353 else
354 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
355}
356#endif
357
348static struct pxaficp_platform_data spitz_ficp_platform_data = { 358static struct pxaficp_platform_data spitz_ficp_platform_data = {
349 .transceiver_cap = IR_SIRMODE | IR_OFF, 359 .transceiver_cap = IR_SIRMODE | IR_OFF,
350 .transceiver_mode = spitz_irda_transceiver_mode, 360 .transceiver_mode = spitz_irda_transceiver_mode,
@@ -417,6 +427,32 @@ static void __init spitz_init(void)
417 platform_device_register(&spitzscoop2_device); 427 platform_device_register(&spitzscoop2_device);
418} 428}
419 429
430#ifdef CONFIG_MACH_AKITA
431/*
432 * Akita IO Expander
433 */
434struct platform_device akitaioexp_device = {
435 .name = "akita-ioexp",
436 .id = -1,
437};
438
439static void __init akita_init(void)
440{
441 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
442
443 /* We just pretend the second element of the array doesn't exist */
444 spitz_pcmcia_config.num_devs = 1;
445 platform_scoop_config = &spitz_pcmcia_config;
446 spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity;
447
448 platform_device_register(&akitaioexp_device);
449
450 spitzscoop_device.dev.parent = &akitaioexp_device.dev;
451 common_init();
452}
453#endif
454
455
420static void __init fixup_spitz(struct machine_desc *desc, 456static void __init fixup_spitz(struct machine_desc *desc,
421 struct tag *tags, char **cmdline, struct meminfo *mi) 457 struct tag *tags, char **cmdline, struct meminfo *mi)
422{ 458{
@@ -452,3 +488,16 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
452 .timer = &pxa_timer, 488 .timer = &pxa_timer,
453MACHINE_END 489MACHINE_END
454#endif 490#endif
491
492#ifdef CONFIG_MACH_AKITA
493MACHINE_START(AKITA, "SHARP Akita")
494 .phys_ram = 0xa0000000,
495 .phys_io = 0x40000000,
496 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
497 .fixup = fixup_spitz,
498 .map_io = pxa_map_io,
499 .init_irq = pxa_init_irq,
500 .init_machine = akita_init,
501 .timer = &pxa_timer,
502MACHINE_END
503#endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
new file mode 100644
index 000000000000..3ce7486daa51
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -0,0 +1,233 @@
1/*
2 * Battery and Power Management code for the Sharp SL-Cxx00
3 *
4 * Copyright (c) 2005 Richard Purdie
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/stat.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <asm/apm.h>
20#include <asm/irq.h>
21#include <asm/mach-types.h>
22#include <asm/hardware.h>
23#include <asm/hardware/scoop.h>
24
25#include <asm/arch/sharpsl.h>
26#include <asm/arch/spitz.h>
27#include <asm/arch/pxa-regs.h>
28#include "sharpsl.h"
29
30static int spitz_last_ac_status;
31
32static void spitz_charger_init(void)
33{
34 pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
35 pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
36}
37
38static void spitz_charge_led(int val)
39{
40 if (val == SHARPSL_LED_ERROR) {
41 dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
42 } else if (val == SHARPSL_LED_ON) {
43 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
44 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
45 } else {
46 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
47 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
48 }
49}
50
51static void spitz_measure_temp(int on)
52{
53 if (on)
54 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
55 else
56 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
57}
58
59static void spitz_charge(int on)
60{
61 if (on) {
62 if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
63 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
64 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
65 } else {
66 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
67 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
68 }
69 } else {
70 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
71 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
72 }
73}
74
75static void spitz_discharge(int on)
76{
77 if (on)
78 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
79 else
80 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
81}
82
83/* HACK - For unknown reasons, accurate voltage readings are only made with a load
84 on the power bus which the green led on spitz provides */
85static void spitz_discharge1(int on)
86{
87 if (on)
88 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
89 else
90 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
91}
92
93static void spitz_presuspend(void)
94{
95 spitz_last_ac_status = STATUS_AC_IN();
96
97 /* GPIO Sleep Register */
98 PGSR0 = 0x00144018;
99 PGSR1 = 0x00EF0000;
100 if (machine_is_akita()) {
101 PGSR2 = 0x2121C000;
102 PGSR3 = 0x00600400;
103 } else {
104 PGSR2 = 0x0121C000;
105 PGSR3 = 0x00600000;
106 }
107
108 PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
109 PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
110 PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
111 PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
112 PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
113
114 pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
115
116 PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
117 PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
118 PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
119 PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
120 PKSR = 0xffffffff; // clear
121
122 /* nRESET_OUT Disable */
123 PSLR |= PSLR_SL_ROD;
124
125 /* Clear reset status */
126 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
127
128 /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
129 PCFR = PCFR_GPR_EN | PCFR_OPDE;
130}
131
132static void spitz_postsuspend(void)
133{
134 pxa_gpio_mode(GPIO18_RDY_MD);
135 pxa_gpio_mode(10 | GPIO_IN);
136}
137
138static int spitz_should_wakeup(unsigned int resume_on_alarm)
139{
140 int is_resume = 0;
141 int acin = STATUS_AC_IN();
142
143 if (spitz_last_ac_status != acin) {
144 if (acin) {
145 /* charge on */
146 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
147 dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
148 } else {
149 /* charge off */
150 dev_dbg(sharpsl_pm.dev, "AC Removed\n");
151 CHARGE_LED_OFF();
152 CHARGE_OFF();
153 sharpsl_pm.charge_mode = CHRG_OFF;
154 }
155 spitz_last_ac_status = acin;
156 /* Return to suspend as this must be what we were woken for */
157 return 0;
158 }
159
160 if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
161 is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
162
163 if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
164 is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
165
166 if (resume_on_alarm && (PEDR & PWER_RTC))
167 is_resume |= PWER_RTC;
168
169 dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
170 return is_resume;
171}
172
173static unsigned long spitz_charger_wakeup(void)
174{
175 return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
176}
177
178static int spitz_acin_status(void)
179{
180 return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
181}
182
183struct sharpsl_charger_machinfo spitz_pm_machinfo = {
184 .init = spitz_charger_init,
185 .gpio_batlock = SPITZ_GPIO_BAT_COVER,
186 .gpio_acin = SPITZ_GPIO_AC_IN,
187 .gpio_batfull = SPITZ_GPIO_CHRG_FULL,
188 .gpio_fatal = SPITZ_GPIO_FATAL_BAT,
189 .status_acin = spitz_acin_status,
190 .discharge = spitz_discharge,
191 .discharge1 = spitz_discharge1,
192 .charge = spitz_charge,
193 .chargeled = spitz_charge_led,
194 .measure_temp = spitz_measure_temp,
195 .presuspend = spitz_presuspend,
196 .postsuspend = spitz_postsuspend,
197 .charger_wakeup = spitz_charger_wakeup,
198 .should_wakeup = spitz_should_wakeup,
199 .bat_levels = 40,
200 .bat_levels_noac = spitz_battery_levels_noac,
201 .bat_levels_acin = spitz_battery_levels_acin,
202 .status_high_acin = 188,
203 .status_low_acin = 178,
204 .status_high_noac = 185,
205 .status_low_noac = 175,
206};
207
208static struct platform_device *spitzpm_device;
209
210static int __devinit spitzpm_init(void)
211{
212 int ret;
213
214 spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
215 if (!spitzpm_device)
216 return -ENOMEM;
217
218 spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
219 ret = platform_device_add(spitzpm_device);
220
221 if (ret)
222 platform_device_put(spitzpm_device);
223
224 return ret;
225}
226
227static void spitzpm_exit(void)
228{
229 platform_device_unregister(spitzpm_device);
230}
231
232module_init(spitzpm_init);
233module_exit(spitzpm_exit);
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 1a1e8a119c3d..712c3c24c954 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -14,6 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pm.h> 16#include <linux/pm.h>
17#include <linux/pm_legacy.h>
17#include <linux/sched.h> 18#include <linux/sched.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/sysctl.h> 20#include <linux/sysctl.h>
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index dbf90ad6eac3..6004bb0795e0 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -699,7 +699,7 @@ depends on PM && !X86_VISWS
699 699
700config APM 700config APM
701 tristate "APM (Advanced Power Management) BIOS support" 701 tristate "APM (Advanced Power Management) BIOS support"
702 depends on PM 702 depends on PM && PM_LEGACY
703 ---help--- 703 ---help---
704 APM is a BIOS specification for saving power using several different 704 APM is a BIOS specification for saving power using several different
705 techniques. This is mostly useful for battery powered laptops with 705 techniques. This is mostly useful for battery powered laptops with
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index b66c13c0cc0f..f36677241ecd 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -39,17 +39,14 @@
39 39
40#ifdef CONFIG_X86_64 40#ifdef CONFIG_X86_64
41 41
42static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
43{
44}
45extern void __init clustered_apic_check(void); 42extern void __init clustered_apic_check(void);
46static inline int ioapic_setup_disabled(void)
47{
48 return 0;
49}
50 43
44extern int gsi_irq_sharing(int gsi);
51#include <asm/proto.h> 45#include <asm/proto.h>
52 46
47static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
48
49
53#else /* X86 */ 50#else /* X86 */
54 51
55#ifdef CONFIG_X86_LOCAL_APIC 52#ifdef CONFIG_X86_LOCAL_APIC
@@ -57,6 +54,8 @@ static inline int ioapic_setup_disabled(void)
57#include <mach_mpparse.h> 54#include <mach_mpparse.h>
58#endif /* CONFIG_X86_LOCAL_APIC */ 55#endif /* CONFIG_X86_LOCAL_APIC */
59 56
57static inline int gsi_irq_sharing(int gsi) { return gsi; }
58
60#endif /* X86 */ 59#endif /* X86 */
61 60
62#define BAD_MADT_ENTRY(entry, end) ( \ 61#define BAD_MADT_ENTRY(entry, end) ( \
@@ -459,7 +458,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
459 *irq = IO_APIC_VECTOR(gsi); 458 *irq = IO_APIC_VECTOR(gsi);
460 else 459 else
461#endif 460#endif
462 *irq = gsi; 461 *irq = gsi_irq_sharing(gsi);
463 return 0; 462 return 0;
464} 463}
465 464
@@ -543,7 +542,7 @@ acpi_scan_rsdp(unsigned long start, unsigned long length)
543 * RSDP signature. 542 * RSDP signature.
544 */ 543 */
545 for (offset = 0; offset < length; offset += 16) { 544 for (offset = 0; offset < length; offset += 16) {
546 if (strncmp((char *)(start + offset), "RSD PTR ", sig_len)) 545 if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
547 continue; 546 continue;
548 return (start + offset); 547 return (start + offset);
549 } 548 }
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 003548b8735f..1e60acbed3c1 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -218,6 +218,7 @@
218#include <linux/time.h> 218#include <linux/time.h>
219#include <linux/sched.h> 219#include <linux/sched.h>
220#include <linux/pm.h> 220#include <linux/pm.h>
221#include <linux/pm_legacy.h>
221#include <linux/device.h> 222#include <linux/device.h>
222#include <linux/kernel.h> 223#include <linux/kernel.h>
223#include <linux/smp.h> 224#include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 53a1681cd964..e344ef88cfcd 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -206,9 +206,9 @@ static void __init init_amd(struct cpuinfo_x86 *c)
206 display_cacheinfo(c); 206 display_cacheinfo(c);
207 207
208 if (cpuid_eax(0x80000000) >= 0x80000008) { 208 if (cpuid_eax(0x80000000) >= 0x80000008) {
209 c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; 209 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
210 if (c->x86_num_cores & (c->x86_num_cores - 1)) 210 if (c->x86_max_cores & (c->x86_max_cores - 1))
211 c->x86_num_cores = 1; 211 c->x86_max_cores = 1;
212 } 212 }
213 213
214#ifdef CONFIG_X86_HT 214#ifdef CONFIG_X86_HT
@@ -217,15 +217,15 @@ static void __init init_amd(struct cpuinfo_x86 *c)
217 * distingush the cores. Assumes number of cores is a power 217 * distingush the cores. Assumes number of cores is a power
218 * of two. 218 * of two.
219 */ 219 */
220 if (c->x86_num_cores > 1) { 220 if (c->x86_max_cores > 1) {
221 int cpu = smp_processor_id(); 221 int cpu = smp_processor_id();
222 unsigned bits = 0; 222 unsigned bits = 0;
223 while ((1 << bits) < c->x86_num_cores) 223 while ((1 << bits) < c->x86_max_cores)
224 bits++; 224 bits++;
225 cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1); 225 cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
226 phys_proc_id[cpu] >>= bits; 226 phys_proc_id[cpu] >>= bits;
227 printk(KERN_INFO "CPU %d(%d) -> Core %d\n", 227 printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
228 cpu, c->x86_num_cores, cpu_core_id[cpu]); 228 cpu, c->x86_max_cores, cpu_core_id[cpu]);
229 } 229 }
230#endif 230#endif
231} 231}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index c145fb30002e..31e344b26bae 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -231,10 +231,10 @@ static void __init early_cpu_detect(void)
231 cpuid(0x00000001, &tfms, &misc, &junk, &cap0); 231 cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
232 c->x86 = (tfms >> 8) & 15; 232 c->x86 = (tfms >> 8) & 15;
233 c->x86_model = (tfms >> 4) & 15; 233 c->x86_model = (tfms >> 4) & 15;
234 if (c->x86 == 0xf) { 234 if (c->x86 == 0xf)
235 c->x86 += (tfms >> 20) & 0xff; 235 c->x86 += (tfms >> 20) & 0xff;
236 if (c->x86 >= 0x6)
236 c->x86_model += ((tfms >> 16) & 0xF) << 4; 237 c->x86_model += ((tfms >> 16) & 0xF) << 4;
237 }
238 c->x86_mask = tfms & 15; 238 c->x86_mask = tfms & 15;
239 if (cap0 & (1<<19)) 239 if (cap0 & (1<<19))
240 c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; 240 c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
@@ -333,7 +333,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
333 c->x86_model = c->x86_mask = 0; /* So far unknown... */ 333 c->x86_model = c->x86_mask = 0; /* So far unknown... */
334 c->x86_vendor_id[0] = '\0'; /* Unset */ 334 c->x86_vendor_id[0] = '\0'; /* Unset */
335 c->x86_model_id[0] = '\0'; /* Unset */ 335 c->x86_model_id[0] = '\0'; /* Unset */
336 c->x86_num_cores = 1; 336 c->x86_max_cores = 1;
337 memset(&c->x86_capability, 0, sizeof c->x86_capability); 337 memset(&c->x86_capability, 0, sizeof c->x86_capability);
338 338
339 if (!have_cpuid_p()) { 339 if (!have_cpuid_p()) {
@@ -443,52 +443,44 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
443void __devinit detect_ht(struct cpuinfo_x86 *c) 443void __devinit detect_ht(struct cpuinfo_x86 *c)
444{ 444{
445 u32 eax, ebx, ecx, edx; 445 u32 eax, ebx, ecx, edx;
446 int index_msb, tmp; 446 int index_msb, core_bits;
447 int cpu = smp_processor_id(); 447 int cpu = smp_processor_id();
448 448
449 cpuid(1, &eax, &ebx, &ecx, &edx);
450
451 c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
452
449 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 453 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
450 return; 454 return;
451 455
452 cpuid(1, &eax, &ebx, &ecx, &edx);
453 smp_num_siblings = (ebx & 0xff0000) >> 16; 456 smp_num_siblings = (ebx & 0xff0000) >> 16;
454 457
455 if (smp_num_siblings == 1) { 458 if (smp_num_siblings == 1) {
456 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 459 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
457 } else if (smp_num_siblings > 1 ) { 460 } else if (smp_num_siblings > 1 ) {
458 index_msb = 31;
459 461
460 if (smp_num_siblings > NR_CPUS) { 462 if (smp_num_siblings > NR_CPUS) {
461 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); 463 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
462 smp_num_siblings = 1; 464 smp_num_siblings = 1;
463 return; 465 return;
464 } 466 }
465 tmp = smp_num_siblings; 467
466 while ((tmp & 0x80000000 ) == 0) { 468 index_msb = get_count_order(smp_num_siblings);
467 tmp <<=1 ;
468 index_msb--;
469 }
470 if (smp_num_siblings & (smp_num_siblings - 1))
471 index_msb++;
472 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); 469 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
473 470
474 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 471 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
475 phys_proc_id[cpu]); 472 phys_proc_id[cpu]);
476 473
477 smp_num_siblings = smp_num_siblings / c->x86_num_cores; 474 smp_num_siblings = smp_num_siblings / c->x86_max_cores;
478 475
479 tmp = smp_num_siblings; 476 index_msb = get_count_order(smp_num_siblings) ;
480 index_msb = 31;
481 while ((tmp & 0x80000000) == 0) {
482 tmp <<=1 ;
483 index_msb--;
484 }
485 477
486 if (smp_num_siblings & (smp_num_siblings - 1)) 478 core_bits = get_count_order(c->x86_max_cores);
487 index_msb++;
488 479
489 cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); 480 cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
481 ((1 << core_bits) - 1);
490 482
491 if (c->x86_num_cores > 1) 483 if (c->x86_max_cores > 1)
492 printk(KERN_INFO "CPU: Processor Core ID: %d\n", 484 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
493 cpu_core_id[cpu]); 485 cpu_core_id[cpu]);
494 } 486 }
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 43601de0f633..5e2da704f0fa 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -6,6 +6,7 @@
6#include <linux/bitops.h> 6#include <linux/bitops.h>
7#include <linux/smp.h> 7#include <linux/smp.h>
8#include <linux/thread_info.h> 8#include <linux/thread_info.h>
9#include <linux/module.h>
9 10
10#include <asm/processor.h> 11#include <asm/processor.h>
11#include <asm/msr.h> 12#include <asm/msr.h>
@@ -157,7 +158,7 @@ static void __devinit init_intel(struct cpuinfo_x86 *c)
157 if ( p ) 158 if ( p )
158 strcpy(c->x86_model_id, p); 159 strcpy(c->x86_model_id, p);
159 160
160 c->x86_num_cores = num_cpu_cores(c); 161 c->x86_max_cores = num_cpu_cores(c);
161 162
162 detect_ht(c); 163 detect_ht(c);
163 164
@@ -264,5 +265,52 @@ __init int intel_cpu_init(void)
264 return 0; 265 return 0;
265} 266}
266 267
268#ifndef CONFIG_X86_CMPXCHG
269unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
270{
271 u8 prev;
272 unsigned long flags;
273
274 /* Poor man's cmpxchg for 386. Unsuitable for SMP */
275 local_irq_save(flags);
276 prev = *(u8 *)ptr;
277 if (prev == old)
278 *(u8 *)ptr = new;
279 local_irq_restore(flags);
280 return prev;
281}
282EXPORT_SYMBOL(cmpxchg_386_u8);
283
284unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
285{
286 u16 prev;
287 unsigned long flags;
288
289 /* Poor man's cmpxchg for 386. Unsuitable for SMP */
290 local_irq_save(flags);
291 prev = *(u16 *)ptr;
292 if (prev == old)
293 *(u16 *)ptr = new;
294 local_irq_restore(flags);
295 return prev;
296}
297EXPORT_SYMBOL(cmpxchg_386_u16);
298
299unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
300{
301 u32 prev;
302 unsigned long flags;
303
304 /* Poor man's cmpxchg for 386. Unsuitable for SMP */
305 local_irq_save(flags);
306 prev = *(u32 *)ptr;
307 if (prev == old)
308 *(u32 *)ptr = new;
309 local_irq_restore(flags);
310 return prev;
311}
312EXPORT_SYMBOL(cmpxchg_386_u32);
313#endif
314
267// arch_initcall(intel_cpu_init); 315// arch_initcall(intel_cpu_init);
268 316
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index 4dc42a189ae5..fbfd374aa336 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -293,29 +293,45 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
293#ifdef CONFIG_SMP 293#ifdef CONFIG_SMP
294static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) 294static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
295{ 295{
296 struct _cpuid4_info *this_leaf; 296 struct _cpuid4_info *this_leaf, *sibling_leaf;
297 unsigned long num_threads_sharing; 297 unsigned long num_threads_sharing;
298#ifdef CONFIG_X86_HT 298 int index_msb, i;
299 struct cpuinfo_x86 *c = cpu_data + cpu; 299 struct cpuinfo_x86 *c = cpu_data;
300#endif
301 300
302 this_leaf = CPUID4_INFO_IDX(cpu, index); 301 this_leaf = CPUID4_INFO_IDX(cpu, index);
303 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; 302 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
304 303
305 if (num_threads_sharing == 1) 304 if (num_threads_sharing == 1)
306 cpu_set(cpu, this_leaf->shared_cpu_map); 305 cpu_set(cpu, this_leaf->shared_cpu_map);
307#ifdef CONFIG_X86_HT 306 else {
308 else if (num_threads_sharing == smp_num_siblings) 307 index_msb = get_count_order(num_threads_sharing);
309 this_leaf->shared_cpu_map = cpu_sibling_map[cpu]; 308
310 else if (num_threads_sharing == (c->x86_num_cores * smp_num_siblings)) 309 for_each_online_cpu(i) {
311 this_leaf->shared_cpu_map = cpu_core_map[cpu]; 310 if (c[i].apicid >> index_msb ==
312 else 311 c[cpu].apicid >> index_msb) {
313 printk(KERN_DEBUG "Number of CPUs sharing cache didn't match " 312 cpu_set(i, this_leaf->shared_cpu_map);
314 "any known set of CPUs\n"); 313 if (i != cpu && cpuid4_info[i]) {
315#endif 314 sibling_leaf = CPUID4_INFO_IDX(i, index);
315 cpu_set(cpu, sibling_leaf->shared_cpu_map);
316 }
317 }
318 }
319 }
320}
321static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
322{
323 struct _cpuid4_info *this_leaf, *sibling_leaf;
324 int sibling;
325
326 this_leaf = CPUID4_INFO_IDX(cpu, index);
327 for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
328 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
329 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
330 }
316} 331}
317#else 332#else
318static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} 333static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
334static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
319#endif 335#endif
320 336
321static void free_cache_attributes(unsigned int cpu) 337static void free_cache_attributes(unsigned int cpu)
@@ -574,8 +590,10 @@ static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
574 unsigned int cpu = sys_dev->id; 590 unsigned int cpu = sys_dev->id;
575 unsigned long i; 591 unsigned long i;
576 592
577 for (i = 0; i < num_cache_leaves; i++) 593 for (i = 0; i < num_cache_leaves; i++) {
594 cache_remove_shared_cpu_map(cpu, i);
578 kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); 595 kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
596 }
579 kobject_unregister(cache_kobject[cpu]); 597 kobject_unregister(cache_kobject[cpu]);
580 cpuid4_cache_sysfs_exit(cpu); 598 cpuid4_cache_sysfs_exit(cpu);
581 return; 599 return;
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index dd4ebd6af7e4..1e9db198c440 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void)
626 if (cpuid_eax(0x80000000) >= 0x80000008) { 626 if (cpuid_eax(0x80000000) >= 0x80000008) {
627 u32 phys_addr; 627 u32 phys_addr;
628 phys_addr = cpuid_eax(0x80000008) & 0xff; 628 phys_addr = cpuid_eax(0x80000008) & 0xff;
629 /* CPUID workaround for Intel 0F33/0F34 CPU */
630 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
631 boot_cpu_data.x86 == 0xF &&
632 boot_cpu_data.x86_model == 0x3 &&
633 (boot_cpu_data.x86_mask == 0x3 ||
634 boot_cpu_data.x86_mask == 0x4))
635 phys_addr = 36;
636
629 size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); 637 size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
630 size_and_mask = ~size_or_mask & 0xfff00000; 638 size_and_mask = ~size_or_mask & 0xfff00000;
631 } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && 639 } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 41b871ecf4b3..e7921315ae9d 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -94,12 +94,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
94 if (c->x86_cache_size >= 0) 94 if (c->x86_cache_size >= 0)
95 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); 95 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
96#ifdef CONFIG_X86_HT 96#ifdef CONFIG_X86_HT
97 if (c->x86_num_cores * smp_num_siblings > 1) { 97 if (c->x86_max_cores * smp_num_siblings > 1) {
98 seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]); 98 seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
99 seq_printf(m, "siblings\t: %d\n", 99 seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n]));
100 c->x86_num_cores * smp_num_siblings);
101 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]); 100 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
102 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores); 101 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
103 } 102 }
104#endif 103#endif
105 104
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index af809ccf5fbe..0248e084017c 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -21,6 +21,7 @@
21#include <asm/hardirq.h> 21#include <asm/hardirq.h>
22#include <asm/nmi.h> 22#include <asm/nmi.h>
23#include <asm/hw_irq.h> 23#include <asm/hw_irq.h>
24#include <asm/apic.h>
24#include <mach_ipi.h> 25#include <mach_ipi.h>
25 26
26 27
@@ -147,6 +148,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
147 regs = &fixed_regs; 148 regs = &fixed_regs;
148 } 149 }
149 crash_save_this_cpu(regs, cpu); 150 crash_save_this_cpu(regs, cpu);
151 disable_local_APIC();
150 atomic_dec(&waiting_for_crash_ipi); 152 atomic_dec(&waiting_for_crash_ipi);
151 /* Assume hlt works */ 153 /* Assume hlt works */
152 halt(); 154 halt();
@@ -186,6 +188,7 @@ static void nmi_shootdown_cpus(void)
186 } 188 }
187 189
188 /* Leave the nmi callback set */ 190 /* Leave the nmi callback set */
191 disable_local_APIC();
189} 192}
190#else 193#else
191static void nmi_shootdown_cpus(void) 194static void nmi_shootdown_cpus(void)
@@ -210,5 +213,9 @@ void machine_crash_shutdown(struct pt_regs *regs)
210 /* Make a note of crashing cpu. Will be used in NMI callback.*/ 213 /* Make a note of crashing cpu. Will be used in NMI callback.*/
211 crashing_cpu = smp_processor_id(); 214 crashing_cpu = smp_processor_id();
212 nmi_shootdown_cpus(); 215 nmi_shootdown_cpus();
216 lapic_shutdown();
217#if defined(CONFIG_X86_IO_APIC)
218 disable_IO_APIC();
219#endif
213 crash_save_self(regs); 220 crash_save_self(regs);
214} 221}
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 9e24f7b207ee..e50b93155249 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -560,11 +560,10 @@ nmi_stack_fixup:
560nmi_debug_stack_check: 560nmi_debug_stack_check:
561 cmpw $__KERNEL_CS,16(%esp) 561 cmpw $__KERNEL_CS,16(%esp)
562 jne nmi_stack_correct 562 jne nmi_stack_correct
563 cmpl $debug - 1,(%esp) 563 cmpl $debug,(%esp)
564 jle nmi_stack_correct 564 jb nmi_stack_correct
565 cmpl $debug_esp_fix_insn,(%esp) 565 cmpl $debug_esp_fix_insn,(%esp)
566 jle nmi_debug_stack_fixup 566 ja nmi_stack_correct
567nmi_debug_stack_fixup:
568 FIX_STACK(24,nmi_stack_correct, 1) 567 FIX_STACK(24,nmi_stack_correct, 1)
569 jmp nmi_stack_correct 568 jmp nmi_stack_correct
570 569
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index bc5a9d97466b..d16520da4550 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -72,9 +72,11 @@ int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
72/* Core ID of each logical CPU */ 72/* Core ID of each logical CPU */
73int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; 73int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
74 74
75/* representing HT siblings of each logical CPU */
75cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 76cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
76EXPORT_SYMBOL(cpu_sibling_map); 77EXPORT_SYMBOL(cpu_sibling_map);
77 78
79/* representing HT and core siblings of each logical CPU */
78cpumask_t cpu_core_map[NR_CPUS] __read_mostly; 80cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
79EXPORT_SYMBOL(cpu_core_map); 81EXPORT_SYMBOL(cpu_core_map);
80 82
@@ -442,35 +444,60 @@ static void __devinit smp_callin(void)
442 444
443static int cpucount; 445static int cpucount;
444 446
447/* representing cpus for which sibling maps can be computed */
448static cpumask_t cpu_sibling_setup_map;
449
445static inline void 450static inline void
446set_cpu_sibling_map(int cpu) 451set_cpu_sibling_map(int cpu)
447{ 452{
448 int i; 453 int i;
454 struct cpuinfo_x86 *c = cpu_data;
455
456 cpu_set(cpu, cpu_sibling_setup_map);
449 457
450 if (smp_num_siblings > 1) { 458 if (smp_num_siblings > 1) {
451 for (i = 0; i < NR_CPUS; i++) { 459 for_each_cpu_mask(i, cpu_sibling_setup_map) {
452 if (!cpu_isset(i, cpu_callout_map)) 460 if (phys_proc_id[cpu] == phys_proc_id[i] &&
453 continue; 461 cpu_core_id[cpu] == cpu_core_id[i]) {
454 if (cpu_core_id[cpu] == cpu_core_id[i]) {
455 cpu_set(i, cpu_sibling_map[cpu]); 462 cpu_set(i, cpu_sibling_map[cpu]);
456 cpu_set(cpu, cpu_sibling_map[i]); 463 cpu_set(cpu, cpu_sibling_map[i]);
464 cpu_set(i, cpu_core_map[cpu]);
465 cpu_set(cpu, cpu_core_map[i]);
457 } 466 }
458 } 467 }
459 } else { 468 } else {
460 cpu_set(cpu, cpu_sibling_map[cpu]); 469 cpu_set(cpu, cpu_sibling_map[cpu]);
461 } 470 }
462 471
463 if (current_cpu_data.x86_num_cores > 1) { 472 if (current_cpu_data.x86_max_cores == 1) {
464 for (i = 0; i < NR_CPUS; i++) {
465 if (!cpu_isset(i, cpu_callout_map))
466 continue;
467 if (phys_proc_id[cpu] == phys_proc_id[i]) {
468 cpu_set(i, cpu_core_map[cpu]);
469 cpu_set(cpu, cpu_core_map[i]);
470 }
471 }
472 } else {
473 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 473 cpu_core_map[cpu] = cpu_sibling_map[cpu];
474 c[cpu].booted_cores = 1;
475 return;
476 }
477
478 for_each_cpu_mask(i, cpu_sibling_setup_map) {
479 if (phys_proc_id[cpu] == phys_proc_id[i]) {
480 cpu_set(i, cpu_core_map[cpu]);
481 cpu_set(cpu, cpu_core_map[i]);
482 /*
483 * Does this new cpu bringup a new core?
484 */
485 if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
486 /*
487 * for each core in package, increment
488 * the booted_cores for this new cpu
489 */
490 if (first_cpu(cpu_sibling_map[i]) == i)
491 c[cpu].booted_cores++;
492 /*
493 * increment the core count for all
494 * the other cpus in this package
495 */
496 if (i != cpu)
497 c[i].booted_cores++;
498 } else if (i != cpu && !c[cpu].booted_cores)
499 c[cpu].booted_cores = c[i].booted_cores;
500 }
474 } 501 }
475} 502}
476 503
@@ -1095,11 +1122,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1095 1122
1096 current_thread_info()->cpu = 0; 1123 current_thread_info()->cpu = 0;
1097 smp_tune_scheduling(); 1124 smp_tune_scheduling();
1098 cpus_clear(cpu_sibling_map[0]);
1099 cpu_set(0, cpu_sibling_map[0]);
1100 1125
1101 cpus_clear(cpu_core_map[0]); 1126 set_cpu_sibling_map(0);
1102 cpu_set(0, cpu_core_map[0]);
1103 1127
1104 /* 1128 /*
1105 * If we couldn't find an SMP configuration at boot time, 1129 * If we couldn't find an SMP configuration at boot time,
@@ -1278,15 +1302,24 @@ static void
1278remove_siblinginfo(int cpu) 1302remove_siblinginfo(int cpu)
1279{ 1303{
1280 int sibling; 1304 int sibling;
1305 struct cpuinfo_x86 *c = cpu_data;
1281 1306
1307 for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
1308 cpu_clear(cpu, cpu_core_map[sibling]);
1309 /*
1310 * last thread sibling in this cpu core going down
1311 */
1312 if (cpus_weight(cpu_sibling_map[cpu]) == 1)
1313 c[sibling].booted_cores--;
1314 }
1315
1282 for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) 1316 for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
1283 cpu_clear(cpu, cpu_sibling_map[sibling]); 1317 cpu_clear(cpu, cpu_sibling_map[sibling]);
1284 for_each_cpu_mask(sibling, cpu_core_map[cpu])
1285 cpu_clear(cpu, cpu_core_map[sibling]);
1286 cpus_clear(cpu_sibling_map[cpu]); 1318 cpus_clear(cpu_sibling_map[cpu]);
1287 cpus_clear(cpu_core_map[cpu]); 1319 cpus_clear(cpu_core_map[cpu]);
1288 phys_proc_id[cpu] = BAD_APICID; 1320 phys_proc_id[cpu] = BAD_APICID;
1289 cpu_core_id[cpu] = BAD_APICID; 1321 cpu_core_id[cpu] = BAD_APICID;
1322 cpu_clear(cpu, cpu_sibling_setup_map);
1290} 1323}
1291 1324
1292int __cpu_disable(void) 1325int __cpu_disable(void)
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 8de658db8146..52b3ed5d2cb5 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -137,8 +137,8 @@ static void __init parse_memory_affinity_structure (char *sratp)
137 "enabled and removable" : "enabled" ) ); 137 "enabled and removable" : "enabled" ) );
138} 138}
139 139
140#if MAX_NR_ZONES != 3 140#if MAX_NR_ZONES != 4
141#error "MAX_NR_ZONES != 3, chunk_to_zone requires review" 141#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
142#endif 142#endif
143/* Take a chunk of pages from page frame cstart to cend and count the number 143/* Take a chunk of pages from page frame cstart to cend and count the number
144 * of pages in each zone, returned via zones[]. 144 * of pages in each zone, returned via zones[].
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
index e42e46d35159..b9b6bd56b9ba 100644
--- a/arch/i386/kernel/timers/timer_pit.c
+++ b/arch/i386/kernel/timers/timer_pit.c
@@ -25,8 +25,9 @@ static int __init init_pit(char* override)
25{ 25{
26 /* check clock override */ 26 /* check clock override */
27 if (override[0] && strncmp(override,"pit",3)) 27 if (override[0] && strncmp(override,"pit",3))
28 printk(KERN_ERR "Warning: clock= override failed. Defaulting to PIT\n"); 28 printk(KERN_ERR "Warning: clock= override failed. Defaulting "
29 29 "to PIT\n");
30 init_cpu_khz();
30 count_p = LATCH; 31 count_p = LATCH;
31 return 0; 32 return 0;
32} 33}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 542d9298da5e..06e26f006238 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -28,6 +28,7 @@
28#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
29#include <linux/efi.h> 29#include <linux/efi.h>
30#include <linux/memory_hotplug.h> 30#include <linux/memory_hotplug.h>
31#include <linux/initrd.h>
31 32
32#include <asm/processor.h> 33#include <asm/processor.h>
33#include <asm/system.h> 34#include <asm/system.h>
@@ -267,7 +268,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
267 pkmap_page_table = pte; 268 pkmap_page_table = pte;
268} 269}
269 270
270void __devinit free_new_highpage(struct page *page) 271static void __devinit free_new_highpage(struct page *page)
271{ 272{
272 set_page_count(page, 1); 273 set_page_count(page, 1);
273 __free_page(page); 274 __free_page(page);
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 8796e12c56f3..b76ce1fe2e7f 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -58,6 +58,10 @@ config IA64_UNCACHED_ALLOCATOR
58 bool 58 bool
59 select GENERIC_ALLOCATOR 59 select GENERIC_ALLOCATOR
60 60
61config ZONE_DMA_IS_DMA32
62 bool
63 default y
64
61choice 65choice
62 prompt "System type" 66 prompt "System type"
63 default IA64_GENERIC 67 default IA64_GENERIC
diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
index 9571a21d6ad4..a1629194e3fd 100644
--- a/arch/m68k/fpsp040/skeleton.S
+++ b/arch/m68k/fpsp040/skeleton.S
@@ -381,10 +381,8 @@ fpsp_done:
381.Lnotkern: 381.Lnotkern:
382 SAVE_ALL_INT 382 SAVE_ALL_INT
383 GET_CURRENT(%d0) 383 GET_CURRENT(%d0)
384 tstb %curptr@(TASK_NEEDRESCHED) 384 | deliver signals, reschedule etc..
385 jne ret_from_exception | deliver signals, 385 jra ret_from_exception
386 | reschedule etc..
387 RESTORE_ALL
388 386
389| 387|
390| mem_write --- write to user or supervisor address space 388| mem_write --- write to user or supervisor address space
diff --git a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
index 4ba2c74da93d..b2dbdf5ee309 100644
--- a/arch/m68k/ifpsp060/iskeleton.S
+++ b/arch/m68k/ifpsp060/iskeleton.S
@@ -75,10 +75,8 @@ _060_isp_done:
75.Lnotkern: 75.Lnotkern:
76 SAVE_ALL_INT 76 SAVE_ALL_INT
77 GET_CURRENT(%d0) 77 GET_CURRENT(%d0)
78 tstb %curptr@(TASK_NEEDRESCHED) 78 | deliver signals, reschedule etc..
79 jne ret_from_exception | deliver signals, 79 jra ret_from_exception
80 | reschedule etc..
81 RESTORE_ALL
82 80
83| 81|
84| _060_real_chk(): 82| _060_real_chk():
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index cee3317b8665..c787c5ba9513 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -25,12 +25,8 @@ int main(void)
25 DEFINE(TASK_STATE, offsetof(struct task_struct, state)); 25 DEFINE(TASK_STATE, offsetof(struct task_struct, state));
26 DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); 26 DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
27 DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); 27 DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
28 DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
29 DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
30 DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
31 DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
32 DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
33 DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); 28 DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
29 DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
34 DEFINE(TASK_MM, offsetof(struct task_struct, mm)); 30 DEFINE(TASK_MM, offsetof(struct task_struct, mm));
35 DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); 31 DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
36 32
@@ -45,6 +41,10 @@ int main(void)
45 DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); 41 DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
46 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); 42 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
47 43
44 /* offsets into the thread_info struct */
45 DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
46 DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
47
48 /* offsets into the pt_regs */ 48 /* offsets into the pt_regs */
49 DEFINE(PT_D0, offsetof(struct pt_regs, d0)); 49 DEFINE(PT_D0, offsetof(struct pt_regs, d0));
50 DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); 50 DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 23ca60a45552..320fde05dc63 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -44,9 +44,7 @@
44 44
45#include <asm/asm-offsets.h> 45#include <asm/asm-offsets.h>
46 46
47.globl system_call, buserr, trap 47.globl system_call, buserr, trap, resume
48.globl resume, ret_from_exception
49.globl ret_from_signal
50.globl inthandler, sys_call_table 48.globl inthandler, sys_call_table
51.globl sys_fork, sys_clone, sys_vfork 49.globl sys_fork, sys_clone, sys_vfork
52.globl ret_from_interrupt, bad_interrupt 50.globl ret_from_interrupt, bad_interrupt
@@ -58,7 +56,7 @@ ENTRY(buserr)
58 movel %sp,%sp@- | stack frame pointer argument 56 movel %sp,%sp@- | stack frame pointer argument
59 bsrl buserr_c 57 bsrl buserr_c
60 addql #4,%sp 58 addql #4,%sp
61 jra ret_from_exception 59 jra .Lret_from_exception
62 60
63ENTRY(trap) 61ENTRY(trap)
64 SAVE_ALL_INT 62 SAVE_ALL_INT
@@ -66,7 +64,7 @@ ENTRY(trap)
66 movel %sp,%sp@- | stack frame pointer argument 64 movel %sp,%sp@- | stack frame pointer argument
67 bsrl trap_c 65 bsrl trap_c
68 addql #4,%sp 66 addql #4,%sp
69 jra ret_from_exception 67 jra .Lret_from_exception
70 68
71 | After a fork we jump here directly from resume, 69 | After a fork we jump here directly from resume,
72 | so that %d1 contains the previous task 70 | so that %d1 contains the previous task
@@ -75,30 +73,31 @@ ENTRY(ret_from_fork)
75 movel %d1,%sp@- 73 movel %d1,%sp@-
76 jsr schedule_tail 74 jsr schedule_tail
77 addql #4,%sp 75 addql #4,%sp
78 jra ret_from_exception 76 jra .Lret_from_exception
79 77
80badsys: 78do_trace_entry:
81 movel #-ENOSYS,%sp@(PT_D0)
82 jra ret_from_exception
83
84do_trace:
85 movel #-ENOSYS,%sp@(PT_D0) | needed for strace 79 movel #-ENOSYS,%sp@(PT_D0) | needed for strace
86 subql #4,%sp 80 subql #4,%sp
87 SAVE_SWITCH_STACK 81 SAVE_SWITCH_STACK
88 jbsr syscall_trace 82 jbsr syscall_trace
89 RESTORE_SWITCH_STACK 83 RESTORE_SWITCH_STACK
90 addql #4,%sp 84 addql #4,%sp
91 movel %sp@(PT_ORIG_D0),%d1 85 movel %sp@(PT_ORIG_D0),%d0
92 movel #-ENOSYS,%d0 86 cmpl #NR_syscalls,%d0
93 cmpl #NR_syscalls,%d1 87 jcs syscall
94 jcc 1f 88badsys:
95 jbsr @(sys_call_table,%d1:l:4)@(0) 89 movel #-ENOSYS,%sp@(PT_D0)
961: movel %d0,%sp@(PT_D0) | save the return value 90 jra ret_from_syscall
97 subql #4,%sp | dummy return address 91
92do_trace_exit:
93 subql #4,%sp
98 SAVE_SWITCH_STACK 94 SAVE_SWITCH_STACK
99 jbsr syscall_trace 95 jbsr syscall_trace
96 RESTORE_SWITCH_STACK
97 addql #4,%sp
98 jra .Lret_from_exception
100 99
101ret_from_signal: 100ENTRY(ret_from_signal)
102 RESTORE_SWITCH_STACK 101 RESTORE_SWITCH_STACK
103 addql #4,%sp 102 addql #4,%sp
104/* on 68040 complete pending writebacks if any */ 103/* on 68040 complete pending writebacks if any */
@@ -111,7 +110,7 @@ ret_from_signal:
111 addql #4,%sp 110 addql #4,%sp
1121: 1111:
113#endif 112#endif
114 jra ret_from_exception 113 jra .Lret_from_exception
115 114
116ENTRY(system_call) 115ENTRY(system_call)
117 SAVE_ALL_SYS 116 SAVE_ALL_SYS
@@ -120,30 +119,34 @@ ENTRY(system_call)
120 | save top of frame 119 | save top of frame
121 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 120 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
122 121
123 tstb %curptr@(TASK_SYSCALL_TRACE) 122 | syscall trace?
124 jne do_trace 123 tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
124 jmi do_trace_entry
125 cmpl #NR_syscalls,%d0 125 cmpl #NR_syscalls,%d0
126 jcc badsys 126 jcc badsys
127syscall:
127 jbsr @(sys_call_table,%d0:l:4)@(0) 128 jbsr @(sys_call_table,%d0:l:4)@(0)
128 movel %d0,%sp@(PT_D0) | save the return value 129 movel %d0,%sp@(PT_D0) | save the return value
129 130ret_from_syscall:
130 |oriw #0x0700,%sr 131 |oriw #0x0700,%sr
131 movel %curptr@(TASK_WORK),%d0 132 movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
132 jne syscall_exit_work 133 jne syscall_exit_work
1331: RESTORE_ALL 1341: RESTORE_ALL
134 135
135syscall_exit_work: 136syscall_exit_work:
136 btst #5,%sp@(PT_SR) | check if returning to kernel 137 btst #5,%sp@(PT_SR) | check if returning to kernel
137 bnes 1b | if so, skip resched, signals 138 bnes 1b | if so, skip resched, signals
138 tstw %d0 139 lslw #1,%d0
139 jeq do_signal_return 140 jcs do_trace_exit
140 tstb %d0 141 jmi do_delayed_trace
141 jne do_delayed_trace 142 lslw #8,%d0
142 143 jmi do_signal_return
143 pea resume_userspace 144 pea resume_userspace
144 jmp schedule 145 jra schedule
146
145 147
146ret_from_exception: 148ENTRY(ret_from_exception)
149.Lret_from_exception:
147 btst #5,%sp@(PT_SR) | check if returning to kernel 150 btst #5,%sp@(PT_SR) | check if returning to kernel
148 bnes 1f | if so, skip resched, signals 151 bnes 1f | if so, skip resched, signals
149 | only allow interrupts when we are really the last one on the 152 | only allow interrupts when we are really the last one on the
@@ -152,19 +155,18 @@ ret_from_exception:
152 andw #ALLOWINT,%sr 155 andw #ALLOWINT,%sr
153 156
154resume_userspace: 157resume_userspace:
155 movel %curptr@(TASK_WORK),%d0 158 moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
156 lsrl #8,%d0
157 jne exit_work 159 jne exit_work
1581: RESTORE_ALL 1601: RESTORE_ALL
159 161
160exit_work: 162exit_work:
161 | save top of frame 163 | save top of frame
162 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 164 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
163 tstb %d0 165 lslb #1,%d0
164 jeq do_signal_return 166 jmi do_signal_return
165
166 pea resume_userspace 167 pea resume_userspace
167 jmp schedule 168 jra schedule
169
168 170
169do_signal_return: 171do_signal_return:
170 |andw #ALLOWINT,%sr 172 |andw #ALLOWINT,%sr
@@ -254,7 +256,7 @@ ret_from_interrupt:
254 256
255 /* check if we need to do software interrupts */ 257 /* check if we need to do software interrupts */
256 tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING 258 tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
257 jeq ret_from_exception 259 jeq .Lret_from_exception
258 pea ret_from_exception 260 pea ret_from_exception
259 jra do_softirq 261 jra do_softirq
260 262
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 7e54422685cf..540638ca81f9 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -109,7 +109,7 @@ static inline void singlestep_disable(struct task_struct *child)
109{ 109{
110 unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); 110 unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
111 put_reg(child, PT_SR, tmp); 111 put_reg(child, PT_SR, tmp);
112 child->thread.work.delayed_trace = 0; 112 clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
113} 113}
114 114
115/* 115/*
@@ -118,7 +118,7 @@ static inline void singlestep_disable(struct task_struct *child)
118void ptrace_disable(struct task_struct *child) 118void ptrace_disable(struct task_struct *child)
119{ 119{
120 singlestep_disable(child); 120 singlestep_disable(child);
121 child->thread.work.syscall_trace = 0; 121 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
122} 122}
123 123
124long arch_ptrace(struct task_struct *child, long request, long addr, long data) 124long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -198,9 +198,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
198 goto out_eio; 198 goto out_eio;
199 199
200 if (request == PTRACE_SYSCALL) 200 if (request == PTRACE_SYSCALL)
201 child->thread.work.syscall_trace = ~0; 201 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
202 else 202 else
203 child->thread.work.syscall_trace = 0; 203 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
204 child->exit_code = data; 204 child->exit_code = data;
205 singlestep_disable(child); 205 singlestep_disable(child);
206 wake_up_process(child); 206 wake_up_process(child);
@@ -223,10 +223,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
223 if (!valid_signal(data)) 223 if (!valid_signal(data))
224 goto out_eio; 224 goto out_eio;
225 225
226 child->thread.work.syscall_trace = 0; 226 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
227 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); 227 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
228 put_reg(child, PT_SR, tmp); 228 put_reg(child, PT_SR, tmp);
229 child->thread.work.delayed_trace = 1; 229 set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
230 230
231 child->exit_code = data; 231 child->exit_code = data;
232 /* give it a chance to run. */ 232 /* give it a chance to run. */
@@ -288,9 +288,6 @@ out_eio:
288 288
289asmlinkage void syscall_trace(void) 289asmlinkage void syscall_trace(void)
290{ 290{
291 if (!current->thread.work.delayed_trace &&
292 !current->thread.work.syscall_trace)
293 return;
294 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 291 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
295 ? 0x80 : 0)); 292 ? 0x80 : 0));
296 /* 293 /*
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index f85093b8d54d..f4926315fb68 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -32,6 +32,7 @@
32#include <linux/config.h> 32#include <linux/config.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/pm.h> 34#include <linux/pm.h>
35#include <linux/pm_legacy.h>
35#include <linux/slab.h> 36#include <linux/slab.h>
36#include <linux/sysctl.h> 37#include <linux/sysctl.h>
37#include <linux/jiffies.h> 38#include <linux/jiffies.h>
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
index 0b21bed7ee55..2cab7629702c 100644
--- a/arch/mips/au1000/common/usbdev.c
+++ b/arch/mips/au1000/common/usbdev.c
@@ -348,7 +348,7 @@ endpoint_stall(endpoint_t * ep)
348{ 348{
349 u32 cs; 349 u32 cs;
350 350
351 warn(__FUNCTION__); 351 warn("%s", __FUNCTION__);
352 352
353 cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL; 353 cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
354 au_writel(cs, ep->reg->ctrl_stat); 354 au_writel(cs, ep->reg->ctrl_stat);
@@ -360,7 +360,7 @@ endpoint_unstall(endpoint_t * ep)
360{ 360{
361 u32 cs; 361 u32 cs;
362 362
363 warn(__FUNCTION__); 363 warn("%s", __FUNCTION__);
364 364
365 cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL; 365 cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
366 au_writel(cs, ep->reg->ctrl_stat); 366 au_writel(cs, ep->reg->ctrl_stat);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c523029674e6..94df74bcc0ee 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -261,7 +261,7 @@ config PPC_ISERIES
261 261
262config EMBEDDED6xx 262config EMBEDDED6xx
263 bool "Embedded 6xx/7xx/7xxx-based board" 263 bool "Embedded 6xx/7xx/7xxx-based board"
264 depends on PPC32 264 depends on PPC32 && BROKEN
265 265
266config APUS 266config APUS
267 bool "Amiga-APUS" 267 bool "Amiga-APUS"
@@ -305,7 +305,7 @@ config PPC_PMAC64
305 305
306config PPC_PREP 306config PPC_PREP
307 bool " PowerPC Reference Platform (PReP) based machines" 307 bool " PowerPC Reference Platform (PReP) based machines"
308 depends on PPC_MULTIPLATFORM && PPC32 308 depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
309 select PPC_I8259 309 select PPC_I8259
310 select PPC_INDIRECT_PCI 310 select PPC_INDIRECT_PCI
311 default y 311 default y
@@ -932,6 +932,7 @@ source "arch/powerpc/oprofile/Kconfig"
932 932
933config KPROBES 933config KPROBES
934 bool "Kprobes (EXPERIMENTAL)" 934 bool "Kprobes (EXPERIMENTAL)"
935 depends on PPC64
935 help 936 help
936 Kprobes allows you to trap at almost any kernel address and 937 Kprobes allows you to trap at almost any kernel address and
937 execute a callback function. register_kprobe() establishes 938 execute a callback function. register_kprobe() establishes
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 5bc11bd36c1f..d41ad2e675db 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -187,7 +187,7 @@ archprepare: checkbin
187 187
188# Temporary hack until we have migrated to asm-powerpc 188# Temporary hack until we have migrated to asm-powerpc
189include/asm: arch/$(ARCH)/include/asm 189include/asm: arch/$(ARCH)/include/asm
190arch/$(ARCH)/include/asm: 190arch/$(ARCH)/include/asm: FORCE
191 $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi 191 $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
192 $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm 192 $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
193 193
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 9f09dff9e11a..913962c1dae0 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -1,18 +1,33 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc4 3# Linux kernel version: 2.6.15-rc1
4# Thu Oct 20 08:32:17 2005 4# Mon Nov 14 15:27:00 2005
5# 5#
6CONFIG_PPC64=y
6CONFIG_64BIT=y 7CONFIG_64BIT=y
8CONFIG_PPC_MERGE=y
7CONFIG_MMU=y 9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y 11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 12CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_GENERIC_ISA_DMA=y 13CONFIG_PPC=y
11CONFIG_EARLY_PRINTK=y 14CONFIG_EARLY_PRINTK=y
12CONFIG_COMPAT=y 15CONFIG_COMPAT=y
16CONFIG_SYSVIPC_COMPAT=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y 18CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15CONFIG_FORCE_MAX_ZONEORDER=13 19
20#
21# Processor support
22#
23# CONFIG_POWER4_ONLY is not set
24CONFIG_POWER3=y
25CONFIG_POWER4=y
26CONFIG_PPC_FPU=y
27CONFIG_ALTIVEC=y
28CONFIG_PPC_STD_MMU=y
29CONFIG_SMP=y
30CONFIG_NR_CPUS=128
16 31
17# 32#
18# Code maturity level options 33# Code maturity level options
@@ -68,75 +83,103 @@ CONFIG_MODVERSIONS=y
68CONFIG_MODULE_SRCVERSION_ALL=y 83CONFIG_MODULE_SRCVERSION_ALL=y
69CONFIG_KMOD=y 84CONFIG_KMOD=y
70CONFIG_STOP_MACHINE=y 85CONFIG_STOP_MACHINE=y
71CONFIG_SYSVIPC_COMPAT=y 86
87#
88# Block layer
89#
90
91#
92# IO Schedulers
93#
94CONFIG_IOSCHED_NOOP=y
95CONFIG_IOSCHED_AS=y
96CONFIG_IOSCHED_DEADLINE=y
97CONFIG_IOSCHED_CFQ=y
98CONFIG_DEFAULT_AS=y
99# CONFIG_DEFAULT_DEADLINE is not set
100# CONFIG_DEFAULT_CFQ is not set
101# CONFIG_DEFAULT_NOOP is not set
102CONFIG_DEFAULT_IOSCHED="anticipatory"
72 103
73# 104#
74# Platform support 105# Platform support
75# 106#
76# CONFIG_PPC_ISERIES is not set
77CONFIG_PPC_MULTIPLATFORM=y 107CONFIG_PPC_MULTIPLATFORM=y
108# CONFIG_PPC_ISERIES is not set
109# CONFIG_EMBEDDED6xx is not set
110# CONFIG_APUS is not set
78CONFIG_PPC_PSERIES=y 111CONFIG_PPC_PSERIES=y
79# CONFIG_PPC_BPA is not set
80# CONFIG_PPC_PMAC is not set 112# CONFIG_PPC_PMAC is not set
81# CONFIG_PPC_MAPLE is not set 113# CONFIG_PPC_MAPLE is not set
82CONFIG_PPC=y 114# CONFIG_PPC_CELL is not set
83CONFIG_PPC64=y
84CONFIG_PPC_OF=y 115CONFIG_PPC_OF=y
85CONFIG_XICS=y 116CONFIG_XICS=y
117# CONFIG_U3_DART is not set
86CONFIG_MPIC=y 118CONFIG_MPIC=y
87CONFIG_ALTIVEC=y 119CONFIG_PPC_RTAS=y
88CONFIG_PPC_SPLPAR=y 120CONFIG_RTAS_ERROR_LOGGING=y
89CONFIG_KEXEC=y 121CONFIG_RTAS_PROC=y
122CONFIG_RTAS_FLASH=m
123# CONFIG_MMIO_NVRAM is not set
90CONFIG_IBMVIO=y 124CONFIG_IBMVIO=y
91# CONFIG_U3_DART is not set 125# CONFIG_PPC_MPC106 is not set
92# CONFIG_BOOTX_TEXT is not set 126# CONFIG_GENERIC_TBSYNC is not set
93# CONFIG_POWER4_ONLY is not set 127# CONFIG_CPU_FREQ is not set
128# CONFIG_WANT_EARLY_SERIAL is not set
129
130#
131# Kernel options
132#
133# CONFIG_HZ_100 is not set
134CONFIG_HZ_250=y
135# CONFIG_HZ_1000 is not set
136CONFIG_HZ=250
137CONFIG_PREEMPT_NONE=y
138# CONFIG_PREEMPT_VOLUNTARY is not set
139# CONFIG_PREEMPT is not set
140# CONFIG_PREEMPT_BKL is not set
141CONFIG_BINFMT_ELF=y
142# CONFIG_BINFMT_MISC is not set
143CONFIG_FORCE_MAX_ZONEORDER=13
94CONFIG_IOMMU_VMERGE=y 144CONFIG_IOMMU_VMERGE=y
95CONFIG_SMP=y 145CONFIG_HOTPLUG_CPU=y
96CONFIG_NR_CPUS=128 146CONFIG_KEXEC=y
147# CONFIG_IRQ_ALL_CPUS is not set
148CONFIG_PPC_SPLPAR=y
149CONFIG_EEH=y
150CONFIG_SCANLOG=m
151CONFIG_LPARCFG=y
152CONFIG_NUMA=y
97CONFIG_ARCH_SELECT_MEMORY_MODEL=y 153CONFIG_ARCH_SELECT_MEMORY_MODEL=y
98CONFIG_ARCH_FLATMEM_ENABLE=y
99CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
100CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
101CONFIG_ARCH_SPARSEMEM_ENABLE=y 154CONFIG_ARCH_SPARSEMEM_ENABLE=y
155CONFIG_ARCH_SPARSEMEM_DEFAULT=y
102CONFIG_SELECT_MEMORY_MODEL=y 156CONFIG_SELECT_MEMORY_MODEL=y
103# CONFIG_FLATMEM_MANUAL is not set 157# CONFIG_FLATMEM_MANUAL is not set
104CONFIG_DISCONTIGMEM_MANUAL=y 158# CONFIG_DISCONTIGMEM_MANUAL is not set
105# CONFIG_SPARSEMEM_MANUAL is not set 159CONFIG_SPARSEMEM_MANUAL=y
106CONFIG_DISCONTIGMEM=y 160CONFIG_SPARSEMEM=y
107CONFIG_FLAT_NODE_MEM_MAP=y
108CONFIG_NEED_MULTIPLE_NODES=y 161CONFIG_NEED_MULTIPLE_NODES=y
162CONFIG_HAVE_MEMORY_PRESENT=y
109# CONFIG_SPARSEMEM_STATIC is not set 163# CONFIG_SPARSEMEM_STATIC is not set
164CONFIG_SPARSEMEM_EXTREME=y
165# CONFIG_MEMORY_HOTPLUG is not set
166CONFIG_SPLIT_PTLOCK_CPUS=4096
110CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y 167CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
111CONFIG_NODES_SPAN_OTHER_NODES=y 168CONFIG_NODES_SPAN_OTHER_NODES=y
112CONFIG_NUMA=y 169# CONFIG_PPC_64K_PAGES is not set
113CONFIG_SCHED_SMT=y 170CONFIG_SCHED_SMT=y
114CONFIG_PREEMPT_NONE=y
115# CONFIG_PREEMPT_VOLUNTARY is not set
116# CONFIG_PREEMPT is not set
117# CONFIG_PREEMPT_BKL is not set
118# CONFIG_HZ_100 is not set
119CONFIG_HZ_250=y
120# CONFIG_HZ_1000 is not set
121CONFIG_HZ=250
122CONFIG_EEH=y
123CONFIG_GENERIC_HARDIRQS=y
124CONFIG_PPC_RTAS=y
125CONFIG_RTAS_PROC=y
126CONFIG_RTAS_FLASH=m
127CONFIG_SCANLOG=m
128CONFIG_LPARCFG=y
129CONFIG_SECCOMP=y
130CONFIG_BINFMT_ELF=y
131# CONFIG_BINFMT_MISC is not set
132CONFIG_HOTPLUG_CPU=y
133CONFIG_PROC_DEVICETREE=y 171CONFIG_PROC_DEVICETREE=y
134# CONFIG_CMDLINE_BOOL is not set 172# CONFIG_CMDLINE_BOOL is not set
173# CONFIG_PM is not set
174CONFIG_SECCOMP=y
135CONFIG_ISA_DMA_API=y 175CONFIG_ISA_DMA_API=y
136 176
137# 177#
138# Bus Options 178# Bus options
139# 179#
180CONFIG_GENERIC_ISA_DMA=y
181CONFIG_PPC_I8259=y
182# CONFIG_PPC_INDIRECT_PCI is not set
140CONFIG_PCI=y 183CONFIG_PCI=y
141CONFIG_PCI_DOMAINS=y 184CONFIG_PCI_DOMAINS=y
142CONFIG_PCI_LEGACY_PROC=y 185CONFIG_PCI_LEGACY_PROC=y
@@ -156,6 +199,7 @@ CONFIG_HOTPLUG_PCI=m
156# CONFIG_HOTPLUG_PCI_SHPC is not set 199# CONFIG_HOTPLUG_PCI_SHPC is not set
157CONFIG_HOTPLUG_PCI_RPA=m 200CONFIG_HOTPLUG_PCI_RPA=m
158CONFIG_HOTPLUG_PCI_RPA_DLPAR=m 201CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
202CONFIG_KERNEL_START=0xc000000000000000
159 203
160# 204#
161# Networking 205# Networking
@@ -197,6 +241,10 @@ CONFIG_TCP_CONG_BIC=y
197# CONFIG_IPV6 is not set 241# CONFIG_IPV6 is not set
198CONFIG_NETFILTER=y 242CONFIG_NETFILTER=y
199# CONFIG_NETFILTER_DEBUG is not set 243# CONFIG_NETFILTER_DEBUG is not set
244
245#
246# Core Netfilter Configuration
247#
200CONFIG_NETFILTER_NETLINK=y 248CONFIG_NETFILTER_NETLINK=y
201CONFIG_NETFILTER_NETLINK_QUEUE=m 249CONFIG_NETFILTER_NETLINK_QUEUE=m
202CONFIG_NETFILTER_NETLINK_LOG=m 250CONFIG_NETFILTER_NETLINK_LOG=m
@@ -299,6 +347,10 @@ CONFIG_LLC=y
299# CONFIG_NET_DIVERT is not set 347# CONFIG_NET_DIVERT is not set
300# CONFIG_ECONET is not set 348# CONFIG_ECONET is not set
301# CONFIG_WAN_ROUTER is not set 349# CONFIG_WAN_ROUTER is not set
350
351#
352# QoS and/or fair queueing
353#
302# CONFIG_NET_SCHED is not set 354# CONFIG_NET_SCHED is not set
303CONFIG_NET_CLS_ROUTE=y 355CONFIG_NET_CLS_ROUTE=y
304 356
@@ -368,14 +420,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
368CONFIG_BLK_DEV_RAM_SIZE=65536 420CONFIG_BLK_DEV_RAM_SIZE=65536
369CONFIG_BLK_DEV_INITRD=y 421CONFIG_BLK_DEV_INITRD=y
370# CONFIG_CDROM_PKTCDVD is not set 422# CONFIG_CDROM_PKTCDVD is not set
371
372#
373# IO Schedulers
374#
375CONFIG_IOSCHED_NOOP=y
376CONFIG_IOSCHED_AS=y
377CONFIG_IOSCHED_DEADLINE=y
378CONFIG_IOSCHED_CFQ=y
379# CONFIG_ATA_OVER_ETH is not set 423# CONFIG_ATA_OVER_ETH is not set
380 424
381# 425#
@@ -473,6 +517,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
473# 517#
474# SCSI low-level drivers 518# SCSI low-level drivers
475# 519#
520# CONFIG_ISCSI_TCP is not set
476# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 521# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
477# CONFIG_SCSI_3W_9XXX is not set 522# CONFIG_SCSI_3W_9XXX is not set
478# CONFIG_SCSI_ACARD is not set 523# CONFIG_SCSI_ACARD is not set
@@ -559,6 +604,7 @@ CONFIG_DM_MULTIPATH_EMC=m
559# 604#
560# Macintosh device drivers 605# Macintosh device drivers
561# 606#
607# CONFIG_WINDFARM is not set
562 608
563# 609#
564# Network device support 610# Network device support
@@ -645,7 +691,6 @@ CONFIG_IXGB=m
645# CONFIG_IXGB_NAPI is not set 691# CONFIG_IXGB_NAPI is not set
646CONFIG_S2IO=m 692CONFIG_S2IO=m
647# CONFIG_S2IO_NAPI is not set 693# CONFIG_S2IO_NAPI is not set
648# CONFIG_2BUFF_MODE is not set
649 694
650# 695#
651# Token Ring devices 696# Token Ring devices
@@ -674,6 +719,7 @@ CONFIG_PPP_ASYNC=m
674CONFIG_PPP_SYNC_TTY=m 719CONFIG_PPP_SYNC_TTY=m
675CONFIG_PPP_DEFLATE=m 720CONFIG_PPP_DEFLATE=m
676CONFIG_PPP_BSDCOMP=m 721CONFIG_PPP_BSDCOMP=m
722# CONFIG_PPP_MPPE is not set
677CONFIG_PPPOE=m 723CONFIG_PPPOE=m
678# CONFIG_SLIP is not set 724# CONFIG_SLIP is not set
679# CONFIG_NET_FC is not set 725# CONFIG_NET_FC is not set
@@ -784,6 +830,8 @@ CONFIG_HVCS=m
784# 830#
785# CONFIG_WATCHDOG is not set 831# CONFIG_WATCHDOG is not set
786# CONFIG_RTC is not set 832# CONFIG_RTC is not set
833CONFIG_GEN_RTC=y
834# CONFIG_GEN_RTC_X is not set
787# CONFIG_DTLK is not set 835# CONFIG_DTLK is not set
788# CONFIG_R3964 is not set 836# CONFIG_R3964 is not set
789# CONFIG_APPLICOM is not set 837# CONFIG_APPLICOM is not set
@@ -801,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=1024
801# TPM devices 849# TPM devices
802# 850#
803# CONFIG_TCG_TPM is not set 851# CONFIG_TCG_TPM is not set
852# CONFIG_TELCLOCK is not set
804 853
805# 854#
806# I2C support 855# I2C support
@@ -852,6 +901,7 @@ CONFIG_I2C_ALGOBIT=y
852# CONFIG_SENSORS_PCF8591 is not set 901# CONFIG_SENSORS_PCF8591 is not set
853# CONFIG_SENSORS_RTC8564 is not set 902# CONFIG_SENSORS_RTC8564 is not set
854# CONFIG_SENSORS_MAX6875 is not set 903# CONFIG_SENSORS_MAX6875 is not set
904# CONFIG_RTC_X1205_I2C is not set
855# CONFIG_I2C_DEBUG_CORE is not set 905# CONFIG_I2C_DEBUG_CORE is not set
856# CONFIG_I2C_DEBUG_ALGO is not set 906# CONFIG_I2C_DEBUG_ALGO is not set
857# CONFIG_I2C_DEBUG_BUS is not set 907# CONFIG_I2C_DEBUG_BUS is not set
@@ -893,7 +943,6 @@ CONFIG_FB=y
893CONFIG_FB_CFB_FILLRECT=y 943CONFIG_FB_CFB_FILLRECT=y
894CONFIG_FB_CFB_COPYAREA=y 944CONFIG_FB_CFB_COPYAREA=y
895CONFIG_FB_CFB_IMAGEBLIT=y 945CONFIG_FB_CFB_IMAGEBLIT=y
896CONFIG_FB_SOFT_CURSOR=y
897CONFIG_FB_MACMODES=y 946CONFIG_FB_MACMODES=y
898CONFIG_FB_MODE_HELPERS=y 947CONFIG_FB_MODE_HELPERS=y
899CONFIG_FB_TILEBLITTING=y 948CONFIG_FB_TILEBLITTING=y
@@ -905,6 +954,7 @@ CONFIG_FB_OF=y
905# CONFIG_FB_ASILIANT is not set 954# CONFIG_FB_ASILIANT is not set
906# CONFIG_FB_IMSTT is not set 955# CONFIG_FB_IMSTT is not set
907# CONFIG_FB_VGA16 is not set 956# CONFIG_FB_VGA16 is not set
957# CONFIG_FB_S1D13XXX is not set
908# CONFIG_FB_NVIDIA is not set 958# CONFIG_FB_NVIDIA is not set
909# CONFIG_FB_RIVA is not set 959# CONFIG_FB_RIVA is not set
910CONFIG_FB_MATROX=y 960CONFIG_FB_MATROX=y
@@ -927,7 +977,6 @@ CONFIG_FB_RADEON_I2C=y
927# CONFIG_FB_VOODOO1 is not set 977# CONFIG_FB_VOODOO1 is not set
928# CONFIG_FB_CYBLA is not set 978# CONFIG_FB_CYBLA is not set
929# CONFIG_FB_TRIDENT is not set 979# CONFIG_FB_TRIDENT is not set
930# CONFIG_FB_S1D13XXX is not set
931# CONFIG_FB_VIRTUAL is not set 980# CONFIG_FB_VIRTUAL is not set
932 981
933# 982#
@@ -936,6 +985,7 @@ CONFIG_FB_RADEON_I2C=y
936# CONFIG_VGA_CONSOLE is not set 985# CONFIG_VGA_CONSOLE is not set
937CONFIG_DUMMY_CONSOLE=y 986CONFIG_DUMMY_CONSOLE=y
938CONFIG_FRAMEBUFFER_CONSOLE=y 987CONFIG_FRAMEBUFFER_CONSOLE=y
988# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
939# CONFIG_FONTS is not set 989# CONFIG_FONTS is not set
940CONFIG_FONT_8x8=y 990CONFIG_FONT_8x8=y
941CONFIG_FONT_8x16=y 991CONFIG_FONT_8x16=y
@@ -990,12 +1040,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
990# 1040#
991# USB Device Class drivers 1041# USB Device Class drivers
992# 1042#
993# CONFIG_USB_BLUETOOTH_TTY is not set
994# CONFIG_USB_ACM is not set 1043# CONFIG_USB_ACM is not set
995# CONFIG_USB_PRINTER is not set 1044# CONFIG_USB_PRINTER is not set
996 1045
997# 1046#
998# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 1047# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1048#
1049
1050#
1051# may also be needed; see USB_STORAGE Help for more information
999# 1052#
1000CONFIG_USB_STORAGE=y 1053CONFIG_USB_STORAGE=y
1001# CONFIG_USB_STORAGE_DEBUG is not set 1054# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1106,6 +1159,7 @@ CONFIG_INFINIBAND_MTHCA=m
1106# CONFIG_INFINIBAND_MTHCA_DEBUG is not set 1159# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
1107CONFIG_INFINIBAND_IPOIB=m 1160CONFIG_INFINIBAND_IPOIB=m
1108# CONFIG_INFINIBAND_IPOIB_DEBUG is not set 1161# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
1162# CONFIG_INFINIBAND_SRP is not set
1109 1163
1110# 1164#
1111# SN Devices 1165# SN Devices
@@ -1288,10 +1342,25 @@ CONFIG_NLS_ISO8859_1=y
1288# CONFIG_NLS_UTF8 is not set 1342# CONFIG_NLS_UTF8 is not set
1289 1343
1290# 1344#
1291# Profiling support 1345# Library routines
1346#
1347CONFIG_CRC_CCITT=m
1348# CONFIG_CRC16 is not set
1349CONFIG_CRC32=y
1350CONFIG_LIBCRC32C=m
1351CONFIG_ZLIB_INFLATE=y
1352CONFIG_ZLIB_DEFLATE=m
1353CONFIG_TEXTSEARCH=y
1354CONFIG_TEXTSEARCH_KMP=m
1355CONFIG_TEXTSEARCH_BM=m
1356CONFIG_TEXTSEARCH_FSM=m
1357
1358#
1359# Instrumentation Support
1292# 1360#
1293CONFIG_PROFILING=y 1361CONFIG_PROFILING=y
1294CONFIG_OPROFILE=y 1362CONFIG_OPROFILE=y
1363# CONFIG_KPROBES is not set
1295 1364
1296# 1365#
1297# Kernel hacking 1366# Kernel hacking
@@ -1308,14 +1377,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
1308# CONFIG_DEBUG_KOBJECT is not set 1377# CONFIG_DEBUG_KOBJECT is not set
1309# CONFIG_DEBUG_INFO is not set 1378# CONFIG_DEBUG_INFO is not set
1310CONFIG_DEBUG_FS=y 1379CONFIG_DEBUG_FS=y
1380# CONFIG_DEBUG_VM is not set
1381# CONFIG_RCU_TORTURE_TEST is not set
1311CONFIG_DEBUG_STACKOVERFLOW=y 1382CONFIG_DEBUG_STACKOVERFLOW=y
1312# CONFIG_KPROBES is not set
1313CONFIG_DEBUG_STACK_USAGE=y 1383CONFIG_DEBUG_STACK_USAGE=y
1314CONFIG_DEBUGGER=y 1384CONFIG_DEBUGGER=y
1315CONFIG_XMON=y 1385CONFIG_XMON=y
1316CONFIG_XMON_DEFAULT=y 1386CONFIG_XMON_DEFAULT=y
1317# CONFIG_PPCDBG is not set
1318CONFIG_IRQSTACKS=y 1387CONFIG_IRQSTACKS=y
1388# CONFIG_BOOTX_TEXT is not set
1319 1389
1320# 1390#
1321# Security options 1391# Security options
@@ -1355,17 +1425,3 @@ CONFIG_CRYPTO_TEST=m
1355# 1425#
1356# Hardware crypto devices 1426# Hardware crypto devices
1357# 1427#
1358
1359#
1360# Library routines
1361#
1362CONFIG_CRC_CCITT=m
1363# CONFIG_CRC16 is not set
1364CONFIG_CRC32=y
1365CONFIG_LIBCRC32C=m
1366CONFIG_ZLIB_INFLATE=y
1367CONFIG_ZLIB_DEFLATE=m
1368CONFIG_TEXTSEARCH=y
1369CONFIG_TEXTSEARCH_KMP=m
1370CONFIG_TEXTSEARCH_BM=m
1371CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9a74b7ab03a4..4970e3721a84 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o 27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
28obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y) 28obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y)
29obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 29obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
31obj-$(CONFIG_LPARCFG) += lparcfg.o 31obj-$(CONFIG_LPARCFG) += lparcfg.o
@@ -49,12 +49,23 @@ extra-y += vmlinux.lds
49obj-y += process.o init_task.o time.o \ 49obj-y += process.o init_task.o time.o \
50 prom.o traps.o setup-common.o 50 prom.o traps.o setup-common.o
51obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o 51obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
52obj-$(CONFIG_PPC64) += misc_64.o 52obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
53obj-$(CONFIG_PPC_OF) += prom_init.o 53obj-$(CONFIG_PPC_OF) += prom_init.o
54obj-$(CONFIG_MODULES) += ppc_ksyms.o 54obj-$(CONFIG_MODULES) += ppc_ksyms.o
55obj-$(CONFIG_BOOTX_TEXT) += btext.o 55obj-$(CONFIG_BOOTX_TEXT) += btext.o
56obj-$(CONFIG_6xx) += idle_6xx.o 56obj-$(CONFIG_6xx) += idle_6xx.o
57obj-$(CONFIG_SMP) += smp.o 57obj-$(CONFIG_SMP) += smp.o
58obj-$(CONFIG_KPROBES) += kprobes.o
59
60module-$(CONFIG_PPC64) += module_64.o
61obj-$(CONFIG_MODULES) += $(module-y)
62
63pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
64 pci_direct_iommu.o iomap.o
65obj-$(CONFIG_PCI) += $(pci64-y)
66
67kexec64-$(CONFIG_PPC64) += machine_kexec_64.o
68obj-$(CONFIG_KEXEC) += $(kexec64-y)
58 69
59ifeq ($(CONFIG_PPC_ISERIES),y) 70ifeq ($(CONFIG_PPC_ISERIES),y)
60$(obj)/head_64.o: $(obj)/lparmap.s 71$(obj)/head_64.o: $(obj)/lparmap.s
@@ -62,11 +73,8 @@ AFLAGS_head_64.o += -I$(obj)
62endif 73endif
63 74
64else 75else
65# stuff used from here for ARCH=ppc or ARCH=ppc64 76# stuff used from here for ARCH=ppc
66smpobj-$(CONFIG_SMP) += smp.o 77smpobj-$(CONFIG_SMP) += smp.o
67obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \
68 setup-common.o $(smpobj-y)
69
70 78
71endif 79endif
72 80
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 4550eb4f4fbd..91538d2445bf 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -270,13 +270,15 @@ int main(void)
270 DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); 270 DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
271 DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); 271 DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
272 DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); 272 DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
273 DEFINE(TSPC64_TV_SEC, offsetof(struct timespec, tv_sec));
274 DEFINE(TSPC64_TV_NSEC, offsetof(struct timespec, tv_nsec));
273 DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec)); 275 DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec));
274 DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); 276 DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
275#else 277#else
276 DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec)); 278 DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
277 DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec)); 279 DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
278 DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec)); 280 DEFINE(TSPC32_TV_SEC, offsetof(struct timespec, tv_sec));
279 DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec)); 281 DEFINE(TSPC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
280#endif 282#endif
281 /* timeval/timezone offsets for use by vdso */ 283 /* timeval/timezone offsets for use by vdso */
282 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); 284 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
diff --git a/arch/ppc64/kernel/dma.c b/arch/powerpc/kernel/dma_64.c
index 7c3419656ccc..7c3419656ccc 100644
--- a/arch/ppc64/kernel/dma.c
+++ b/arch/powerpc/kernel/dma_64.c
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 5063c603fad4..8d60fa99fc4b 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
24 * Copyright 2002-2004 MontaVista Software, Inc. 24 * Copyright 2002-2004 MontaVista Software, Inc.
25 * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> 25 * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
26 * Copyright 2004 Freescale Semiconductor, Inc 26 * Copyright 2004 Freescale Semiconductor, Inc
27 * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com> 27 * PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
28 * 28 *
29 * This program is free software; you can redistribute it and/or modify it 29 * This program is free software; you can redistribute it and/or modify it
30 * under the terms of the GNU General Public License as published by the 30 * under the terms of the GNU General Public License as published by the
diff --git a/arch/ppc64/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index 6160c8dbb7c5..6160c8dbb7c5 100644
--- a/arch/ppc64/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
diff --git a/arch/ppc64/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 4d9b4388918b..4d9b4388918b 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4b7940693f3d..5a71ed9612fe 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -71,6 +71,11 @@
71#include <asm/paca.h> 71#include <asm/paca.h>
72#endif 72#endif
73 73
74int __irq_offset_value;
75#ifdef CONFIG_PPC32
76EXPORT_SYMBOL(__irq_offset_value);
77#endif
78
74static int ppc_spurious_interrupts; 79static int ppc_spurious_interrupts;
75 80
76#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) 81#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
@@ -98,7 +103,6 @@ extern atomic_t ipi_sent;
98EXPORT_SYMBOL(irq_desc); 103EXPORT_SYMBOL(irq_desc);
99 104
100int distribute_irqs = 1; 105int distribute_irqs = 1;
101int __irq_offset_value;
102u64 ppc64_interrupt_controller; 106u64 ppc64_interrupt_controller;
103#endif /* CONFIG_PPC64 */ 107#endif /* CONFIG_PPC64 */
104 108
@@ -311,7 +315,6 @@ void __init init_IRQ(void)
311} 315}
312 316
313#ifdef CONFIG_PPC64 317#ifdef CONFIG_PPC64
314#ifndef CONFIG_PPC_ISERIES
315/* 318/*
316 * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. 319 * Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
317 */ 320 */
@@ -420,8 +423,6 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
420 423
421} 424}
422 425
423#endif /* CONFIG_PPC_ISERIES */
424
425#ifdef CONFIG_IRQSTACKS 426#ifdef CONFIG_IRQSTACKS
426struct thread_info *softirq_ctx[NR_CPUS]; 427struct thread_info *softirq_ctx[NR_CPUS];
427struct thread_info *hardirq_ctx[NR_CPUS]; 428struct thread_info *hardirq_ctx[NR_CPUS];
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 511af54e6230..511af54e6230 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 1b3ba8a440a6..9dda16ccde78 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -42,32 +42,6 @@
42 42
43/* #define LPARCFG_DEBUG */ 43/* #define LPARCFG_DEBUG */
44 44
45/* find a better place for this function... */
46static void log_plpar_hcall_return(unsigned long rc, char *tag)
47{
48 if (rc == 0) /* success, return */
49 return;
50/* check for null tag ? */
51 if (rc == H_Hardware)
52 printk(KERN_INFO
53 "plpar-hcall (%s) failed with hardware fault\n", tag);
54 else if (rc == H_Function)
55 printk(KERN_INFO
56 "plpar-hcall (%s) failed; function not allowed\n", tag);
57 else if (rc == H_Authority)
58 printk(KERN_INFO
59 "plpar-hcall (%s) failed; not authorized to this function\n",
60 tag);
61 else if (rc == H_Parameter)
62 printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
63 tag);
64 else
65 printk(KERN_INFO
66 "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
67 tag, rc);
68
69}
70
71static struct proc_dir_entry *proc_ppc64_lparcfg; 45static struct proc_dir_entry *proc_ppc64_lparcfg;
72#define LPARCFG_BUFF_SIZE 4096 46#define LPARCFG_BUFF_SIZE 4096
73 47
@@ -172,6 +146,31 @@ static int lparcfg_data(struct seq_file *m, void *v)
172/* 146/*
173 * Methods used to fetch LPAR data when running on a pSeries platform. 147 * Methods used to fetch LPAR data when running on a pSeries platform.
174 */ 148 */
149/* find a better place for this function... */
150static void log_plpar_hcall_return(unsigned long rc, char *tag)
151{
152 if (rc == 0) /* success, return */
153 return;
154/* check for null tag ? */
155 if (rc == H_Hardware)
156 printk(KERN_INFO
157 "plpar-hcall (%s) failed with hardware fault\n", tag);
158 else if (rc == H_Function)
159 printk(KERN_INFO
160 "plpar-hcall (%s) failed; function not allowed\n", tag);
161 else if (rc == H_Authority)
162 printk(KERN_INFO
163 "plpar-hcall (%s) failed; not authorized to this function\n",
164 tag);
165 else if (rc == H_Parameter)
166 printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
167 tag);
168 else
169 printk(KERN_INFO
170 "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
171 tag, rc);
172
173}
175 174
176/* 175/*
177 * H_GET_PPP hcall returns info in 4 parms. 176 * H_GET_PPP hcall returns info in 4 parms.
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec_64.c
index 07ea03598c00..97c51e452be7 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -185,8 +185,8 @@ void kexec_copy_flush(struct kimage *image)
185 */ 185 */
186void kexec_smp_down(void *arg) 186void kexec_smp_down(void *arg)
187{ 187{
188 if (ppc_md.cpu_irq_down) 188 if (ppc_md.kexec_cpu_down)
189 ppc_md.cpu_irq_down(1); 189 ppc_md.kexec_cpu_down(0, 1);
190 190
191 local_irq_disable(); 191 local_irq_disable();
192 kexec_smp_wait(); 192 kexec_smp_wait();
@@ -233,8 +233,8 @@ static void kexec_prepare_cpus(void)
233 } 233 }
234 234
235 /* after we tell the others to go down */ 235 /* after we tell the others to go down */
236 if (ppc_md.cpu_irq_down) 236 if (ppc_md.kexec_cpu_down)
237 ppc_md.cpu_irq_down(0); 237 ppc_md.kexec_cpu_down(0, 0);
238 238
239 put_cpu(); 239 put_cpu();
240 240
@@ -255,8 +255,8 @@ static void kexec_prepare_cpus(void)
255 * UP to an SMP kernel. 255 * UP to an SMP kernel.
256 */ 256 */
257 smp_release_cpus(); 257 smp_release_cpus();
258 if (ppc_md.cpu_irq_down) 258 if (ppc_md.kexec_cpu_down)
259 ppc_md.cpu_irq_down(0); 259 ppc_md.kexec_cpu_down(0, 0);
260 local_irq_disable(); 260 local_irq_disable();
261} 261}
262 262
@@ -305,3 +305,54 @@ void machine_kexec(struct kimage *image)
305 ppc_md.hpte_clear_all); 305 ppc_md.hpte_clear_all);
306 /* NOTREACHED */ 306 /* NOTREACHED */
307} 307}
308
309/* Values we need to export to the second kernel via the device tree. */
310static unsigned long htab_base, htab_size, kernel_end;
311
312static struct property htab_base_prop = {
313 .name = "linux,htab-base",
314 .length = sizeof(unsigned long),
315 .value = (unsigned char *)&htab_base,
316};
317
318static struct property htab_size_prop = {
319 .name = "linux,htab-size",
320 .length = sizeof(unsigned long),
321 .value = (unsigned char *)&htab_size,
322};
323
324static struct property kernel_end_prop = {
325 .name = "linux,kernel-end",
326 .length = sizeof(unsigned long),
327 .value = (unsigned char *)&kernel_end,
328};
329
330static void __init export_htab_values(void)
331{
332 struct device_node *node;
333
334 node = of_find_node_by_path("/chosen");
335 if (!node)
336 return;
337
338 kernel_end = __pa(_end);
339 prom_add_property(node, &kernel_end_prop);
340
341 /* On machines with no htab htab_address is NULL */
342 if (NULL == htab_address)
343 goto out;
344
345 htab_base = __pa(htab_address);
346 prom_add_property(node, &htab_base_prop);
347
348 htab_size = 1UL << ppc64_pft_size;
349 prom_add_property(node, &htab_size_prop);
350
351 out:
352 of_node_put(node);
353}
354
355void __init kexec_setup(void)
356{
357 export_htab_values();
358}
diff --git a/arch/ppc64/kernel/module.c b/arch/powerpc/kernel/module_64.c
index 928b8581fcb0..928b8581fcb0 100644
--- a/arch/ppc64/kernel/module.c
+++ b/arch/powerpc/kernel/module_64.c
diff --git a/arch/ppc64/kernel/pci.c b/arch/powerpc/kernel/pci_64.c
index 3cef1b8f57f0..3cef1b8f57f0 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/powerpc/kernel/pci_64.c
diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c
index e1a32f802c0b..e1a32f802c0b 100644
--- a/arch/ppc64/kernel/pci_direct_iommu.c
+++ b/arch/powerpc/kernel/pci_direct_iommu.c
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 12c4c9e9bbc7..12c4c9e9bbc7 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
index bdf15dbbf4f0..bdf15dbbf4f0 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/powerpc/kernel/pci_iommu.c
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 5dcf4ba05ee8..59846b40d521 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -105,6 +105,13 @@ EXPORT_SYMBOL(__clear_user);
105EXPORT_SYMBOL(__strncpy_from_user); 105EXPORT_SYMBOL(__strncpy_from_user);
106EXPORT_SYMBOL(__strnlen_user); 106EXPORT_SYMBOL(__strnlen_user);
107 107
108#ifndef __powerpc64__
109EXPORT_SYMBOL(__ide_mm_insl);
110EXPORT_SYMBOL(__ide_mm_outsw);
111EXPORT_SYMBOL(__ide_mm_insw);
112EXPORT_SYMBOL(__ide_mm_outsl);
113#endif
114
108EXPORT_SYMBOL(_insb); 115EXPORT_SYMBOL(_insb);
109EXPORT_SYMBOL(_outsb); 116EXPORT_SYMBOL(_outsb);
110EXPORT_SYMBOL(_insw); 117EXPORT_SYMBOL(_insw);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6a5b468edb4d..3bf968e74095 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1368,6 +1368,7 @@ prom_n_addr_cells(struct device_node* np)
1368 /* No #address-cells property for the root node, default to 1 */ 1368 /* No #address-cells property for the root node, default to 1 */
1369 return 1; 1369 return 1;
1370} 1370}
1371EXPORT_SYMBOL(prom_n_addr_cells);
1371 1372
1372int 1373int
1373prom_n_size_cells(struct device_node* np) 1374prom_n_size_cells(struct device_node* np)
@@ -1383,6 +1384,7 @@ prom_n_size_cells(struct device_node* np)
1383 /* No #size-cells property for the root node, default to 1 */ 1384 /* No #size-cells property for the root node, default to 1 */
1384 return 1; 1385 return 1;
1385} 1386}
1387EXPORT_SYMBOL(prom_n_size_cells);
1386 1388
1387/** 1389/**
1388 * Work out the sense (active-low level / active-high edge) 1390 * Work out the sense (active-low level / active-high edge)
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
new file mode 100644
index 000000000000..7b948662704c
--- /dev/null
+++ b/arch/powerpc/kernel/rtas-rtc.c
@@ -0,0 +1,105 @@
1#include <linux/kernel.h>
2#include <linux/time.h>
3#include <linux/timer.h>
4#include <linux/init.h>
5#include <linux/rtc.h>
6#include <linux/delay.h>
7#include <asm/prom.h>
8#include <asm/rtas.h>
9#include <asm/time.h>
10
11
12#define MAX_RTC_WAIT 5000 /* 5 sec */
13#define RTAS_CLOCK_BUSY (-2)
14unsigned long __init rtas_get_boot_time(void)
15{
16 int ret[8];
17 int error, wait_time;
18 unsigned long max_wait_tb;
19
20 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
21 do {
22 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
23 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
24 wait_time = rtas_extended_busy_delay_time(error);
25 /* This is boot time so we spin. */
26 udelay(wait_time*1000);
27 error = RTAS_CLOCK_BUSY;
28 }
29 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
30
31 if (error != 0 && printk_ratelimit()) {
32 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
33 error);
34 return 0;
35 }
36
37 return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
38}
39
40/* NOTE: get_rtc_time will get an error if executed in interrupt context
41 * and if a delay is needed to read the clock. In this case we just
42 * silently return without updating rtc_tm.
43 */
44void rtas_get_rtc_time(struct rtc_time *rtc_tm)
45{
46 int ret[8];
47 int error, wait_time;
48 unsigned long max_wait_tb;
49
50 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
51 do {
52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
54 if (in_interrupt() && printk_ratelimit()) {
55 memset(&rtc_tm, 0, sizeof(struct rtc_time));
56 printk(KERN_WARNING "error: reading clock"
57 " would delay interrupt\n");
58 return; /* delay not allowed */
59 }
60 wait_time = rtas_extended_busy_delay_time(error);
61 msleep(wait_time);
62 error = RTAS_CLOCK_BUSY;
63 }
64 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
65
66 if (error != 0 && printk_ratelimit()) {
67 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
68 error);
69 return;
70 }
71
72 rtc_tm->tm_sec = ret[5];
73 rtc_tm->tm_min = ret[4];
74 rtc_tm->tm_hour = ret[3];
75 rtc_tm->tm_mday = ret[2];
76 rtc_tm->tm_mon = ret[1] - 1;
77 rtc_tm->tm_year = ret[0] - 1900;
78}
79
80int rtas_set_rtc_time(struct rtc_time *tm)
81{
82 int error, wait_time;
83 unsigned long max_wait_tb;
84
85 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
86 do {
87 error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
88 tm->tm_year + 1900, tm->tm_mon + 1,
89 tm->tm_mday, tm->tm_hour, tm->tm_min,
90 tm->tm_sec, 0);
91 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
92 if (in_interrupt())
93 return 1; /* probably decrementer */
94 wait_time = rtas_extended_busy_delay_time(error);
95 msleep(wait_time);
96 error = RTAS_CLOCK_BUSY;
97 }
98 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
99
100 if (error != 0 && printk_ratelimit())
101 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
102 error);
103
104 return 0;
105}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index c98cfcc9cd9a..e5694335bf10 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -57,10 +57,6 @@ extern void power4_idle(void);
57boot_infos_t *boot_infos; 57boot_infos_t *boot_infos;
58struct ide_machdep_calls ppc_ide_md; 58struct ide_machdep_calls ppc_ide_md;
59 59
60/* XXX should go elsewhere */
61int __irq_offset_value;
62EXPORT_SYMBOL(__irq_offset_value);
63
64int boot_cpuid; 60int boot_cpuid;
65EXPORT_SYMBOL_GPL(boot_cpuid); 61EXPORT_SYMBOL_GPL(boot_cpuid);
66int boot_cpuid_phys; 62int boot_cpuid_phys;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fdbd9f9122f2..608fee7c7e20 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -59,6 +59,7 @@
59#include <asm/firmware.h> 59#include <asm/firmware.h>
60#include <asm/xmon.h> 60#include <asm/xmon.h>
61#include <asm/udbg.h> 61#include <asm/udbg.h>
62#include <asm/kexec.h>
62 63
63#include "setup.h" 64#include "setup.h"
64 65
@@ -415,6 +416,10 @@ void __init setup_system(void)
415 */ 416 */
416 unflatten_device_tree(); 417 unflatten_device_tree();
417 418
419#ifdef CONFIG_KEXEC
420 kexec_setup(); /* requires unflattened device tree. */
421#endif
422
418 /* 423 /*
419 * Fill the ppc64_caches & systemcfg structures with informations 424 * Fill the ppc64_caches & systemcfg structures with informations
420 * retreived from the device-tree. Need to be called before 425 * retreived from the device-tree. Need to be called before
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 8bdf95b7e420..5a2eba60dd39 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -403,8 +403,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
403 ELF_NFPREG * sizeof(double))) 403 ELF_NFPREG * sizeof(double)))
404 return 1; 404 return 1;
405 405
406 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
407
408#ifdef CONFIG_ALTIVEC 406#ifdef CONFIG_ALTIVEC
409 /* save altivec registers */ 407 /* save altivec registers */
410 if (current->thread.used_vr) { 408 if (current->thread.used_vr) {
@@ -818,6 +816,9 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
818 goto badframe; 816 goto badframe;
819 regs->link = (unsigned long) frame->tramp; 817 regs->link = (unsigned long) frame->tramp;
820 } 818 }
819
820 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
821
821 if (put_user(regs->gpr[1], (u32 __user *)newsp)) 822 if (put_user(regs->gpr[1], (u32 __user *)newsp))
822 goto badframe; 823 goto badframe;
823 regs->gpr[1] = newsp; 824 regs->gpr[1] = newsp;
@@ -1097,6 +1098,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1097 regs->link = (unsigned long) frame->mctx.tramp; 1098 regs->link = (unsigned long) frame->mctx.tramp;
1098 } 1099 }
1099 1100
1101 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
1102
1100 if (put_user(regs->gpr[1], (u32 __user *)newsp)) 1103 if (put_user(regs->gpr[1], (u32 __user *)newsp))
1101 goto badframe; 1104 goto badframe;
1102 regs->gpr[1] = newsp; 1105 regs->gpr[1] = newsp;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 58194e150711..1decf2785530 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -131,9 +131,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
131 131
132 flush_fp_to_thread(current); 132 flush_fp_to_thread(current);
133 133
134 /* Make sure signal doesn't get spurrious FP exceptions */
135 current->thread.fpscr.val = 0;
136
137#ifdef CONFIG_ALTIVEC 134#ifdef CONFIG_ALTIVEC
138 err |= __put_user(v_regs, &sc->v_regs); 135 err |= __put_user(v_regs, &sc->v_regs);
139 136
@@ -423,6 +420,9 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
423 if (err) 420 if (err)
424 goto badframe; 421 goto badframe;
425 422
423 /* Make sure signal handler doesn't get spurious FP exceptions */
424 current->thread.fpscr.val = 0;
425
426 /* Set up to return from userspace. */ 426 /* Set up to return from userspace. */
427 if (vdso64_rt_sigtramp && current->thread.vdso_base) { 427 if (vdso64_rt_sigtramp && current->thread.vdso_base) {
428 regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; 428 regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index a08c26e87835..f6b38472318d 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -77,8 +77,9 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
77 mflr r12 77 mflr r12
78 .cfi_register lr,r12 78 .cfi_register lr,r12
79 bl __get_datapage@local 79 bl __get_datapage@local
80 lwz r3,CFG_TB_TICKS_PER_SEC(r3)
81 lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) 80 lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
81 lwz r3,CFG_TB_TICKS_PER_SEC(r3)
82 mtlr r12 82 mtlr r12
83 blr
83 .cfi_endproc 84 .cfi_endproc
84V_FUNCTION_END(__kernel_get_tbfreq) 85V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index aeb5fc9b87b3..0a32a41d50b0 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -83,7 +83,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
83 /* Check for supported clock IDs */ 83 /* Check for supported clock IDs */
84 cmpli cr0,r3,CLOCK_REALTIME 84 cmpli cr0,r3,CLOCK_REALTIME
85 cmpli cr1,r3,CLOCK_MONOTONIC 85 cmpli cr1,r3,CLOCK_MONOTONIC
86 cror cr0,cr0,cr1 86 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
87 bne cr0,99f 87 bne cr0,99f
88 88
89 mflr r12 /* r12 saves lr */ 89 mflr r12 /* r12 saves lr */
@@ -91,7 +91,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
91 mr r10,r3 /* r10 saves id */ 91 mr r10,r3 /* r10 saves id */
92 mr r11,r4 /* r11 saves tp */ 92 mr r11,r4 /* r11 saves tp */
93 bl __get_datapage@local /* get data page */ 93 bl __get_datapage@local /* get data page */
94 mr r9, r3 /* datapage ptr in r9 */ 94 mr r9,r3 /* datapage ptr in r9 */
95 beq cr1,50f /* if monotonic -> jump there */ 95 beq cr1,50f /* if monotonic -> jump there */
96 96
97 /* 97 /*
@@ -173,10 +173,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
173 add r4,r4,r7 173 add r4,r4,r7
174 lis r5,NSEC_PER_SEC@h 174 lis r5,NSEC_PER_SEC@h
175 ori r5,r5,NSEC_PER_SEC@l 175 ori r5,r5,NSEC_PER_SEC@l
176 cmpli cr0,r4,r5 176 cmpl cr0,r4,r5
177 cmpli cr1,r4,0
177 blt 1f 178 blt 1f
178 subf r4,r5,r4 179 subf r4,r5,r4
179 addi r3,r3,1 180 addi r3,r3,1
1811: bge cr1,1f
182 addi r3,r3,-1
183 add r4,r4,r5
1801: stw r3,TSPC32_TV_SEC(r11) 1841: stw r3,TSPC32_TV_SEC(r11)
181 stw r4,TSPC32_TV_NSEC(r11) 185 stw r4,TSPC32_TV_NSEC(r11)
182 186
@@ -210,7 +214,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
210 /* Check for supported clock IDs */ 214 /* Check for supported clock IDs */
211 cmpwi cr0,r3,CLOCK_REALTIME 215 cmpwi cr0,r3,CLOCK_REALTIME
212 cmpwi cr1,r3,CLOCK_MONOTONIC 216 cmpwi cr1,r3,CLOCK_MONOTONIC
213 cror cr0,cr0,cr1 217 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
214 bne cr0,99f 218 bne cr0,99f
215 219
216 li r3,0 220 li r3,0
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index e67eda0f8cda..6393e4137bc7 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -80,5 +80,6 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
80 bl V_LOCAL_FUNC(__get_datapage) 80 bl V_LOCAL_FUNC(__get_datapage)
81 ld r3,CFG_TB_TICKS_PER_SEC(r3) 81 ld r3,CFG_TB_TICKS_PER_SEC(r3)
82 mtlr r12 82 mtlr r12
83 blr
83 .cfi_endproc 84 .cfi_endproc
84V_FUNCTION_END(__kernel_get_tbfreq) 85V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index d371c02a8c0e..1a89094715cc 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -1,4 +1,5 @@
1/* 1
2 /*
2 * Userland implementation of gettimeofday() for 64 bits processes in a 3 * Userland implementation of gettimeofday() for 64 bits processes in a
3 * ppc64 kernel for use in the vDSO 4 * ppc64 kernel for use in the vDSO
4 * 5 *
@@ -68,7 +69,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
68 /* Check for supported clock IDs */ 69 /* Check for supported clock IDs */
69 cmpwi cr0,r3,CLOCK_REALTIME 70 cmpwi cr0,r3,CLOCK_REALTIME
70 cmpwi cr1,r3,CLOCK_MONOTONIC 71 cmpwi cr1,r3,CLOCK_MONOTONIC
71 cror cr0,cr0,cr1 72 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
72 bne cr0,99f 73 bne cr0,99f
73 74
74 mflr r12 /* r12 saves lr */ 75 mflr r12 /* r12 saves lr */
@@ -84,16 +85,17 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
84 85
85 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ 86 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
86 87
87 lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ 88 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
88 ori r7,r7,0xca00 89 ori r7,r7,16960
89 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ 90 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
90 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ 91 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
91 std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ 92 std r5,TSPC64_TV_SEC(r11) /* store sec in tv */
92 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ 93 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
93 mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / 94 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
94 * XSEC_PER_SEC 95 * XSEC_PER_SEC
95 */ 96 */
96 rldicl r0,r0,44,20 97 rldicl r0,r0,44,20
98 mulli r0,r0,1000 /* nsec = usec * 1000 */
97 std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ 99 std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */
98 100
99 mtlr r12 101 mtlr r12
@@ -106,15 +108,16 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
106 108
10750: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ 10950: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
108 110
109 lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ 111 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
110 ori r7,r7,0xca00 112 ori r7,r7,16960
111 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ 113 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
112 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ 114 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
113 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ 115 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
114 mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / 116 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
115 * XSEC_PER_SEC 117 * XSEC_PER_SEC
116 */ 118 */
117 rldicl r6,r0,44,20 119 rldicl r6,r0,44,20
120 mulli r6,r6,1000 /* nsec = usec * 1000 */
118 121
119 /* now we must fixup using wall to monotonic. We need to snapshot 122 /* now we must fixup using wall to monotonic. We need to snapshot
120 * that value and do the counter trick again. Fortunately, we still 123 * that value and do the counter trick again. Fortunately, we still
@@ -123,8 +126,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
123 * can be used 126 * can be used
124 */ 127 */
125 128
126 lwz r4,WTOM_CLOCK_SEC(r9) 129 lwa r4,WTOM_CLOCK_SEC(r3)
127 lwz r7,WTOM_CLOCK_NSEC(r9) 130 lwa r7,WTOM_CLOCK_NSEC(r3)
128 131
129 /* We now have our result in r4,r7. We create a fake dependency 132 /* We now have our result in r4,r7. We create a fake dependency
130 * on that result and re-check the counter 133 * on that result and re-check the counter
@@ -144,10 +147,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
144 add r7,r7,r6 147 add r7,r7,r6
145 lis r9,NSEC_PER_SEC@h 148 lis r9,NSEC_PER_SEC@h
146 ori r9,r9,NSEC_PER_SEC@l 149 ori r9,r9,NSEC_PER_SEC@l
147 cmpli cr0,r7,r9 150 cmpl cr0,r7,r9
151 cmpli cr1,r7,0
148 blt 1f 152 blt 1f
149 subf r7,r9,r7 153 subf r7,r9,r7
150 addi r4,r4,1 154 addi r4,r4,1
1551: bge cr1,1f
156 addi r4,r4,-1
157 add r7,r7,r9
1511: std r4,TSPC64_TV_SEC(r11) 1581: std r4,TSPC64_TV_SEC(r11)
152 std r7,TSPC64_TV_NSEC(r11) 159 std r7,TSPC64_TV_NSEC(r11)
153 160
@@ -181,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
181 /* Check for supported clock IDs */ 188 /* Check for supported clock IDs */
182 cmpwi cr0,r3,CLOCK_REALTIME 189 cmpwi cr0,r3,CLOCK_REALTIME
183 cmpwi cr1,r3,CLOCK_MONOTONIC 190 cmpwi cr1,r3,CLOCK_MONOTONIC
184 cror cr0,cr0,cr1 191 cror cr0*4+eq,cr0*4+eq,cr1*4+eq
185 bne cr0,99f 192 bne cr0,99f
186 193
187 li r3,0 194 li r3,0
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index af9ca0eb6d55..5d581bb3aa12 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Modifications by Kumar Gala (kumar.gala@freescale.com) to support 2 * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
3 * E500 Book E processors. 3 * E500 Book E processors.
4 * 4 *
5 * Copyright 2004 Freescale Semiconductor, Inc 5 * Copyright 2004 Freescale Semiconductor, Inc
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index 86124a94c9af..26539cda6023 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -7,7 +7,7 @@
7 * Copyright (c) 2004 Freescale Semiconductor, Inc 7 * Copyright (c) 2004 Freescale Semiconductor, Inc
8 * 8 *
9 * Author: Andy Fleming 9 * Author: Andy Fleming
10 * Maintainer: Kumar Gala <Kumar.Gala@freescale.com> 10 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 01090e9ce0cf..a58daa153686 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -42,13 +42,6 @@
42#include "irq.h" 42#include "irq.h"
43#include "call_pci.h" 43#include "call_pci.h"
44 44
45/* This maps virtual irq numbers to real irqs */
46unsigned int virt_irq_to_real_map[NR_IRQS];
47
48/* The next available virtual irq number */
49/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
50static int next_virtual_irq = 2;
51
52static long Pci_Interrupt_Count; 45static long Pci_Interrupt_Count;
53static long Pci_Event_Count; 46static long Pci_Event_Count;
54 47
@@ -350,26 +343,14 @@ static hw_irq_controller iSeries_IRQ_handler = {
350int __init iSeries_allocate_IRQ(HvBusNumber busNumber, 343int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
351 HvSubBusNumber subBusNumber, HvAgentId deviceId) 344 HvSubBusNumber subBusNumber, HvAgentId deviceId)
352{ 345{
353 unsigned int realirq, virtirq; 346 int virtirq;
347 unsigned int realirq;
354 u8 idsel = (deviceId >> 4); 348 u8 idsel = (deviceId >> 4);
355 u8 function = deviceId & 7; 349 u8 function = deviceId & 7;
356 350
357 virtirq = next_virtual_irq++;
358 realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; 351 realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
359 virt_irq_to_real_map[virtirq] = realirq; 352 virtirq = virt_irq_create_mapping(realirq);
360 353
361 irq_desc[virtirq].handler = &iSeries_IRQ_handler; 354 irq_desc[virtirq].handler = &iSeries_IRQ_handler;
362 return virtirq; 355 return virtirq;
363} 356}
364
365int virt_irq_create_mapping(unsigned int real_irq)
366{
367 BUG(); /* Don't call this on iSeries, yet */
368
369 return 0;
370}
371
372void virt_irq_init(void)
373{
374 return;
375}
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 6a29f301436b..da26639190db 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -39,7 +39,6 @@
39#include <asm/sections.h> 39#include <asm/sections.h>
40#include <asm/iommu.h> 40#include <asm/iommu.h>
41#include <asm/firmware.h> 41#include <asm/firmware.h>
42#include <asm/systemcfg.h>
43#include <asm/system.h> 42#include <asm/system.h>
44#include <asm/time.h> 43#include <asm/time.h>
45#include <asm/paca.h> 44#include <asm/paca.h>
@@ -548,8 +547,6 @@ static unsigned long __init build_iSeries_Memory_Map(void)
548 */ 547 */
549static void __init iSeries_setup_arch(void) 548static void __init iSeries_setup_arch(void)
550{ 549{
551 unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
552
553 if (get_paca()->lppaca.shared_proc) { 550 if (get_paca()->lppaca.shared_proc) {
554 ppc_md.idle_loop = iseries_shared_idle; 551 ppc_md.idle_loop = iseries_shared_idle;
555 printk(KERN_INFO "Using shared processor idle loop\n"); 552 printk(KERN_INFO "Using shared processor idle loop\n");
@@ -565,9 +562,6 @@ static void __init iSeries_setup_arch(void)
565 itVpdAreas.xSlicMaxLogicalProcs); 562 itVpdAreas.xSlicMaxLogicalProcs);
566 printk("Max physical processors = %d\n", 563 printk("Max physical processors = %d\n",
567 itVpdAreas.xSlicMaxPhysicalProcs); 564 itVpdAreas.xSlicMaxPhysicalProcs);
568
569 _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
570 printk("Processor version = %x\n", _systemcfg->processor);
571} 565}
572 566
573static void iSeries_show_cpuinfo(struct seq_file *m) 567static void iSeries_show_cpuinfo(struct seq_file *m)
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index 5947b21a8588..feb0a94e7819 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -102,7 +102,7 @@ static unsigned long from_rtc_time(struct rtc_time *tm)
102static unsigned long cuda_get_time(void) 102static unsigned long cuda_get_time(void)
103{ 103{
104 struct adb_request req; 104 struct adb_request req;
105 unsigned long now; 105 unsigned int now;
106 106
107 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) 107 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
108 return 0; 108 return 0;
@@ -113,7 +113,7 @@ static unsigned long cuda_get_time(void)
113 req.reply_len); 113 req.reply_len);
114 now = (req.reply[3] << 24) + (req.reply[4] << 16) 114 now = (req.reply[3] << 24) + (req.reply[4] << 16)
115 + (req.reply[5] << 8) + req.reply[6]; 115 + (req.reply[5] << 8) + req.reply[6];
116 return now - RTC_OFFSET; 116 return ((unsigned long)now) - RTC_OFFSET;
117} 117}
118 118
119#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm)) 119#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm))
@@ -146,7 +146,7 @@ static int cuda_set_rtc_time(struct rtc_time *tm)
146static unsigned long pmu_get_time(void) 146static unsigned long pmu_get_time(void)
147{ 147{
148 struct adb_request req; 148 struct adb_request req;
149 unsigned long now; 149 unsigned int now;
150 150
151 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) 151 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
152 return 0; 152 return 0;
@@ -156,7 +156,7 @@ static unsigned long pmu_get_time(void)
156 req.reply_len); 156 req.reply_len);
157 now = (req.reply[0] << 24) + (req.reply[1] << 16) 157 now = (req.reply[0] << 24) + (req.reply[1] << 16)
158 + (req.reply[2] << 8) + req.reply[3]; 158 + (req.reply[2] << 8) + req.reply[3];
159 return now - RTC_OFFSET; 159 return ((unsigned long)now) - RTC_OFFSET;
160} 160}
161 161
162#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm)) 162#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm))
@@ -199,6 +199,7 @@ static unsigned long smu_get_time(void)
199#define smu_set_rtc_time(tm, spin) 0 199#define smu_set_rtc_time(tm, spin) 0
200#endif 200#endif
201 201
202/* Can't be __init, it's called when suspending and resuming */
202unsigned long pmac_get_boot_time(void) 203unsigned long pmac_get_boot_time(void)
203{ 204{
204 /* Get the time from the RTC, used only at boot time */ 205 /* Get the time from the RTC, used only at boot time */
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index e7ca5b1f591e..06d5ef501218 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -4,4 +4,7 @@ obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_IBMVIO) += vio.o 4obj-$(CONFIG_IBMVIO) += vio.o
5obj-$(CONFIG_XICS) += xics.o 5obj-$(CONFIG_XICS) += xics.o
6obj-$(CONFIG_SCANLOG) += scanlog.o 6obj-$(CONFIG_SCANLOG) += scanlog.o
7obj-$(CONFIG_EEH) += eeh.o eeh_event.o 7obj-$(CONFIG_EEH) += eeh.o eeh_event.o
8
9obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
10obj-$(CONFIG_HVCS) += hvcserver.o
diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 138e128a3886..138e128a3886 100644
--- a/arch/ppc64/kernel/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
diff --git a/arch/ppc64/kernel/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c
index 4d584172055a..4d584172055a 100644
--- a/arch/ppc64/kernel/hvcserver.c
+++ b/arch/powerpc/platforms/pseries/hvcserver.c
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 31990829310c..b9d9732b2e06 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(void)
200 if (ppc64_interrupt_controller == IC_OPEN_PIC) { 200 if (ppc64_interrupt_controller == IC_OPEN_PIC) {
201 ppc_md.init_IRQ = pSeries_init_mpic; 201 ppc_md.init_IRQ = pSeries_init_mpic;
202 ppc_md.get_irq = mpic_get_irq; 202 ppc_md.get_irq = mpic_get_irq;
203 ppc_md.cpu_irq_down = mpic_teardown_this_cpu;
204 /* Allocate the mpic now, so that find_and_init_phbs() can 203 /* Allocate the mpic now, so that find_and_init_phbs() can
205 * fill the ISUs */ 204 * fill the ISUs */
206 pSeries_setup_mpic(); 205 pSeries_setup_mpic();
207 } else { 206 } else {
208 ppc_md.init_IRQ = xics_init_IRQ; 207 ppc_md.init_IRQ = xics_init_IRQ;
209 ppc_md.get_irq = xics_get_irq; 208 ppc_md.get_irq = xics_get_irq;
210 ppc_md.cpu_irq_down = xics_teardown_cpu;
211 } 209 }
212 210
213#ifdef CONFIG_SMP 211#ifdef CONFIG_SMP
@@ -595,6 +593,27 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
595 return PCI_PROBE_NORMAL; 593 return PCI_PROBE_NORMAL;
596} 594}
597 595
596#ifdef CONFIG_KEXEC
597static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
598{
599 /* Don't risk a hypervisor call if we're crashing */
600 if (!crash_shutdown) {
601 unsigned long vpa = __pa(&get_paca()->lppaca);
602
603 if (unregister_vpa(hard_smp_processor_id(), vpa)) {
604 printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
605 "failed\n", smp_processor_id(),
606 hard_smp_processor_id());
607 }
608 }
609
610 if (ppc64_interrupt_controller == IC_OPEN_PIC)
611 mpic_teardown_this_cpu(secondary);
612 else
613 xics_teardown_cpu(secondary);
614}
615#endif
616
598struct machdep_calls __initdata pSeries_md = { 617struct machdep_calls __initdata pSeries_md = {
599 .probe = pSeries_probe, 618 .probe = pSeries_probe,
600 .setup_arch = pSeries_setup_arch, 619 .setup_arch = pSeries_setup_arch,
@@ -617,4 +636,7 @@ struct machdep_calls __initdata pSeries_md = {
617 .check_legacy_ioport = pSeries_check_legacy_ioport, 636 .check_legacy_ioport = pSeries_check_legacy_ioport,
618 .system_reset_exception = pSeries_system_reset_exception, 637 .system_reset_exception = pSeries_system_reset_exception,
619 .machine_check_exception = pSeries_machine_check_exception, 638 .machine_check_exception = pSeries_machine_check_exception,
639#ifdef CONFIG_KEXEC
640 .kexec_cpu_down = pseries_kexec_cpu_down,
641#endif
620}; 642};
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index ef4356b29a97..c45a6ad5f3b7 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -19,6 +19,7 @@
19#include <linux/cpumask.h> 19#include <linux/cpumask.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/sysrq.h> 21#include <linux/sysrq.h>
22#include <linux/interrupt.h>
22 23
23#include <asm/ptrace.h> 24#include <asm/ptrace.h>
24#include <asm/string.h> 25#include <asm/string.h>
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 5063c603fad4..8d60fa99fc4b 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
24 * Copyright 2002-2004 MontaVista Software, Inc. 24 * Copyright 2002-2004 MontaVista Software, Inc.
25 * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> 25 * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
26 * Copyright 2004 Freescale Semiconductor, Inc 26 * Copyright 2004 Freescale Semiconductor, Inc
27 * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com> 27 * PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
28 * 28 *
29 * This program is free software; you can redistribute it and/or modify it 29 * This program is free software; you can redistribute it and/or modify it
30 * under the terms of the GNU General Public License as published by the 30 * under the terms of the GNU General Public License as published by the
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c
index af9ca0eb6d55..5d581bb3aa12 100644
--- a/arch/ppc/mm/fsl_booke_mmu.c
+++ b/arch/ppc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Modifications by Kumar Gala (kumar.gala@freescale.com) to support 2 * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
3 * E500 Book E processors. 3 * E500 Book E processors.
4 * 4 *
5 * Copyright 2004 Freescale Semiconductor, Inc 5 * Copyright 2004 Freescale Semiconductor, Inc
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 98edc75f4105..04bdc39bf47b 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC834x SYS board specific routines 4 * MPC834x SYS board specific routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
@@ -73,12 +73,19 @@ mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
73 * A B C D 73 * A B C D
74 */ 74 */
75 { 75 {
76 {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */ 76 {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
77 {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */ 77 {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
78 {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */ 78 {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */
79 {0, 0, 0, 0},
80 {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */
81 {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */
82 {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */
83 {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */
84 {0, 0, 0, 0}, /* idsel 0x19 */
85 {0, 0, 0, 0}, /* idsel 0x20 */
79 }; 86 };
80 87
81 const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4; 88 const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
82 return PCI_IRQ_TABLE_LOOKUP; 89 return PCI_IRQ_TABLE_LOOKUP;
83} 90}
84 91
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 58e44c042535..2e514d316fb8 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC834X SYS common board definitions 4 * MPC834X SYS common board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor, Inc. 8 * Copyright 2005 Freescale Semiconductor, Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 7e952c1228cb..c5cde97c6ef0 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8540ADS board specific routines 4 * MPC8540ADS board specific routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
index 3d05d7c4a938..e48ca3a97397 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8540ADS board definitions 4 * MPC8540ADS board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc8555_cds.h b/arch/ppc/platforms/85xx/mpc8555_cds.h
index e0e75568bc57..1a8e6c67355d 100644
--- a/arch/ppc/platforms/85xx/mpc8555_cds.h
+++ b/arch/ppc/platforms/85xx/mpc8555_cds.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8555CDS board definitions 4 * MPC8555CDS board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 208433f1e93a..8e39a5517092 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8560ADS board specific routines 4 * MPC8560ADS board specific routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.h b/arch/ppc/platforms/85xx/mpc8560_ads.h
index 7df885d73e9d..143ae7eefa7c 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8540ADS board definitions 4 * MPC8540ADS board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index 16ad092d8a06..17ce48fe3503 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx ADS board common routines 4 * MPC85xx ADS board common routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 84acf6e8d45e..7b26bcc5d10d 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85XX ADS common board definitions 4 * MPC85XX ADS common board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index a21156967a5e..d8991b88dc9c 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx CDS board specific routines 4 * MPC85xx CDS board specific routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor, Inc 8 * Copyright 2004 Freescale Semiconductor, Inc
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 12b292c6ae32..5b588cfd0e41 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx CDS board definitions 4 * MPC85xx CDS board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor, Inc 8 * Copyright 2004 Freescale Semiconductor, Inc
9 * 9 *
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index b4ee1707a836..45a5b81b4ed1 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Wind River SBC8560 board specific routines 4 * Wind River SBC8560 board specific routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 58884a63ebdb..1e69b0593162 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -2317,6 +2317,14 @@ static struct pmac_mb_def pmac_mb_defs[] = {
2317 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, 2317 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2318 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, 2318 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2319 }, 2319 },
2320 { "PowerBook5,8", "PowerBook G4 15\"",
2321 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2322 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2323 },
2324 { "PowerBook5,9", "PowerBook G4 17\"",
2325 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2326 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2327 },
2320 { "PowerBook6,1", "PowerBook G4 12\"", 2328 { "PowerBook6,1", "PowerBook G4 12\"",
2321 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, 2329 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2322 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, 2330 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 6a1475c1e128..71c9fca1fe9b 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * PQ2ADS platform support 4 * PQ2ADS platform support
5 * 5 *
6 * Author: Kumar Gala <kumar.gala@freescale.com> 6 * Author: Kumar Gala <galak@kernel.crashing.org>
7 * Derived from: est8260_setup.c by Allen Curtis 7 * Derived from: est8260_setup.c by Allen Curtis
8 * 8 *
9 * Copyright 2004 Freescale Semiconductor, Inc. 9 * Copyright 2004 Freescale Semiconductor, Inc.
diff --git a/arch/ppc/syslib/ipic.h b/arch/ppc/syslib/ipic.h
index 2b56a4fcf373..a7ce7da8785c 100644
--- a/arch/ppc/syslib/ipic.h
+++ b/arch/ppc/syslib/ipic.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * IPIC private definitions and structure. 4 * IPIC private definitions and structure.
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor, Inc 8 * Copyright 2005 Freescale Semiconductor, Inc
9 * 9 *
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index f43fbf9a9389..847df4409982 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC83xx Device descriptions 4 * MPC83xx Device descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index da743446789b..a1523989aff4 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC83xx System descriptions 4 * MPC83xx System descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 2ede677a0a53..69949d255658 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx Device descriptions 4 * MPC85xx Device descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index cb68d8c58348..397cfbcce5ea 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx System descriptions 4 * MPC85xx System descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index 2b5f0e701687..92dc98b36bde 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8xx Device descriptions 4 * MPC8xx Device descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.com> 8 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.com>
9 * 9 *
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index 3cc27d29e3af..d3c617521603 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC8xx System descriptions 4 * MPC8xx System descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> 8 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
9 * 9 *
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index 4da168a6ad03..1b5fe9e398d4 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC83XX common board code 4 * MPC83XX common board code
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ppc83xx_setup.h
index c766c1a5f786..a122a7322e5e 100644
--- a/arch/ppc/syslib/ppc83xx_setup.h
+++ b/arch/ppc/syslib/ppc83xx_setup.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC83XX common board definitions 4 * MPC83XX common board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc85xx_common.c b/arch/ppc/syslib/ppc85xx_common.c
index da841dacdc13..19ad537225e4 100644
--- a/arch/ppc/syslib/ppc85xx_common.c
+++ b/arch/ppc/syslib/ppc85xx_common.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx support routines 4 * MPC85xx support routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc85xx_common.h b/arch/ppc/syslib/ppc85xx_common.h
index 2c8f304441bf..94edf32151dd 100644
--- a/arch/ppc/syslib/ppc85xx_common.h
+++ b/arch/ppc/syslib/ppc85xx_common.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85xx support routines 4 * MPC85xx support routines
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index de2f90576577..1a47ff4b831d 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85XX common board code 4 * MPC85XX common board code
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h
index 6e6cfe162faf..e340b0545fb5 100644
--- a/arch/ppc/syslib/ppc85xx_setup.h
+++ b/arch/ppc/syslib/ppc85xx_setup.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * MPC85XX common board definitions 4 * MPC85XX common board definitions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2004 Freescale Semiconductor Inc. 8 * Copyright 2004 Freescale Semiconductor Inc.
9 * 9 *
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 603f01190816..c0b93c4191ee 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * PPC System library functions 4 * PPC System library functions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * Copyright 2005 Freescale Semiconductor Inc. 8 * Copyright 2005 Freescale Semiconductor Inc.
9 * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> 9 * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index e960fe935325..6ff3aab82fc3 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * PQ2 Device descriptions 4 * PQ2 Device descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * This file is licensed under the terms of the GNU General Public License 8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any 9 * version 2. This program is licensed "as is" without any warranty of any
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 7b6c9ebdb9e3..36d6e2179940 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * PQ2 System descriptions 4 * PQ2 System descriptions
5 * 5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com> 6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 * 7 *
8 * This file is licensed under the terms of the GNU General Public License 8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any 9 * version 2. This program is licensed "as is" without any warranty of any
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
deleted file mode 100644
index 9d10c12e87fe..000000000000
--- a/arch/ppc64/Kconfig
+++ /dev/null
@@ -1,520 +0,0 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6config 64BIT
7 def_bool y
8
9config MMU
10 bool
11 default y
12
13config PPC_STD_MMU
14 def_bool y
15
16config UID16
17 bool
18
19config RWSEM_GENERIC_SPINLOCK
20 bool
21
22config RWSEM_XCHGADD_ALGORITHM
23 bool
24 default y
25
26config GENERIC_CALIBRATE_DELAY
27 bool
28 default y
29
30config GENERIC_ISA_DMA
31 bool
32 default y
33
34config EARLY_PRINTK
35 bool
36 default y
37
38config COMPAT
39 bool
40 default y
41
42config SCHED_NO_NO_OMIT_FRAME_POINTER
43 bool
44 default y
45
46config ARCH_MAY_HAVE_PC_FDC
47 bool
48 default y
49
50config PPC_STD_MMU
51 bool
52 default y
53
54# We optimistically allocate largepages from the VM, so make the limit
55# large enough (16MB). This badly named config option is actually
56# max order + 1
57config FORCE_MAX_ZONEORDER
58 int
59 default "9" if PPC_64K_PAGES
60 default "13"
61
62source "init/Kconfig"
63
64config SYSVIPC_COMPAT
65 bool
66 depends on COMPAT && SYSVIPC
67 default y
68
69menu "Platform support"
70
71choice
72 prompt "Platform Type"
73 default PPC_MULTIPLATFORM
74
75config PPC_ISERIES
76 bool "IBM Legacy iSeries"
77
78config PPC_MULTIPLATFORM
79 bool "Generic"
80
81endchoice
82
83config PPC_PSERIES
84 depends on PPC_MULTIPLATFORM
85 bool " IBM pSeries & new iSeries"
86 default y
87
88config PPC_BPA
89 bool " Broadband Processor Architecture"
90 depends on PPC_MULTIPLATFORM
91
92config PPC_PMAC
93 depends on PPC_MULTIPLATFORM
94 bool " Apple G5 based machines"
95 default y
96 select U3_DART
97 select GENERIC_TBSYNC
98
99config PPC_MAPLE
100 depends on PPC_MULTIPLATFORM
101 bool " Maple 970FX Evaluation Board"
102 select U3_DART
103 select MPIC_BROKEN_U3
104 select GENERIC_TBSYNC
105 default n
106 help
107 This option enables support for the Maple 970FX Evaluation Board.
108 For more informations, refer to <http://www.970eval.com>
109
110config PPC
111 bool
112 default y
113
114config PPC64
115 bool
116 default y
117
118config PPC_OF
119 depends on PPC_MULTIPLATFORM
120 bool
121 default y
122
123config XICS
124 depends on PPC_PSERIES
125 bool
126 default y
127
128config MPIC
129 depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
130 bool
131 default y
132
133config PPC_I8259
134 depends on PPC_PSERIES
135 bool
136 default y
137
138config BPA_IIC
139 depends on PPC_BPA
140 bool
141 default y
142
143# VMX is pSeries only for now until somebody writes the iSeries
144# exception vectors for it
145config ALTIVEC
146 bool "Support for VMX (Altivec) vector unit"
147 depends on PPC_MULTIPLATFORM
148 default y
149
150config PPC_SPLPAR
151 depends on PPC_PSERIES
152 bool "Support for shared-processor logical partitions"
153 default n
154 help
155 Enabling this option will make the kernel run more efficiently
156 on logically-partitioned pSeries systems which use shared
157 processors, that is, which share physical processors between
158 two or more partitions.
159
160config KEXEC
161 bool "kexec system call (EXPERIMENTAL)"
162 depends on PPC_MULTIPLATFORM && EXPERIMENTAL
163 help
164 kexec is a system call that implements the ability to shutdown your
165 current kernel, and to start another kernel. It is like a reboot
166 but it is indepedent of the system firmware. And like a reboot
167 you can start any kernel with it, not just Linux.
168
169 The name comes from the similiarity to the exec system call.
170
171 It is an ongoing process to be certain the hardware in a machine
172 is properly shutdown, so do not be surprised if this code does not
173 initially work for you. It may help to enable device hotplugging
174 support. As of this writing the exact hardware interface is
175 strongly in flux, so no good recommendation can be made.
176
177source "drivers/cpufreq/Kconfig"
178
179config CPU_FREQ_PMAC64
180 bool "Support for some Apple G5s"
181 depends on CPU_FREQ && PMAC_SMU && PPC64
182 select CPU_FREQ_TABLE
183 help
184 This adds support for frequency switching on Apple iMac G5,
185 and some of the more recent desktop G5 machines as well.
186
187config IBMVIO
188 depends on PPC_PSERIES || PPC_ISERIES
189 bool
190 default y
191
192config U3_DART
193 bool
194 depends on PPC_MULTIPLATFORM
195 default n
196
197config MPIC_BROKEN_U3
198 bool
199 depends on PPC_MAPLE
200 default y
201
202config GENERIC_TBSYNC
203 def_bool n
204
205config PPC_PMAC64
206 bool
207 depends on PPC_PMAC
208 default y
209
210config BOOTX_TEXT
211 bool "Support for early boot text console"
212 depends PPC_OF
213 help
214 Say Y here to see progress messages from the boot firmware in text
215 mode. Requires an Open Firmware compatible video card.
216
217config POWER4
218 def_bool y
219
220config PPC_FPU
221 def_bool y
222
223config POWER4_ONLY
224 bool "Optimize for POWER4"
225 default n
226 ---help---
227 Cause the compiler to optimize for POWER4 processors. The resulting
228 binary will not work on POWER3 or RS64 processors when compiled with
229 binutils 2.15 or later.
230
231config IOMMU_VMERGE
232 bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
233 depends on EXPERIMENTAL
234 default n
235 help
236 Cause IO segments sent to a device for DMA to be merged virtually
237 by the IOMMU when they happen to have been allocated contiguously.
238 This doesn't add pressure to the IOMMU allocator. However, some
239 drivers don't support getting large merged segments coming back
240 from *_map_sg(). Say Y if you know the drivers you are using are
241 properly handling this case.
242
243config SMP
244 bool "Symmetric multi-processing support"
245 ---help---
246 This enables support for systems with more than one CPU. If you have
247 a system with only one CPU, say N. If you have a system with more
248 than one CPU, say Y.
249
250 If you say N here, the kernel will run on single and multiprocessor
251 machines, but will use only one CPU of a multiprocessor machine. If
252 you say Y here, the kernel will run on single-processor machines.
253 On a single-processor machine, the kernel will run faster if you say
254 N here.
255
256 If you don't know what to do here, say Y.
257
258config NR_CPUS
259 int "Maximum number of CPUs (2-128)"
260 range 2 128
261 depends on SMP
262 default "32"
263
264config HMT
265 bool "Hardware multithreading"
266 depends on SMP && PPC_PSERIES && BROKEN
267 help
268 This option enables hardware multithreading on RS64 cpus.
269 pSeries systems p620 and p660 have such a cpu type.
270
271config NUMA
272 bool "NUMA support"
273 default y if SMP && PPC_PSERIES
274
275config ARCH_SELECT_MEMORY_MODEL
276 def_bool y
277
278config ARCH_FLATMEM_ENABLE
279 def_bool y
280 depends on !NUMA
281
282config ARCH_SPARSEMEM_ENABLE
283 def_bool y
284
285config ARCH_SPARSEMEM_DEFAULT
286 def_bool y
287 depends on NUMA
288
289source "mm/Kconfig"
290
291config HAVE_ARCH_EARLY_PFN_TO_NID
292 def_bool y
293 depends on NEED_MULTIPLE_NODES
294
295config ARCH_MEMORY_PROBE
296 def_bool y
297 depends on MEMORY_HOTPLUG
298
299# Some NUMA nodes have memory ranges that span
300# other nodes. Even though a pfn is valid and
301# between a node's start and end pfns, it may not
302# reside on that node.
303#
304# This is a relatively temporary hack that should
305# be able to go away when sparsemem is fully in
306# place
307config NODES_SPAN_OTHER_NODES
308 def_bool y
309 depends on NEED_MULTIPLE_NODES
310
311config PPC_64K_PAGES
312 bool "64k page size"
313 help
314 This option changes the kernel logical page size to 64k. On machines
315 without processor support for 64k pages, the kernel will simulate
316 them by loading each individual 4k page on demand transparently,
317 while on hardware with such support, it will be used to map
318 normal application pages.
319
320config SCHED_SMT
321 bool "SMT (Hyperthreading) scheduler support"
322 depends on SMP
323 default off
324 help
325 SMT scheduler support improves the CPU scheduler's decision making
326 when dealing with POWER5 cpus at a cost of slightly increased
327 overhead in some places. If unsure say N here.
328
329source "kernel/Kconfig.preempt"
330source kernel/Kconfig.hz
331
332config EEH
333 bool "PCI Extended Error Handling (EEH)" if EMBEDDED
334 depends on PPC_PSERIES
335 default y if !EMBEDDED
336
337#
338# Use the generic interrupt handling code in kernel/irq/:
339#
340config GENERIC_HARDIRQS
341 bool
342 default y
343
344config PPC_RTAS
345 bool
346 depends on PPC_PSERIES || PPC_BPA
347 default y
348
349config RTAS_ERROR_LOGGING
350 bool
351 depends on PPC_RTAS
352 default y
353
354config RTAS_PROC
355 bool "Proc interface to RTAS"
356 depends on PPC_RTAS
357 default y
358
359config RTAS_FLASH
360 tristate "Firmware flash interface"
361 depends on RTAS_PROC
362
363config SCANLOG
364 tristate "Scanlog dump interface"
365 depends on RTAS_PROC && PPC_PSERIES
366
367config LPARCFG
368 tristate "LPAR Configuration Data"
369 depends on PPC_PSERIES || PPC_ISERIES
370 help
371 Provide system capacity information via human readable
372 <key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
373
374config SECCOMP
375 bool "Enable seccomp to safely compute untrusted bytecode"
376 depends on PROC_FS
377 default y
378 help
379 This kernel feature is useful for number crunching applications
380 that may need to compute untrusted bytecode during their
381 execution. By using pipes or other transports made available to
382 the process as file descriptors supporting the read/write
383 syscalls, it's possible to isolate those applications in
384 their own address space using seccomp. Once seccomp is
385 enabled via /proc/<pid>/seccomp, it cannot be disabled
386 and the task is only allowed to execute a few safe syscalls
387 defined by each seccomp mode.
388
389 If unsure, say Y. Only embedded should say N here.
390
391source "fs/Kconfig.binfmt"
392
393config HOTPLUG_CPU
394 bool "Support for hot-pluggable CPUs"
395 depends on SMP && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
396 select HOTPLUG
397 ---help---
398 Say Y here to be able to turn CPUs off and on.
399
400 Say N if you are unsure.
401
402config PROC_DEVICETREE
403 bool "Support for Open Firmware device tree in /proc"
404 help
405 This option adds a device-tree directory under /proc which contains
406 an image of the device tree that the kernel copies from Open
407 Firmware. If unsure, say Y here.
408
409config CMDLINE_BOOL
410 bool "Default bootloader kernel arguments"
411 depends on !PPC_ISERIES
412
413config CMDLINE
414 string "Initial kernel command string"
415 depends on CMDLINE_BOOL
416 default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
417 help
418 On some platforms, there is currently no way for the boot loader to
419 pass arguments to the kernel. For these platforms, you can supply
420 some command-line options at build time by entering them here. In
421 most cases you will need to specify the root device here.
422
423endmenu
424
425config ISA_DMA_API
426 bool
427 default y
428
429menu "Bus Options"
430
431config ISA
432 bool
433 help
434 Find out whether you have ISA slots on your motherboard. ISA is the
435 name of a bus system, i.e. the way the CPU talks to the other stuff
436 inside your box. If you have an Apple machine, say N here; if you
437 have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If
438 you have an embedded board, consult your board documentation.
439
440config SBUS
441 bool
442
443config MCA
444 bool
445
446config EISA
447 bool
448
449config PCI
450 bool "support for PCI devices" if (EMBEDDED && PPC_ISERIES)
451 default y
452 help
453 Find out whether your system includes a PCI bus. PCI is the name of
454 a bus system, i.e. the way the CPU talks to the other stuff inside
455 your box. If you say Y here, the kernel will include drivers and
456 infrastructure code to support PCI bus devices.
457
458config PCI_DOMAINS
459 bool
460 default PCI
461
462source "drivers/pci/Kconfig"
463
464source "drivers/pcmcia/Kconfig"
465
466source "drivers/pci/hotplug/Kconfig"
467
468endmenu
469
470source "net/Kconfig"
471
472source "drivers/Kconfig"
473
474source "fs/Kconfig"
475
476menu "iSeries device drivers"
477 depends on PPC_ISERIES
478
479config VIOCONS
480 tristate "iSeries Virtual Console Support"
481
482config VIODASD
483 tristate "iSeries Virtual I/O disk support"
484 help
485 If you are running on an iSeries system and you want to use
486 virtual disks created and managed by OS/400, say Y.
487
488config VIOCD
489 tristate "iSeries Virtual I/O CD support"
490 help
491 If you are running Linux on an IBM iSeries system and you want to
492 read a CD drive owned by OS/400, say Y here.
493
494config VIOTAPE
495 tristate "iSeries Virtual Tape Support"
496 help
497 If you are running Linux on an iSeries system and you want Linux
498 to read and/or write a tape drive owned by OS/400, say Y here.
499
500endmenu
501
502config VIOPATH
503 bool
504 depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
505 default y
506
507source "arch/powerpc/oprofile/Kconfig"
508
509source "arch/ppc64/Kconfig.debug"
510
511source "security/Kconfig"
512
513config KEYS_COMPAT
514 bool
515 depends on COMPAT && KEYS
516 default y
517
518source "crypto/Kconfig"
519
520source "lib/Kconfig"
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index dac4cc20fa93..e876c213f5ce 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,45 +2,6 @@
2# Makefile for the linux ppc64 kernel. 2# Makefile for the linux ppc64 kernel.
3# 3#
4 4
5ifneq ($(CONFIG_PPC_MERGE),y) 5obj-y += idle.o align.o
6
7EXTRA_CFLAGS += -mno-minimal-toc
8extra-y := head.o vmlinux.lds
9
10obj-y := misc.o prom.o
11
12endif
13
14obj-y += idle.o dma.o \
15 align.o \
16 rtc.o \
17 iommu.o
18
19pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
20
21obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
22 6
23obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o 7obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
24ifneq ($(CONFIG_PPC_MERGE),y)
25obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
26endif
27
28obj-$(CONFIG_KEXEC) += machine_kexec.o
29obj-$(CONFIG_MODULES) += module.o
30ifneq ($(CONFIG_PPC_MERGE),y)
31obj-$(CONFIG_MODULES) += ppc_ksyms.o
32endif
33obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
34ifneq ($(CONFIG_PPC_MERGE),y)
35obj-$(CONFIG_BOOTX_TEXT) += btext.o
36endif
37obj-$(CONFIG_HVCS) += hvcserver.o
38
39obj-$(CONFIG_KPROBES) += kprobes.o
40
41ifneq ($(CONFIG_PPC_MERGE),y)
42ifeq ($(CONFIG_PPC_ISERIES),y)
43arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
44AFLAGS_head.o += -Iarch/powerpc/kernel
45endif
46endif
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
deleted file mode 100644
index 84ab5c18ef52..000000000000
--- a/arch/ppc64/kernel/asm-offsets.c
+++ /dev/null
@@ -1,195 +0,0 @@
1/*
2 * This program is used to generate definitions needed by
3 * assembly language modules.
4 *
5 * We use the technique used in the OSF Mach kernel code:
6 * generate asm statements containing #defines,
7 * compile this file to assembler, and then extract the
8 * #defines from the assembly-language output.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/signal.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/string.h>
22#include <linux/types.h>
23#include <linux/mman.h>
24#include <linux/mm.h>
25#include <linux/time.h>
26#include <linux/hardirq.h>
27#include <asm/io.h>
28#include <asm/page.h>
29#include <asm/pgtable.h>
30#include <asm/processor.h>
31
32#include <asm/paca.h>
33#include <asm/lppaca.h>
34#include <asm/iseries/hv_lp_event.h>
35#include <asm/rtas.h>
36#include <asm/cputable.h>
37#include <asm/cache.h>
38#include <asm/systemcfg.h>
39#include <asm/compat.h>
40
41#define DEFINE(sym, val) \
42 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
43
44#define BLANK() asm volatile("\n->" : : )
45
46int main(void)
47{
48 /* thread struct on stack */
49 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
50 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
51 DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
52
53 /* task_struct->thread */
54 DEFINE(THREAD, offsetof(struct task_struct, thread));
55 DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
56 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
57 DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
58 DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
59 DEFINE(KSP, offsetof(struct thread_struct, ksp));
60 DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
61
62#ifdef CONFIG_ALTIVEC
63 DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
64 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
65 DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
66 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
67#endif /* CONFIG_ALTIVEC */
68 DEFINE(MM, offsetof(struct task_struct, mm));
69 DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
70
71 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
72 DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
73 DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
74 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
75 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
76 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
77 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
78
79 /* paca */
80 DEFINE(PACA_SIZE, sizeof(struct paca_struct));
81 DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
82 DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
83 DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
84 DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
85 DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
86 DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
87 DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
88 DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
89 DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
90 DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
91 DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
92 DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
93 DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
94 DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
95#ifdef CONFIG_PPC_64K_PAGES
96 DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir));
97#endif
98#ifdef CONFIG_HUGETLB_PAGE
99 DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
100 DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
101#endif /* CONFIG_HUGETLB_PAGE */
102 DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
103 DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
104 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
105 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
106 DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
107 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
108 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
109 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
110 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
111 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
112 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
113 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
114
115 /* RTAS */
116 DEFINE(RTASBASE, offsetof(struct rtas_t, base));
117 DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
118
119 /* Interrupt register frame */
120 DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
121
122 DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
123
124 /* 288 = # of volatile regs, int & fp, for leaf routines */
125 /* which do not stack a frame. See the PPC64 ABI. */
126 DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
127 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
128 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
129 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
130 DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
131 DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
132 DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
133 DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
134 DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
135 DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
136 DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
137 DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
138 DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
139 DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
140 DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
141 DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
142 DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
143 DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
144 /*
145 * Note: these symbols include _ because they overlap with special
146 * register names
147 */
148 DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
149 DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
150 DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
151 DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
152 DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
153 DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
154 DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
155 DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
156 DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
157 DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
158 DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
159 DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
160
161 /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
162 DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
163 DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
164
165 DEFINE(CLONE_VM, CLONE_VM);
166 DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
167
168 /* About the CPU features table */
169 DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
170 DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
171 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
172 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
173 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
174
175 /* systemcfg offsets for use by vdso */
176 DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
177 DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
178 DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
179 DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
180 DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
181 DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
182 DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
183 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
184 DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
185
186 /* timeval/timezone offsets for use by vdso */
187 DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
188 DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
189 DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
190 DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
191 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
192 DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
193
194 return 0;
195}
diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c
deleted file mode 100644
index 506a37885c5c..000000000000
--- a/arch/ppc64/kernel/btext.c
+++ /dev/null
@@ -1,792 +0,0 @@
1/*
2 * Procedures for drawing on the screen early on in the boot process.
3 *
4 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 */
6#include <linux/config.h>
7#include <linux/kernel.h>
8#include <linux/string.h>
9#include <linux/init.h>
10
11#include <asm/sections.h>
12#include <asm/prom.h>
13#include <asm/btext.h>
14#include <asm/prom.h>
15#include <asm/page.h>
16#include <asm/mmu.h>
17#include <asm/pgtable.h>
18#include <asm/io.h>
19#include <asm/lmb.h>
20#include <asm/processor.h>
21#include <asm/udbg.h>
22
23#undef NO_SCROLL
24
25#ifndef NO_SCROLL
26static void scrollscreen(void);
27#endif
28
29static void draw_byte(unsigned char c, long locX, long locY);
30static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
33
34static int g_loc_X;
35static int g_loc_Y;
36static int g_max_loc_X;
37static int g_max_loc_Y;
38
39static int dispDeviceRowBytes;
40static int dispDeviceDepth;
41static int dispDeviceRect[4];
42static unsigned char *dispDeviceBase, *logicalDisplayBase;
43
44unsigned long disp_BAT[2] __initdata = {0, 0};
45
46#define cmapsz (16*256)
47
48static unsigned char vga_font[cmapsz];
49
50int boot_text_mapped;
51int force_printk_to_btext = 0;
52
53
54/* Here's a small text engine to use during early boot
55 * or for debugging purposes
56 *
57 * todo:
58 *
59 * - build some kind of vgacon with it to enable early printk
60 * - move to a separate file
61 * - add a few video driver hooks to keep in sync with display
62 * changes.
63 */
64
65void map_boot_text(void)
66{
67 unsigned long base, offset, size;
68 unsigned char *vbase;
69
70 /* By default, we are no longer mapped */
71 boot_text_mapped = 0;
72 if (dispDeviceBase == 0)
73 return;
74 base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
75 offset = ((unsigned long) dispDeviceBase) - base;
76 size = dispDeviceRowBytes * dispDeviceRect[3] + offset
77 + dispDeviceRect[0];
78 vbase = __ioremap(base, size, _PAGE_NO_CACHE);
79 if (vbase == 0)
80 return;
81 logicalDisplayBase = vbase + offset;
82 boot_text_mapped = 1;
83}
84
85int btext_initialize(struct device_node *np)
86{
87 unsigned int width, height, depth, pitch;
88 unsigned long address = 0;
89 u32 *prop;
90
91 prop = (u32 *)get_property(np, "width", NULL);
92 if (prop == NULL)
93 return -EINVAL;
94 width = *prop;
95 prop = (u32 *)get_property(np, "height", NULL);
96 if (prop == NULL)
97 return -EINVAL;
98 height = *prop;
99 prop = (u32 *)get_property(np, "depth", NULL);
100 if (prop == NULL)
101 return -EINVAL;
102 depth = *prop;
103 pitch = width * ((depth + 7) / 8);
104 prop = (u32 *)get_property(np, "linebytes", NULL);
105 if (prop)
106 pitch = *prop;
107 if (pitch == 1)
108 pitch = 0x1000;
109 prop = (u32 *)get_property(np, "address", NULL);
110 if (prop)
111 address = *prop;
112
113 /* FIXME: Add support for PCI reg properties */
114
115 if (address == 0)
116 return -EINVAL;
117
118 g_loc_X = 0;
119 g_loc_Y = 0;
120 g_max_loc_X = width / 8;
121 g_max_loc_Y = height / 16;
122 logicalDisplayBase = (unsigned char *)address;
123 dispDeviceBase = (unsigned char *)address;
124 dispDeviceRowBytes = pitch;
125 dispDeviceDepth = depth;
126 dispDeviceRect[0] = dispDeviceRect[1] = 0;
127 dispDeviceRect[2] = width;
128 dispDeviceRect[3] = height;
129
130 map_boot_text();
131
132 return 0;
133}
134
135static void btext_putc(unsigned char c)
136{
137 btext_drawchar(c);
138}
139
140void __init init_boot_display(void)
141{
142 char *name;
143 struct device_node *np = NULL;
144 int rc = -ENODEV;
145
146 printk("trying to initialize btext ...\n");
147
148 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
149 if (name != NULL) {
150 np = of_find_node_by_path(name);
151 if (np != NULL) {
152 if (strcmp(np->type, "display") != 0) {
153 printk("boot stdout isn't a display !\n");
154 of_node_put(np);
155 np = NULL;
156 }
157 }
158 }
159 if (np)
160 rc = btext_initialize(np);
161 if (rc) {
162 for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
163 if (get_property(np, "linux,opened", NULL)) {
164 printk("trying %s ...\n", np->full_name);
165 rc = btext_initialize(np);
166 printk("result: %d\n", rc);
167 }
168 if (rc == 0)
169 break;
170 }
171 }
172 if (rc == 0 && udbg_putc == NULL)
173 udbg_putc = btext_putc;
174}
175
176
177/* Calc the base address of a given point (x,y) */
178static unsigned char * calc_base(int x, int y)
179{
180 unsigned char *base;
181
182 base = logicalDisplayBase;
183 if (base == 0)
184 base = dispDeviceBase;
185 base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
186 base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
187 return base;
188}
189
190/* Adjust the display to a new resolution */
191void btext_update_display(unsigned long phys, int width, int height,
192 int depth, int pitch)
193{
194 if (dispDeviceBase == 0)
195 return;
196
197 /* check it's the same frame buffer (within 256MB) */
198 if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
199 return;
200
201 dispDeviceBase = (__u8 *) phys;
202 dispDeviceRect[0] = 0;
203 dispDeviceRect[1] = 0;
204 dispDeviceRect[2] = width;
205 dispDeviceRect[3] = height;
206 dispDeviceDepth = depth;
207 dispDeviceRowBytes = pitch;
208 if (boot_text_mapped) {
209 iounmap(logicalDisplayBase);
210 boot_text_mapped = 0;
211 }
212 map_boot_text();
213 g_loc_X = 0;
214 g_loc_Y = 0;
215 g_max_loc_X = width / 8;
216 g_max_loc_Y = height / 16;
217}
218
219void btext_clearscreen(void)
220{
221 unsigned long *base = (unsigned long *)calc_base(0, 0);
222 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
223 (dispDeviceDepth >> 3)) >> 3;
224 int i,j;
225
226 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
227 {
228 unsigned long *ptr = base;
229 for(j=width; j; --j)
230 *(ptr++) = 0;
231 base += (dispDeviceRowBytes >> 3);
232 }
233}
234
235#ifndef NO_SCROLL
236static void scrollscreen(void)
237{
238 unsigned long *src = (unsigned long *)calc_base(0,16);
239 unsigned long *dst = (unsigned long *)calc_base(0,0);
240 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
241 (dispDeviceDepth >> 3)) >> 3;
242 int i,j;
243
244 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
245 {
246 unsigned long *src_ptr = src;
247 unsigned long *dst_ptr = dst;
248 for(j=width; j; --j)
249 *(dst_ptr++) = *(src_ptr++);
250 src += (dispDeviceRowBytes >> 3);
251 dst += (dispDeviceRowBytes >> 3);
252 }
253 for (i=0; i<16; i++)
254 {
255 unsigned long *dst_ptr = dst;
256 for(j=width; j; --j)
257 *(dst_ptr++) = 0;
258 dst += (dispDeviceRowBytes >> 3);
259 }
260}
261#endif /* ndef NO_SCROLL */
262
263void btext_drawchar(char c)
264{
265 int cline = 0;
266#ifdef NO_SCROLL
267 int x;
268#endif
269 if (!boot_text_mapped)
270 return;
271
272 switch (c) {
273 case '\b':
274 if (g_loc_X > 0)
275 --g_loc_X;
276 break;
277 case '\t':
278 g_loc_X = (g_loc_X & -8) + 8;
279 break;
280 case '\r':
281 g_loc_X = 0;
282 break;
283 case '\n':
284 g_loc_X = 0;
285 g_loc_Y++;
286 cline = 1;
287 break;
288 default:
289 draw_byte(c, g_loc_X++, g_loc_Y);
290 }
291 if (g_loc_X >= g_max_loc_X) {
292 g_loc_X = 0;
293 g_loc_Y++;
294 cline = 1;
295 }
296#ifndef NO_SCROLL
297 while (g_loc_Y >= g_max_loc_Y) {
298 scrollscreen();
299 g_loc_Y--;
300 }
301#else
302 /* wrap around from bottom to top of screen so we don't
303 waste time scrolling each line. -- paulus. */
304 if (g_loc_Y >= g_max_loc_Y)
305 g_loc_Y = 0;
306 if (cline) {
307 for (x = 0; x < g_max_loc_X; ++x)
308 draw_byte(' ', x, g_loc_Y);
309 }
310#endif
311}
312
313void btext_drawstring(const char *c)
314{
315 if (!boot_text_mapped)
316 return;
317 while (*c)
318 btext_drawchar(*c++);
319}
320
321void btext_drawhex(unsigned long v)
322{
323 char *hex_table = "0123456789abcdef";
324
325 if (!boot_text_mapped)
326 return;
327 btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
328 btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
329 btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
330 btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
331 btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
332 btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
333 btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
334 btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
335 btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
336 btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
337 btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
338 btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
339 btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
340 btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]);
341 btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]);
342 btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]);
343 btext_drawchar(' ');
344}
345
346static void draw_byte(unsigned char c, long locX, long locY)
347{
348 unsigned char *base = calc_base(locX << 3, locY << 4);
349 unsigned char *font = &vga_font[((unsigned int)c) * 16];
350 int rb = dispDeviceRowBytes;
351
352 switch(dispDeviceDepth) {
353 case 24:
354 case 32:
355 draw_byte_32(font, (unsigned int *)base, rb);
356 break;
357 case 15:
358 case 16:
359 draw_byte_16(font, (unsigned int *)base, rb);
360 break;
361 case 8:
362 draw_byte_8(font, (unsigned int *)base, rb);
363 break;
364 }
365}
366
367static unsigned int expand_bits_8[16] = {
368 0x00000000,
369 0x000000ff,
370 0x0000ff00,
371 0x0000ffff,
372 0x00ff0000,
373 0x00ff00ff,
374 0x00ffff00,
375 0x00ffffff,
376 0xff000000,
377 0xff0000ff,
378 0xff00ff00,
379 0xff00ffff,
380 0xffff0000,
381 0xffff00ff,
382 0xffffff00,
383 0xffffffff
384};
385
386static unsigned int expand_bits_16[4] = {
387 0x00000000,
388 0x0000ffff,
389 0xffff0000,
390 0xffffffff
391};
392
393
394static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
395{
396 int l, bits;
397 int fg = 0xFFFFFFFFUL;
398 int bg = 0x00000000UL;
399
400 for (l = 0; l < 16; ++l)
401 {
402 bits = *font++;
403 base[0] = (-(bits >> 7) & fg) ^ bg;
404 base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
405 base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
406 base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
407 base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
408 base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
409 base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
410 base[7] = (-(bits & 1) & fg) ^ bg;
411 base = (unsigned int *) ((char *)base + rb);
412 }
413}
414
415static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
416{
417 int l, bits;
418 int fg = 0xFFFFFFFFUL;
419 int bg = 0x00000000UL;
420 unsigned int *eb = (int *)expand_bits_16;
421
422 for (l = 0; l < 16; ++l)
423 {
424 bits = *font++;
425 base[0] = (eb[bits >> 6] & fg) ^ bg;
426 base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
427 base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
428 base[3] = (eb[bits & 3] & fg) ^ bg;
429 base = (unsigned int *) ((char *)base + rb);
430 }
431}
432
433static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
434{
435 int l, bits;
436 int fg = 0x0F0F0F0FUL;
437 int bg = 0x00000000UL;
438 unsigned int *eb = (int *)expand_bits_8;
439
440 for (l = 0; l < 16; ++l)
441 {
442 bits = *font++;
443 base[0] = (eb[bits >> 4] & fg) ^ bg;
444 base[1] = (eb[bits & 0xf] & fg) ^ bg;
445 base = (unsigned int *) ((char *)base + rb);
446 }
447}
448
449static unsigned char vga_font[cmapsz] = {
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
4520x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
4530xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
4560x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
4570x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
4600x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
4610xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
4630x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
4640xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
4650x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
4680x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
4690x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
4720xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
4730x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
4760x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
4770xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
4790x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
4810x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
4840x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
4880xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
4920x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
4970x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
4980x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
4990x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
5000x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
5010x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
5040x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
5050x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
5080x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
5160x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5170x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
5200x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
5210xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
5240x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5250xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
5280x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5290x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
5320x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
5330x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
5360xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
5370x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
5400xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
5410x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
5440x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
5450xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
5480x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
5490x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
5520x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
5530xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
5560xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
5570x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
5590x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
5600x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5610xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5620x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
5630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
5640xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
5650xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
5660x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
5670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
5680x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
5690xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
5700x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
5710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
5720x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
5730xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
5740x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
5750x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
5760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
5780x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
5800xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
5810x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
5820x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
5830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
5840xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5850x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5860x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
5870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
5880xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
5890x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
5900x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
5910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
5920x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
5930x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
5940x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
5950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
5960xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5970x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
5980x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
5990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
6000x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
6010x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
6020x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
6030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
6040x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
6050x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
6060x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
6080xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6090x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
6100x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
6110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
6120xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
6130x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
6140x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
6150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
6160x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
6170x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
6180x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
6200xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6210xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
6220x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6230x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
6240xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
6250x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6260x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
6270x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
6280xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
6290x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6300x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
6310x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
6320xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
6330x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6340x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
6350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
6360x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
6370x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6380x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6390x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
6400xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
6410x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
6420x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
6430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
6440x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
6450xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
6460x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
6480xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
6490x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6500x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6510x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
6520xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
6530x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
6540x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6550x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6560xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
6570xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
6580x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
6590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
6600xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
6610x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
6620x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
6630xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
6640xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
6650x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6660x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6670x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
6680xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
6690x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
6700x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
6710x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
6720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
6730x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6740x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
6750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
6760xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6770x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
6780x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
6790x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
6800x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
6810x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
6820x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
6830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
6840x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
6850x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
6860x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
6870x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
6880xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
6890x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
6900x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
6910x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
6920x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
6930x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
6940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
6950x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
6960x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
6970x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
6980x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
6990x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
7000x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7010x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7020x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
7030x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
7040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7050x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7060x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
7070x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
7080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7090x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7100x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7110x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
7120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
7130x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7140x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7150x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
7160x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7170x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7180x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7190x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
7200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7210x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7220x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7230x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
7240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
7250x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7260x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
7270x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
7280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7290x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
7310x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
7320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
7330x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7340x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7350x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
7360x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7370x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7380x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
7390x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
7400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7410x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7430xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
7440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
7450xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
7460x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
7470x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
7480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7490x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
7500x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
7510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
7520xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7530xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
7540x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
7550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
7560xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7570x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
7580x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
7600x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
7610x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
7620x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
7630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
7640x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7650x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7660x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
7670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
7680x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
7690xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
7700x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
7710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
7720x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
7730x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
7740x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
7750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
7760x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7770x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
7780x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
7790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
7800x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
7810x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
7830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7840x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
7850x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
7860x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
7870x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
7880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7890x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
7900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7910x00, 0x00, 0x00, 0x00,
792};
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
deleted file mode 100644
index 1c869ea72d28..000000000000
--- a/arch/ppc64/kernel/head.S
+++ /dev/null
@@ -1,2007 +0,0 @@
1/*
2 * arch/ppc64/kernel/head.S
3 *
4 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
8 * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
9 * Adapted for Power Macintosh by Paul Mackerras.
10 * Low-level exception handlers and MMU support
11 * rewritten by Paul Mackerras.
12 * Copyright (C) 1996 Paul Mackerras.
13 *
14 * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
15 * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
16 *
17 * This file contains the low-level support and setup for the
18 * PowerPC-64 platform, including trap and interrupt dispatch.
19 *
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version
23 * 2 of the License, or (at your option) any later version.
24 */
25
26#include <linux/config.h>
27#include <linux/threads.h>
28#include <asm/processor.h>
29#include <asm/page.h>
30#include <asm/mmu.h>
31#include <asm/ppc_asm.h>
32#include <asm/asm-offsets.h>
33#include <asm/bug.h>
34#include <asm/cputable.h>
35#include <asm/setup.h>
36#include <asm/hvcall.h>
37#include <asm/iseries/lpar_map.h>
38#include <asm/thread_info.h>
39
40#ifdef CONFIG_PPC_ISERIES
41#define DO_SOFT_DISABLE
42#endif
43
44/*
45 * We layout physical memory as follows:
46 * 0x0000 - 0x00ff : Secondary processor spin code
47 * 0x0100 - 0x2fff : pSeries Interrupt prologs
48 * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
49 * 0x6000 - 0x6fff : Initial (CPU0) segment table
50 * 0x7000 - 0x7fff : FWNMI data area
51 * 0x8000 - : Early init and support code
52 */
53
54/*
55 * SPRG Usage
56 *
57 * Register Definition
58 *
59 * SPRG0 reserved for hypervisor
60 * SPRG1 temp - used to save gpr
61 * SPRG2 temp - used to save gpr
62 * SPRG3 virt addr of paca
63 */
64
65/*
66 * Entering into this code we make the following assumptions:
67 * For pSeries:
68 * 1. The MMU is off & open firmware is running in real mode.
69 * 2. The kernel is entered at __start
70 *
71 * For iSeries:
72 * 1. The MMU is on (as it always is for iSeries)
73 * 2. The kernel is entered at system_reset_iSeries
74 */
75
76 .text
77 .globl _stext
78_stext:
79#ifdef CONFIG_PPC_MULTIPLATFORM
80_GLOBAL(__start)
81 /* NOP this out unconditionally */
82BEGIN_FTR_SECTION
83 b .__start_initialization_multiplatform
84END_FTR_SECTION(0, 1)
85#endif /* CONFIG_PPC_MULTIPLATFORM */
86
87 /* Catch branch to 0 in real mode */
88 trap
89
90#ifdef CONFIG_PPC_ISERIES
91 /*
92 * At offset 0x20, there is a pointer to iSeries LPAR data.
93 * This is required by the hypervisor
94 */
95 . = 0x20
96 .llong hvReleaseData-KERNELBASE
97
98 /*
99 * At offset 0x28 and 0x30 are offsets to the mschunks_map
100 * array (used by the iSeries LPAR debugger to do translation
101 * between physical addresses and absolute addresses) and
102 * to the pidhash table (also used by the debugger)
103 */
104 .llong mschunks_map-KERNELBASE
105 .llong 0 /* pidhash-KERNELBASE SFRXXX */
106
107 /* Offset 0x38 - Pointer to start of embedded System.map */
108 .globl embedded_sysmap_start
109embedded_sysmap_start:
110 .llong 0
111 /* Offset 0x40 - Pointer to end of embedded System.map */
112 .globl embedded_sysmap_end
113embedded_sysmap_end:
114 .llong 0
115
116#endif /* CONFIG_PPC_ISERIES */
117
118 /* Secondary processors spin on this value until it goes to 1. */
119 .globl __secondary_hold_spinloop
120__secondary_hold_spinloop:
121 .llong 0x0
122
123 /* Secondary processors write this value with their cpu # */
124 /* after they enter the spin loop immediately below. */
125 .globl __secondary_hold_acknowledge
126__secondary_hold_acknowledge:
127 .llong 0x0
128
129 . = 0x60
130/*
131 * The following code is used on pSeries to hold secondary processors
132 * in a spin loop after they have been freed from OpenFirmware, but
133 * before the bulk of the kernel has been relocated. This code
134 * is relocated to physical address 0x60 before prom_init is run.
135 * All of it must fit below the first exception vector at 0x100.
136 */
137_GLOBAL(__secondary_hold)
138 mfmsr r24
139 ori r24,r24,MSR_RI
140 mtmsrd r24 /* RI on */
141
142 /* Grab our linux cpu number */
143 mr r24,r3
144
145 /* Tell the master cpu we're here */
146 /* Relocation is off & we are located at an address less */
147 /* than 0x100, so only need to grab low order offset. */
148 std r24,__secondary_hold_acknowledge@l(0)
149 sync
150
151 /* All secondary cpus wait here until told to start. */
152100: ld r4,__secondary_hold_spinloop@l(0)
153 cmpdi 0,r4,1
154 bne 100b
155
156#ifdef CONFIG_HMT
157 b .hmt_init
158#else
159#ifdef CONFIG_SMP
160 mr r3,r24
161 b .pSeries_secondary_smp_init
162#else
163 BUG_OPCODE
164#endif
165#endif
166
167/* This value is used to mark exception frames on the stack. */
168 .section ".toc","aw"
169exception_marker:
170 .tc ID_72656773_68657265[TC],0x7265677368657265
171 .text
172
173/*
174 * The following macros define the code that appears as
175 * the prologue to each of the exception handlers. They
176 * are split into two parts to allow a single kernel binary
177 * to be used for pSeries and iSeries.
178 * LOL. One day... - paulus
179 */
180
181/*
182 * We make as much of the exception code common between native
183 * exception handlers (including pSeries LPAR) and iSeries LPAR
184 * implementations as possible.
185 */
186
187/*
188 * This is the start of the interrupt handlers for pSeries
189 * This code runs with relocation off.
190 */
191#define EX_R9 0
192#define EX_R10 8
193#define EX_R11 16
194#define EX_R12 24
195#define EX_R13 32
196#define EX_SRR0 40
197#define EX_DAR 48
198#define EX_DSISR 56
199#define EX_CCR 60
200#define EX_R3 64
201#define EX_LR 72
202
203#define EXCEPTION_PROLOG_PSERIES(area, label) \
204 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
205 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
206 std r10,area+EX_R10(r13); \
207 std r11,area+EX_R11(r13); \
208 std r12,area+EX_R12(r13); \
209 mfspr r9,SPRN_SPRG1; \
210 std r9,area+EX_R13(r13); \
211 mfcr r9; \
212 clrrdi r12,r13,32; /* get high part of &label */ \
213 mfmsr r10; \
214 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
215 ori r12,r12,(label)@l; /* virt addr of handler */ \
216 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
217 mtspr SPRN_SRR0,r12; \
218 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
219 mtspr SPRN_SRR1,r10; \
220 rfid; \
221 b . /* prevent speculative execution */
222
223/*
224 * This is the start of the interrupt handlers for iSeries
225 * This code runs with relocation on.
226 */
227#define EXCEPTION_PROLOG_ISERIES_1(area) \
228 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
229 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
230 std r10,area+EX_R10(r13); \
231 std r11,area+EX_R11(r13); \
232 std r12,area+EX_R12(r13); \
233 mfspr r9,SPRN_SPRG1; \
234 std r9,area+EX_R13(r13); \
235 mfcr r9
236
237#define EXCEPTION_PROLOG_ISERIES_2 \
238 mfmsr r10; \
239 ld r11,PACALPPACA+LPPACASRR0(r13); \
240 ld r12,PACALPPACA+LPPACASRR1(r13); \
241 ori r10,r10,MSR_RI; \
242 mtmsrd r10,1
243
244/*
245 * The common exception prolog is used for all except a few exceptions
246 * such as a segment miss on a kernel address. We have to be prepared
247 * to take another exception from the point where we first touch the
248 * kernel stack onwards.
249 *
250 * On entry r13 points to the paca, r9-r13 are saved in the paca,
251 * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
252 * SRR1, and relocation is on.
253 */
254#define EXCEPTION_PROLOG_COMMON(n, area) \
255 andi. r10,r12,MSR_PR; /* See if coming from user */ \
256 mr r10,r1; /* Save r1 */ \
257 subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
258 beq- 1f; \
259 ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
2601: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
261 bge- cr1,bad_stack; /* abort if it is */ \
262 std r9,_CCR(r1); /* save CR in stackframe */ \
263 std r11,_NIP(r1); /* save SRR0 in stackframe */ \
264 std r12,_MSR(r1); /* save SRR1 in stackframe */ \
265 std r10,0(r1); /* make stack chain pointer */ \
266 std r0,GPR0(r1); /* save r0 in stackframe */ \
267 std r10,GPR1(r1); /* save r1 in stackframe */ \
268 std r2,GPR2(r1); /* save r2 in stackframe */ \
269 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
270 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
271 ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
272 ld r10,area+EX_R10(r13); \
273 std r9,GPR9(r1); \
274 std r10,GPR10(r1); \
275 ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
276 ld r10,area+EX_R12(r13); \
277 ld r11,area+EX_R13(r13); \
278 std r9,GPR11(r1); \
279 std r10,GPR12(r1); \
280 std r11,GPR13(r1); \
281 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
282 mflr r9; /* save LR in stackframe */ \
283 std r9,_LINK(r1); \
284 mfctr r10; /* save CTR in stackframe */ \
285 std r10,_CTR(r1); \
286 mfspr r11,SPRN_XER; /* save XER in stackframe */ \
287 std r11,_XER(r1); \
288 li r9,(n)+1; \
289 std r9,_TRAP(r1); /* set trap number */ \
290 li r10,0; \
291 ld r11,exception_marker@toc(r2); \
292 std r10,RESULT(r1); /* clear regs->result */ \
293 std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
294
295/*
296 * Exception vectors.
297 */
298#define STD_EXCEPTION_PSERIES(n, label) \
299 . = n; \
300 .globl label##_pSeries; \
301label##_pSeries: \
302 HMT_MEDIUM; \
303 mtspr SPRN_SPRG1,r13; /* save r13 */ \
304 RUNLATCH_ON(r13); \
305 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
306
307#define STD_EXCEPTION_ISERIES(n, label, area) \
308 .globl label##_iSeries; \
309label##_iSeries: \
310 HMT_MEDIUM; \
311 mtspr SPRN_SPRG1,r13; /* save r13 */ \
312 RUNLATCH_ON(r13); \
313 EXCEPTION_PROLOG_ISERIES_1(area); \
314 EXCEPTION_PROLOG_ISERIES_2; \
315 b label##_common
316
317#define MASKABLE_EXCEPTION_ISERIES(n, label) \
318 .globl label##_iSeries; \
319label##_iSeries: \
320 HMT_MEDIUM; \
321 mtspr SPRN_SPRG1,r13; /* save r13 */ \
322 RUNLATCH_ON(r13); \
323 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
324 lbz r10,PACAPROCENABLED(r13); \
325 cmpwi 0,r10,0; \
326 beq- label##_iSeries_masked; \
327 EXCEPTION_PROLOG_ISERIES_2; \
328 b label##_common; \
329
330#ifdef DO_SOFT_DISABLE
331#define DISABLE_INTS \
332 lbz r10,PACAPROCENABLED(r13); \
333 li r11,0; \
334 std r10,SOFTE(r1); \
335 mfmsr r10; \
336 stb r11,PACAPROCENABLED(r13); \
337 ori r10,r10,MSR_EE; \
338 mtmsrd r10,1
339
340#define ENABLE_INTS \
341 lbz r10,PACAPROCENABLED(r13); \
342 mfmsr r11; \
343 std r10,SOFTE(r1); \
344 ori r11,r11,MSR_EE; \
345 mtmsrd r11,1
346
347#else /* hard enable/disable interrupts */
348#define DISABLE_INTS
349
350#define ENABLE_INTS \
351 ld r12,_MSR(r1); \
352 mfmsr r11; \
353 rlwimi r11,r12,0,MSR_EE; \
354 mtmsrd r11,1
355
356#endif
357
358#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
359 .align 7; \
360 .globl label##_common; \
361label##_common: \
362 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
363 DISABLE_INTS; \
364 bl .save_nvgprs; \
365 addi r3,r1,STACK_FRAME_OVERHEAD; \
366 bl hdlr; \
367 b .ret_from_except
368
369#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
370 .align 7; \
371 .globl label##_common; \
372label##_common: \
373 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
374 DISABLE_INTS; \
375 addi r3,r1,STACK_FRAME_OVERHEAD; \
376 bl hdlr; \
377 b .ret_from_except_lite
378
379/*
380 * Start of pSeries system interrupt routines
381 */
382 . = 0x100
383 .globl __start_interrupts
384__start_interrupts:
385
386 STD_EXCEPTION_PSERIES(0x100, system_reset)
387
388 . = 0x200
389_machine_check_pSeries:
390 HMT_MEDIUM
391 mtspr SPRN_SPRG1,r13 /* save r13 */
392 RUNLATCH_ON(r13)
393 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
394
395 . = 0x300
396 .globl data_access_pSeries
397data_access_pSeries:
398 HMT_MEDIUM
399 mtspr SPRN_SPRG1,r13
400BEGIN_FTR_SECTION
401 mtspr SPRN_SPRG2,r12
402 mfspr r13,SPRN_DAR
403 mfspr r12,SPRN_DSISR
404 srdi r13,r13,60
405 rlwimi r13,r12,16,0x20
406 mfcr r12
407 cmpwi r13,0x2c
408 beq .do_stab_bolted_pSeries
409 mtcrf 0x80,r12
410 mfspr r12,SPRN_SPRG2
411END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
412 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
413
414 . = 0x380
415 .globl data_access_slb_pSeries
416data_access_slb_pSeries:
417 HMT_MEDIUM
418 mtspr SPRN_SPRG1,r13
419 RUNLATCH_ON(r13)
420 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
421 std r3,PACA_EXSLB+EX_R3(r13)
422 mfspr r3,SPRN_DAR
423 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
424 mfcr r9
425#ifdef __DISABLED__
426 /* Keep that around for when we re-implement dynamic VSIDs */
427 cmpdi r3,0
428 bge slb_miss_user_pseries
429#endif /* __DISABLED__ */
430 std r10,PACA_EXSLB+EX_R10(r13)
431 std r11,PACA_EXSLB+EX_R11(r13)
432 std r12,PACA_EXSLB+EX_R12(r13)
433 mfspr r10,SPRN_SPRG1
434 std r10,PACA_EXSLB+EX_R13(r13)
435 mfspr r12,SPRN_SRR1 /* and SRR1 */
436 b .slb_miss_realmode /* Rel. branch works in real mode */
437
438 STD_EXCEPTION_PSERIES(0x400, instruction_access)
439
440 . = 0x480
441 .globl instruction_access_slb_pSeries
442instruction_access_slb_pSeries:
443 HMT_MEDIUM
444 mtspr SPRN_SPRG1,r13
445 RUNLATCH_ON(r13)
446 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
447 std r3,PACA_EXSLB+EX_R3(r13)
448 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
449 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
450 mfcr r9
451#ifdef __DISABLED__
452 /* Keep that around for when we re-implement dynamic VSIDs */
453 cmpdi r3,0
454 bge slb_miss_user_pseries
455#endif /* __DISABLED__ */
456 std r10,PACA_EXSLB+EX_R10(r13)
457 std r11,PACA_EXSLB+EX_R11(r13)
458 std r12,PACA_EXSLB+EX_R12(r13)
459 mfspr r10,SPRN_SPRG1
460 std r10,PACA_EXSLB+EX_R13(r13)
461 mfspr r12,SPRN_SRR1 /* and SRR1 */
462 b .slb_miss_realmode /* Rel. branch works in real mode */
463
464 STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
465 STD_EXCEPTION_PSERIES(0x600, alignment)
466 STD_EXCEPTION_PSERIES(0x700, program_check)
467 STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
468 STD_EXCEPTION_PSERIES(0x900, decrementer)
469 STD_EXCEPTION_PSERIES(0xa00, trap_0a)
470 STD_EXCEPTION_PSERIES(0xb00, trap_0b)
471
472 . = 0xc00
473 .globl system_call_pSeries
474system_call_pSeries:
475 HMT_MEDIUM
476 RUNLATCH_ON(r9)
477 mr r9,r13
478 mfmsr r10
479 mfspr r13,SPRN_SPRG3
480 mfspr r11,SPRN_SRR0
481 clrrdi r12,r13,32
482 oris r12,r12,system_call_common@h
483 ori r12,r12,system_call_common@l
484 mtspr SPRN_SRR0,r12
485 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
486 mfspr r12,SPRN_SRR1
487 mtspr SPRN_SRR1,r10
488 rfid
489 b . /* prevent speculative execution */
490
491 STD_EXCEPTION_PSERIES(0xd00, single_step)
492 STD_EXCEPTION_PSERIES(0xe00, trap_0e)
493
494 /* We need to deal with the Altivec unavailable exception
495 * here which is at 0xf20, thus in the middle of the
496 * prolog code of the PerformanceMonitor one. A little
497 * trickery is thus necessary
498 */
499 . = 0xf00
500 b performance_monitor_pSeries
501
502 STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
503
504 STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
505 STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
506
507 . = 0x3000
508
509/*** pSeries interrupt support ***/
510
511 /* moved from 0xf00 */
512 STD_EXCEPTION_PSERIES(., performance_monitor)
513
514 .align 7
515_GLOBAL(do_stab_bolted_pSeries)
516 mtcrf 0x80,r12
517 mfspr r12,SPRN_SPRG2
518 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
519
520/*
521 * We have some room here we use that to put
522 * the peries slb miss user trampoline code so it's reasonably
523 * away from slb_miss_user_common to avoid problems with rfid
524 *
525 * This is used for when the SLB miss handler has to go virtual,
526 * which doesn't happen for now anymore but will once we re-implement
527 * dynamic VSIDs for shared page tables
528 */
529#ifdef __DISABLED__
530slb_miss_user_pseries:
531 std r10,PACA_EXGEN+EX_R10(r13)
532 std r11,PACA_EXGEN+EX_R11(r13)
533 std r12,PACA_EXGEN+EX_R12(r13)
534 mfspr r10,SPRG1
535 ld r11,PACA_EXSLB+EX_R9(r13)
536 ld r12,PACA_EXSLB+EX_R3(r13)
537 std r10,PACA_EXGEN+EX_R13(r13)
538 std r11,PACA_EXGEN+EX_R9(r13)
539 std r12,PACA_EXGEN+EX_R3(r13)
540 clrrdi r12,r13,32
541 mfmsr r10
542 mfspr r11,SRR0 /* save SRR0 */
543 ori r12,r12,slb_miss_user_common@l /* virt addr of handler */
544 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
545 mtspr SRR0,r12
546 mfspr r12,SRR1 /* and SRR1 */
547 mtspr SRR1,r10
548 rfid
549 b . /* prevent spec. execution */
550#endif /* __DISABLED__ */
551
552/*
553 * Vectors for the FWNMI option. Share common code.
554 */
555 .globl system_reset_fwnmi
556system_reset_fwnmi:
557 HMT_MEDIUM
558 mtspr SPRN_SPRG1,r13 /* save r13 */
559 RUNLATCH_ON(r13)
560 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
561
562 .globl machine_check_fwnmi
563machine_check_fwnmi:
564 HMT_MEDIUM
565 mtspr SPRN_SPRG1,r13 /* save r13 */
566 RUNLATCH_ON(r13)
567 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
568
569#ifdef CONFIG_PPC_ISERIES
570/*** ISeries-LPAR interrupt handlers ***/
571
572 STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
573
574 .globl data_access_iSeries
575data_access_iSeries:
576 mtspr SPRN_SPRG1,r13
577BEGIN_FTR_SECTION
578 mtspr SPRN_SPRG2,r12
579 mfspr r13,SPRN_DAR
580 mfspr r12,SPRN_DSISR
581 srdi r13,r13,60
582 rlwimi r13,r12,16,0x20
583 mfcr r12
584 cmpwi r13,0x2c
585 beq .do_stab_bolted_iSeries
586 mtcrf 0x80,r12
587 mfspr r12,SPRN_SPRG2
588END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
589 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
590 EXCEPTION_PROLOG_ISERIES_2
591 b data_access_common
592
593.do_stab_bolted_iSeries:
594 mtcrf 0x80,r12
595 mfspr r12,SPRN_SPRG2
596 EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
597 EXCEPTION_PROLOG_ISERIES_2
598 b .do_stab_bolted
599
600 .globl data_access_slb_iSeries
601data_access_slb_iSeries:
602 mtspr SPRN_SPRG1,r13 /* save r13 */
603 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
604 std r3,PACA_EXSLB+EX_R3(r13)
605 mfspr r3,SPRN_DAR
606 std r9,PACA_EXSLB+EX_R9(r13)
607 mfcr r9
608#ifdef __DISABLED__
609 cmpdi r3,0
610 bge slb_miss_user_iseries
611#endif
612 std r10,PACA_EXSLB+EX_R10(r13)
613 std r11,PACA_EXSLB+EX_R11(r13)
614 std r12,PACA_EXSLB+EX_R12(r13)
615 mfspr r10,SPRN_SPRG1
616 std r10,PACA_EXSLB+EX_R13(r13)
617 ld r12,PACALPPACA+LPPACASRR1(r13);
618 b .slb_miss_realmode
619
620 STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
621
622 .globl instruction_access_slb_iSeries
623instruction_access_slb_iSeries:
624 mtspr SPRN_SPRG1,r13 /* save r13 */
625 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
626 std r3,PACA_EXSLB+EX_R3(r13)
627 ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
628 std r9,PACA_EXSLB+EX_R9(r13)
629 mfcr r9
630#ifdef __DISABLED__
631 cmpdi r3,0
632 bge .slb_miss_user_iseries
633#endif
634 std r10,PACA_EXSLB+EX_R10(r13)
635 std r11,PACA_EXSLB+EX_R11(r13)
636 std r12,PACA_EXSLB+EX_R12(r13)
637 mfspr r10,SPRN_SPRG1
638 std r10,PACA_EXSLB+EX_R13(r13)
639 ld r12,PACALPPACA+LPPACASRR1(r13);
640 b .slb_miss_realmode
641
642#ifdef __DISABLED__
643slb_miss_user_iseries:
644 std r10,PACA_EXGEN+EX_R10(r13)
645 std r11,PACA_EXGEN+EX_R11(r13)
646 std r12,PACA_EXGEN+EX_R12(r13)
647 mfspr r10,SPRG1
648 ld r11,PACA_EXSLB+EX_R9(r13)
649 ld r12,PACA_EXSLB+EX_R3(r13)
650 std r10,PACA_EXGEN+EX_R13(r13)
651 std r11,PACA_EXGEN+EX_R9(r13)
652 std r12,PACA_EXGEN+EX_R3(r13)
653 EXCEPTION_PROLOG_ISERIES_2
654 b slb_miss_user_common
655#endif
656
657 MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
658 STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
659 STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
660 STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
661 MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
662 STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
663 STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
664
665 .globl system_call_iSeries
666system_call_iSeries:
667 mr r9,r13
668 mfspr r13,SPRN_SPRG3
669 EXCEPTION_PROLOG_ISERIES_2
670 b system_call_common
671
672 STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
673 STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
674 STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
675
676 .globl system_reset_iSeries
677system_reset_iSeries:
678 mfspr r13,SPRN_SPRG3 /* Get paca address */
679 mfmsr r24
680 ori r24,r24,MSR_RI
681 mtmsrd r24 /* RI on */
682 lhz r24,PACAPACAINDEX(r13) /* Get processor # */
683 cmpwi 0,r24,0 /* Are we processor 0? */
684 beq .__start_initialization_iSeries /* Start up the first processor */
685 mfspr r4,SPRN_CTRLF
686 li r5,CTRL_RUNLATCH /* Turn off the run light */
687 andc r4,r4,r5
688 mtspr SPRN_CTRLT,r4
689
6901:
691 HMT_LOW
692#ifdef CONFIG_SMP
693 lbz r23,PACAPROCSTART(r13) /* Test if this processor
694 * should start */
695 sync
696 LOADADDR(r3,current_set)
697 sldi r28,r24,3 /* get current_set[cpu#] */
698 ldx r3,r3,r28
699 addi r1,r3,THREAD_SIZE
700 subi r1,r1,STACK_FRAME_OVERHEAD
701
702 cmpwi 0,r23,0
703 beq iSeries_secondary_smp_loop /* Loop until told to go */
704 bne .__secondary_start /* Loop until told to go */
705iSeries_secondary_smp_loop:
706 /* Let the Hypervisor know we are alive */
707 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
708 lis r3,0x8002
709 rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
710#else /* CONFIG_SMP */
711 /* Yield the processor. This is required for non-SMP kernels
712 which are running on multi-threaded machines. */
713 lis r3,0x8000
714 rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
715 addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
716 li r4,0 /* "yield timed" */
717 li r5,-1 /* "yield forever" */
718#endif /* CONFIG_SMP */
719 li r0,-1 /* r0=-1 indicates a Hypervisor call */
720 sc /* Invoke the hypervisor via a system call */
721 mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
722 b 1b /* If SMP not configured, secondaries
723 * loop forever */
724
725 .globl decrementer_iSeries_masked
726decrementer_iSeries_masked:
727 li r11,1
728 stb r11,PACALPPACA+LPPACADECRINT(r13)
729 lwz r12,PACADEFAULTDECR(r13)
730 mtspr SPRN_DEC,r12
731 /* fall through */
732
733 .globl hardware_interrupt_iSeries_masked
734hardware_interrupt_iSeries_masked:
735 mtcrf 0x80,r9 /* Restore regs */
736 ld r11,PACALPPACA+LPPACASRR0(r13)
737 ld r12,PACALPPACA+LPPACASRR1(r13)
738 mtspr SPRN_SRR0,r11
739 mtspr SPRN_SRR1,r12
740 ld r9,PACA_EXGEN+EX_R9(r13)
741 ld r10,PACA_EXGEN+EX_R10(r13)
742 ld r11,PACA_EXGEN+EX_R11(r13)
743 ld r12,PACA_EXGEN+EX_R12(r13)
744 ld r13,PACA_EXGEN+EX_R13(r13)
745 rfid
746 b . /* prevent speculative execution */
747#endif /* CONFIG_PPC_ISERIES */
748
749/*** Common interrupt handlers ***/
750
751 STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
752
753 /*
754 * Machine check is different because we use a different
755 * save area: PACA_EXMC instead of PACA_EXGEN.
756 */
757 .align 7
758 .globl machine_check_common
759machine_check_common:
760 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
761 DISABLE_INTS
762 bl .save_nvgprs
763 addi r3,r1,STACK_FRAME_OVERHEAD
764 bl .machine_check_exception
765 b .ret_from_except
766
767 STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
768 STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
769 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
770 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
771 STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
772 STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
773 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
774#ifdef CONFIG_ALTIVEC
775 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
776#else
777 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
778#endif
779
780/*
781 * Here we have detected that the kernel stack pointer is bad.
782 * R9 contains the saved CR, r13 points to the paca,
783 * r10 contains the (bad) kernel stack pointer,
784 * r11 and r12 contain the saved SRR0 and SRR1.
785 * We switch to using an emergency stack, save the registers there,
786 * and call kernel_bad_stack(), which panics.
787 */
788bad_stack:
789 ld r1,PACAEMERGSP(r13)
790 subi r1,r1,64+INT_FRAME_SIZE
791 std r9,_CCR(r1)
792 std r10,GPR1(r1)
793 std r11,_NIP(r1)
794 std r12,_MSR(r1)
795 mfspr r11,SPRN_DAR
796 mfspr r12,SPRN_DSISR
797 std r11,_DAR(r1)
798 std r12,_DSISR(r1)
799 mflr r10
800 mfctr r11
801 mfxer r12
802 std r10,_LINK(r1)
803 std r11,_CTR(r1)
804 std r12,_XER(r1)
805 SAVE_GPR(0,r1)
806 SAVE_GPR(2,r1)
807 SAVE_4GPRS(3,r1)
808 SAVE_2GPRS(7,r1)
809 SAVE_10GPRS(12,r1)
810 SAVE_10GPRS(22,r1)
811 addi r11,r1,INT_FRAME_SIZE
812 std r11,0(r1)
813 li r12,0
814 std r12,0(r11)
815 ld r2,PACATOC(r13)
8161: addi r3,r1,STACK_FRAME_OVERHEAD
817 bl .kernel_bad_stack
818 b 1b
819
820/*
821 * Return from an exception with minimal checks.
822 * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
823 * If interrupts have been enabled, or anything has been
824 * done that might have changed the scheduling status of
825 * any task or sent any task a signal, you should use
826 * ret_from_except or ret_from_except_lite instead of this.
827 */
828 .globl fast_exception_return
829fast_exception_return:
830 ld r12,_MSR(r1)
831 ld r11,_NIP(r1)
832 andi. r3,r12,MSR_RI /* check if RI is set */
833 beq- unrecov_fer
834 ld r3,_CCR(r1)
835 ld r4,_LINK(r1)
836 ld r5,_CTR(r1)
837 ld r6,_XER(r1)
838 mtcr r3
839 mtlr r4
840 mtctr r5
841 mtxer r6
842 REST_GPR(0, r1)
843 REST_8GPRS(2, r1)
844
845 mfmsr r10
846 clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
847 mtmsrd r10,1
848
849 mtspr SPRN_SRR1,r12
850 mtspr SPRN_SRR0,r11
851 REST_4GPRS(10, r1)
852 ld r1,GPR1(r1)
853 rfid
854 b . /* prevent speculative execution */
855
856unrecov_fer:
857 bl .save_nvgprs
8581: addi r3,r1,STACK_FRAME_OVERHEAD
859 bl .unrecoverable_exception
860 b 1b
861
862/*
863 * Here r13 points to the paca, r9 contains the saved CR,
864 * SRR0 and SRR1 are saved in r11 and r12,
865 * r9 - r13 are saved in paca->exgen.
866 */
867 .align 7
868 .globl data_access_common
869data_access_common:
870 RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
871 mfspr r10,SPRN_DAR
872 std r10,PACA_EXGEN+EX_DAR(r13)
873 mfspr r10,SPRN_DSISR
874 stw r10,PACA_EXGEN+EX_DSISR(r13)
875 EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
876 ld r3,PACA_EXGEN+EX_DAR(r13)
877 lwz r4,PACA_EXGEN+EX_DSISR(r13)
878 li r5,0x300
879 b .do_hash_page /* Try to handle as hpte fault */
880
881 .align 7
882 .globl instruction_access_common
883instruction_access_common:
884 EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
885 ld r3,_NIP(r1)
886 andis. r4,r12,0x5820
887 li r5,0x400
888 b .do_hash_page /* Try to handle as hpte fault */
889
890/*
891 * Here is the common SLB miss user that is used when going to virtual
892 * mode for SLB misses, that is currently not used
893 */
894#ifdef __DISABLED__
895 .align 7
896 .globl slb_miss_user_common
897slb_miss_user_common:
898 mflr r10
899 std r3,PACA_EXGEN+EX_DAR(r13)
900 stw r9,PACA_EXGEN+EX_CCR(r13)
901 std r10,PACA_EXGEN+EX_LR(r13)
902 std r11,PACA_EXGEN+EX_SRR0(r13)
903 bl .slb_allocate_user
904
905 ld r10,PACA_EXGEN+EX_LR(r13)
906 ld r3,PACA_EXGEN+EX_R3(r13)
907 lwz r9,PACA_EXGEN+EX_CCR(r13)
908 ld r11,PACA_EXGEN+EX_SRR0(r13)
909 mtlr r10
910 beq- slb_miss_fault
911
912 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
913 beq- unrecov_user_slb
914 mfmsr r10
915
916.machine push
917.machine "power4"
918 mtcrf 0x80,r9
919.machine pop
920
921 clrrdi r10,r10,2 /* clear RI before setting SRR0/1 */
922 mtmsrd r10,1
923
924 mtspr SRR0,r11
925 mtspr SRR1,r12
926
927 ld r9,PACA_EXGEN+EX_R9(r13)
928 ld r10,PACA_EXGEN+EX_R10(r13)
929 ld r11,PACA_EXGEN+EX_R11(r13)
930 ld r12,PACA_EXGEN+EX_R12(r13)
931 ld r13,PACA_EXGEN+EX_R13(r13)
932 rfid
933 b .
934
935slb_miss_fault:
936 EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
937 ld r4,PACA_EXGEN+EX_DAR(r13)
938 li r5,0
939 std r4,_DAR(r1)
940 std r5,_DSISR(r1)
941 b .handle_page_fault
942
943unrecov_user_slb:
944 EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
945 DISABLE_INTS
946 bl .save_nvgprs
9471: addi r3,r1,STACK_FRAME_OVERHEAD
948 bl .unrecoverable_exception
949 b 1b
950
951#endif /* __DISABLED__ */
952
953
954/*
955 * r13 points to the PACA, r9 contains the saved CR,
956 * r12 contain the saved SRR1, SRR0 is still ready for return
957 * r3 has the faulting address
958 * r9 - r13 are saved in paca->exslb.
959 * r3 is saved in paca->slb_r3
960 * We assume we aren't going to take any exceptions during this procedure.
961 */
962_GLOBAL(slb_miss_realmode)
963 mflr r10
964
965 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
966 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
967
968 bl .slb_allocate_realmode
969
970 /* All done -- return from exception. */
971
972 ld r10,PACA_EXSLB+EX_LR(r13)
973 ld r3,PACA_EXSLB+EX_R3(r13)
974 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
975#ifdef CONFIG_PPC_ISERIES
976 ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
977#endif /* CONFIG_PPC_ISERIES */
978
979 mtlr r10
980
981 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
982 beq- unrecov_slb
983
984.machine push
985.machine "power4"
986 mtcrf 0x80,r9
987 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
988.machine pop
989
990#ifdef CONFIG_PPC_ISERIES
991 mtspr SPRN_SRR0,r11
992 mtspr SPRN_SRR1,r12
993#endif /* CONFIG_PPC_ISERIES */
994 ld r9,PACA_EXSLB+EX_R9(r13)
995 ld r10,PACA_EXSLB+EX_R10(r13)
996 ld r11,PACA_EXSLB+EX_R11(r13)
997 ld r12,PACA_EXSLB+EX_R12(r13)
998 ld r13,PACA_EXSLB+EX_R13(r13)
999 rfid
1000 b . /* prevent speculative execution */
1001
1002unrecov_slb:
1003 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1004 DISABLE_INTS
1005 bl .save_nvgprs
10061: addi r3,r1,STACK_FRAME_OVERHEAD
1007 bl .unrecoverable_exception
1008 b 1b
1009
1010 .align 7
1011 .globl hardware_interrupt_common
1012 .globl hardware_interrupt_entry
1013hardware_interrupt_common:
1014 EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
1015hardware_interrupt_entry:
1016 DISABLE_INTS
1017 addi r3,r1,STACK_FRAME_OVERHEAD
1018 bl .do_IRQ
1019 b .ret_from_except_lite
1020
1021 .align 7
1022 .globl alignment_common
1023alignment_common:
1024 mfspr r10,SPRN_DAR
1025 std r10,PACA_EXGEN+EX_DAR(r13)
1026 mfspr r10,SPRN_DSISR
1027 stw r10,PACA_EXGEN+EX_DSISR(r13)
1028 EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
1029 ld r3,PACA_EXGEN+EX_DAR(r13)
1030 lwz r4,PACA_EXGEN+EX_DSISR(r13)
1031 std r3,_DAR(r1)
1032 std r4,_DSISR(r1)
1033 bl .save_nvgprs
1034 addi r3,r1,STACK_FRAME_OVERHEAD
1035 ENABLE_INTS
1036 bl .alignment_exception
1037 b .ret_from_except
1038
1039 .align 7
1040 .globl program_check_common
1041program_check_common:
1042 EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
1043 bl .save_nvgprs
1044 addi r3,r1,STACK_FRAME_OVERHEAD
1045 ENABLE_INTS
1046 bl .program_check_exception
1047 b .ret_from_except
1048
1049 .align 7
1050 .globl fp_unavailable_common
1051fp_unavailable_common:
1052 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
1053 bne .load_up_fpu /* if from user, just load it up */
1054 bl .save_nvgprs
1055 addi r3,r1,STACK_FRAME_OVERHEAD
1056 ENABLE_INTS
1057 bl .kernel_fp_unavailable_exception
1058 BUG_OPCODE
1059
1060 .align 7
1061 .globl altivec_unavailable_common
1062altivec_unavailable_common:
1063 EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
1064#ifdef CONFIG_ALTIVEC
1065BEGIN_FTR_SECTION
1066 bne .load_up_altivec /* if from user, just load it up */
1067END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1068#endif
1069 bl .save_nvgprs
1070 addi r3,r1,STACK_FRAME_OVERHEAD
1071 ENABLE_INTS
1072 bl .altivec_unavailable_exception
1073 b .ret_from_except
1074
1075#ifdef CONFIG_ALTIVEC
1076/*
1077 * load_up_altivec(unused, unused, tsk)
1078 * Disable VMX for the task which had it previously,
1079 * and save its vector registers in its thread_struct.
1080 * Enables the VMX for use in the kernel on return.
1081 * On SMP we know the VMX is free, since we give it up every
1082 * switch (ie, no lazy save of the vector registers).
1083 * On entry: r13 == 'current' && last_task_used_altivec != 'current'
1084 */
1085_STATIC(load_up_altivec)
1086 mfmsr r5 /* grab the current MSR */
1087 oris r5,r5,MSR_VEC@h
1088 mtmsrd r5 /* enable use of VMX now */
1089 isync
1090
1091/*
1092 * For SMP, we don't do lazy VMX switching because it just gets too
1093 * horrendously complex, especially when a task switches from one CPU
1094 * to another. Instead we call giveup_altvec in switch_to.
1095 * VRSAVE isn't dealt with here, that is done in the normal context
1096 * switch code. Note that we could rely on vrsave value to eventually
1097 * avoid saving all of the VREGs here...
1098 */
1099#ifndef CONFIG_SMP
1100 ld r3,last_task_used_altivec@got(r2)
1101 ld r4,0(r3)
1102 cmpdi 0,r4,0
1103 beq 1f
1104 /* Save VMX state to last_task_used_altivec's THREAD struct */
1105 addi r4,r4,THREAD
1106 SAVE_32VRS(0,r5,r4)
1107 mfvscr vr0
1108 li r10,THREAD_VSCR
1109 stvx vr0,r10,r4
1110 /* Disable VMX for last_task_used_altivec */
1111 ld r5,PT_REGS(r4)
1112 ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1113 lis r6,MSR_VEC@h
1114 andc r4,r4,r6
1115 std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
11161:
1117#endif /* CONFIG_SMP */
1118 /* Hack: if we get an altivec unavailable trap with VRSAVE
1119 * set to all zeros, we assume this is a broken application
1120 * that fails to set it properly, and thus we switch it to
1121 * all 1's
1122 */
1123 mfspr r4,SPRN_VRSAVE
1124 cmpdi 0,r4,0
1125 bne+ 1f
1126 li r4,-1
1127 mtspr SPRN_VRSAVE,r4
11281:
1129 /* enable use of VMX after return */
1130 ld r4,PACACURRENT(r13)
1131 addi r5,r4,THREAD /* Get THREAD */
1132 oris r12,r12,MSR_VEC@h
1133 std r12,_MSR(r1)
1134 li r4,1
1135 li r10,THREAD_VSCR
1136 stw r4,THREAD_USED_VR(r5)
1137 lvx vr0,r10,r5
1138 mtvscr vr0
1139 REST_32VRS(0,r4,r5)
1140#ifndef CONFIG_SMP
1141 /* Update last_task_used_math to 'current' */
1142 subi r4,r5,THREAD /* Back to 'current' */
1143 std r4,0(r3)
1144#endif /* CONFIG_SMP */
1145 /* restore registers and return */
1146 b fast_exception_return
1147#endif /* CONFIG_ALTIVEC */
1148
1149/*
1150 * Hash table stuff
1151 */
1152 .align 7
1153_GLOBAL(do_hash_page)
1154 std r3,_DAR(r1)
1155 std r4,_DSISR(r1)
1156
1157 andis. r0,r4,0xa450 /* weird error? */
1158 bne- .handle_page_fault /* if not, try to insert a HPTE */
1159BEGIN_FTR_SECTION
1160 andis. r0,r4,0x0020 /* Is it a segment table fault? */
1161 bne- .do_ste_alloc /* If so handle it */
1162END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1163
1164 /*
1165 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
1166 * accessing a userspace segment (even from the kernel). We assume
1167 * kernel addresses always have the high bit set.
1168 */
1169 rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
1170 rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
1171 orc r0,r12,r0 /* MSR_PR | ~high_bit */
1172 rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
1173 ori r4,r4,1 /* add _PAGE_PRESENT */
1174 rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
1175
1176 /*
1177 * On iSeries, we soft-disable interrupts here, then
1178 * hard-enable interrupts so that the hash_page code can spin on
1179 * the hash_table_lock without problems on a shared processor.
1180 */
1181 DISABLE_INTS
1182
1183 /*
1184 * r3 contains the faulting address
1185 * r4 contains the required access permissions
1186 * r5 contains the trap number
1187 *
1188 * at return r3 = 0 for success
1189 */
1190 bl .hash_page /* build HPTE if possible */
1191 cmpdi r3,0 /* see if hash_page succeeded */
1192
1193#ifdef DO_SOFT_DISABLE
1194 /*
1195 * If we had interrupts soft-enabled at the point where the
1196 * DSI/ISI occurred, and an interrupt came in during hash_page,
1197 * handle it now.
1198 * We jump to ret_from_except_lite rather than fast_exception_return
1199 * because ret_from_except_lite will check for and handle pending
1200 * interrupts if necessary.
1201 */
1202 beq .ret_from_except_lite
1203 /* For a hash failure, we don't bother re-enabling interrupts */
1204 ble- 12f
1205
1206 /*
1207 * hash_page couldn't handle it, set soft interrupt enable back
1208 * to what it was before the trap. Note that .local_irq_restore
1209 * handles any interrupts pending at this point.
1210 */
1211 ld r3,SOFTE(r1)
1212 bl .local_irq_restore
1213 b 11f
1214#else
1215 beq fast_exception_return /* Return from exception on success */
1216 ble- 12f /* Failure return from hash_page */
1217
1218 /* fall through */
1219#endif
1220
1221/* Here we have a page fault that hash_page can't handle. */
1222_GLOBAL(handle_page_fault)
1223 ENABLE_INTS
122411: ld r4,_DAR(r1)
1225 ld r5,_DSISR(r1)
1226 addi r3,r1,STACK_FRAME_OVERHEAD
1227 bl .do_page_fault
1228 cmpdi r3,0
1229 beq+ .ret_from_except_lite
1230 bl .save_nvgprs
1231 mr r5,r3
1232 addi r3,r1,STACK_FRAME_OVERHEAD
1233 lwz r4,_DAR(r1)
1234 bl .bad_page_fault
1235 b .ret_from_except
1236
1237/* We have a page fault that hash_page could handle but HV refused
1238 * the PTE insertion
1239 */
124012: bl .save_nvgprs
1241 addi r3,r1,STACK_FRAME_OVERHEAD
1242 lwz r4,_DAR(r1)
1243 bl .low_hash_fault
1244 b .ret_from_except
1245
1246 /* here we have a segment miss */
1247_GLOBAL(do_ste_alloc)
1248 bl .ste_allocate /* try to insert stab entry */
1249 cmpdi r3,0
1250 beq+ fast_exception_return
1251 b .handle_page_fault
1252
1253/*
1254 * r13 points to the PACA, r9 contains the saved CR,
1255 * r11 and r12 contain the saved SRR0 and SRR1.
1256 * r9 - r13 are saved in paca->exslb.
1257 * We assume we aren't going to take any exceptions during this procedure.
1258 * We assume (DAR >> 60) == 0xc.
1259 */
1260 .align 7
1261_GLOBAL(do_stab_bolted)
1262 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
1263 std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
1264
1265 /* Hash to the primary group */
1266 ld r10,PACASTABVIRT(r13)
1267 mfspr r11,SPRN_DAR
1268 srdi r11,r11,28
1269 rldimi r10,r11,7,52 /* r10 = first ste of the group */
1270
1271 /* Calculate VSID */
1272 /* This is a kernel address, so protovsid = ESID */
1273 ASM_VSID_SCRAMBLE(r11, r9)
1274 rldic r9,r11,12,16 /* r9 = vsid << 12 */
1275
1276 /* Search the primary group for a free entry */
12771: ld r11,0(r10) /* Test valid bit of the current ste */
1278 andi. r11,r11,0x80
1279 beq 2f
1280 addi r10,r10,16
1281 andi. r11,r10,0x70
1282 bne 1b
1283
1284 /* Stick for only searching the primary group for now. */
1285 /* At least for now, we use a very simple random castout scheme */
1286 /* Use the TB as a random number ; OR in 1 to avoid entry 0 */
1287 mftb r11
1288 rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
1289 ori r11,r11,0x10
1290
1291 /* r10 currently points to an ste one past the group of interest */
1292 /* make it point to the randomly selected entry */
1293 subi r10,r10,128
1294 or r10,r10,r11 /* r10 is the entry to invalidate */
1295
1296 isync /* mark the entry invalid */
1297 ld r11,0(r10)
1298 rldicl r11,r11,56,1 /* clear the valid bit */
1299 rotldi r11,r11,8
1300 std r11,0(r10)
1301 sync
1302
1303 clrrdi r11,r11,28 /* Get the esid part of the ste */
1304 slbie r11
1305
13062: std r9,8(r10) /* Store the vsid part of the ste */
1307 eieio
1308
1309 mfspr r11,SPRN_DAR /* Get the new esid */
1310 clrrdi r11,r11,28 /* Permits a full 32b of ESID */
1311 ori r11,r11,0x90 /* Turn on valid and kp */
1312 std r11,0(r10) /* Put new entry back into the stab */
1313
1314 sync
1315
1316 /* All done -- return from exception. */
1317 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1318 ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
1319
1320 andi. r10,r12,MSR_RI
1321 beq- unrecov_slb
1322
1323 mtcrf 0x80,r9 /* restore CR */
1324
1325 mfmsr r10
1326 clrrdi r10,r10,2
1327 mtmsrd r10,1
1328
1329 mtspr SPRN_SRR0,r11
1330 mtspr SPRN_SRR1,r12
1331 ld r9,PACA_EXSLB+EX_R9(r13)
1332 ld r10,PACA_EXSLB+EX_R10(r13)
1333 ld r11,PACA_EXSLB+EX_R11(r13)
1334 ld r12,PACA_EXSLB+EX_R12(r13)
1335 ld r13,PACA_EXSLB+EX_R13(r13)
1336 rfid
1337 b . /* prevent speculative execution */
1338
1339/*
1340 * Space for CPU0's segment table.
1341 *
1342 * On iSeries, the hypervisor must fill in at least one entry before
1343 * we get control (with relocate on). The address is give to the hv
1344 * as a page number (see xLparMap in lpardata.c), so this must be at a
1345 * fixed address (the linker can't compute (u64)&initial_stab >>
1346 * PAGE_SHIFT).
1347 */
1348 . = STAB0_PHYS_ADDR /* 0x6000 */
1349 .globl initial_stab
1350initial_stab:
1351 .space 4096
1352
1353/*
1354 * Data area reserved for FWNMI option.
1355 * This address (0x7000) is fixed by the RPA.
1356 */
1357 .= 0x7000
1358 .globl fwnmi_data_area
1359fwnmi_data_area:
1360
1361 /* iSeries does not use the FWNMI stuff, so it is safe to put
1362 * this here, even if we later allow kernels that will boot on
1363 * both pSeries and iSeries */
1364#ifdef CONFIG_PPC_ISERIES
1365 . = LPARMAP_PHYS
1366#include "lparmap.s"
1367/*
1368 * This ".text" is here for old compilers that generate a trailing
1369 * .note section when compiling .c files to .s
1370 */
1371 .text
1372#endif /* CONFIG_PPC_ISERIES */
1373
1374 . = 0x8000
1375
1376/*
1377 * On pSeries, secondary processors spin in the following code.
1378 * At entry, r3 = this processor's number (physical cpu id)
1379 */
1380_GLOBAL(pSeries_secondary_smp_init)
1381 mr r24,r3
1382
1383 /* turn on 64-bit mode */
1384 bl .enable_64b_mode
1385 isync
1386
1387 /* Copy some CPU settings from CPU 0 */
1388 bl .__restore_cpu_setup
1389
1390 /* Set up a paca value for this processor. Since we have the
1391 * physical cpu id in r24, we need to search the pacas to find
1392 * which logical id maps to our physical one.
1393 */
1394 LOADADDR(r13, paca) /* Get base vaddr of paca array */
1395 li r5,0 /* logical cpu id */
13961: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
1397 cmpw r6,r24 /* Compare to our id */
1398 beq 2f
1399 addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */
1400 addi r5,r5,1
1401 cmpwi r5,NR_CPUS
1402 blt 1b
1403
1404 mr r3,r24 /* not found, copy phys to r3 */
1405 b .kexec_wait /* next kernel might do better */
1406
14072: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
1408 /* From now on, r24 is expected to be logical cpuid */
1409 mr r24,r5
14103: HMT_LOW
1411 lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
1412 /* start. */
1413 sync
1414
1415 /* Create a temp kernel stack for use before relocation is on. */
1416 ld r1,PACAEMERGSP(r13)
1417 subi r1,r1,STACK_FRAME_OVERHEAD
1418
1419 cmpwi 0,r23,0
1420#ifdef CONFIG_SMP
1421 bne .__secondary_start
1422#endif
1423 b 3b /* Loop until told to go */
1424
1425#ifdef CONFIG_PPC_ISERIES
1426_STATIC(__start_initialization_iSeries)
1427 /* Clear out the BSS */
1428 LOADADDR(r11,__bss_stop)
1429 LOADADDR(r8,__bss_start)
1430 sub r11,r11,r8 /* bss size */
1431 addi r11,r11,7 /* round up to an even double word */
1432 rldicl. r11,r11,61,3 /* shift right by 3 */
1433 beq 4f
1434 addi r8,r8,-8
1435 li r0,0
1436 mtctr r11 /* zero this many doublewords */
14373: stdu r0,8(r8)
1438 bdnz 3b
14394:
1440 LOADADDR(r1,init_thread_union)
1441 addi r1,r1,THREAD_SIZE
1442 li r0,0
1443 stdu r0,-STACK_FRAME_OVERHEAD(r1)
1444
1445 LOADADDR(r3,cpu_specs)
1446 LOADADDR(r4,cur_cpu_spec)
1447 li r5,0
1448 bl .identify_cpu
1449
1450 LOADADDR(r2,__toc_start)
1451 addi r2,r2,0x4000
1452 addi r2,r2,0x4000
1453
1454 bl .iSeries_early_setup
1455 bl .early_setup
1456
1457 /* relocation is on at this point */
1458
1459 b .start_here_common
1460#endif /* CONFIG_PPC_ISERIES */
1461
1462#ifdef CONFIG_PPC_MULTIPLATFORM
1463
1464_STATIC(__mmu_off)
1465 mfmsr r3
1466 andi. r0,r3,MSR_IR|MSR_DR
1467 beqlr
1468 andc r3,r3,r0
1469 mtspr SPRN_SRR0,r4
1470 mtspr SPRN_SRR1,r3
1471 sync
1472 rfid
1473 b . /* prevent speculative execution */
1474
1475
1476/*
1477 * Here is our main kernel entry point. We support currently 2 kind of entries
1478 * depending on the value of r5.
1479 *
1480 * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
1481 * in r3...r7
1482 *
1483 * r5 == NULL -> kexec style entry. r3 is a physical pointer to the
1484 * DT block, r4 is a physical pointer to the kernel itself
1485 *
1486 */
1487_GLOBAL(__start_initialization_multiplatform)
1488 /*
1489 * Are we booted from a PROM Of-type client-interface ?
1490 */
1491 cmpldi cr0,r5,0
1492 bne .__boot_from_prom /* yes -> prom */
1493
1494 /* Save parameters */
1495 mr r31,r3
1496 mr r30,r4
1497
1498 /* Make sure we are running in 64 bits mode */
1499 bl .enable_64b_mode
1500
1501 /* Setup some critical 970 SPRs before switching MMU off */
1502 bl .__970_cpu_preinit
1503
1504 /* cpu # */
1505 li r24,0
1506
1507 /* Switch off MMU if not already */
1508 LOADADDR(r4, .__after_prom_start - KERNELBASE)
1509 add r4,r4,r30
1510 bl .__mmu_off
1511 b .__after_prom_start
1512
1513_STATIC(__boot_from_prom)
1514 /* Save parameters */
1515 mr r31,r3
1516 mr r30,r4
1517 mr r29,r5
1518 mr r28,r6
1519 mr r27,r7
1520
1521 /* Make sure we are running in 64 bits mode */
1522 bl .enable_64b_mode
1523
1524 /* put a relocation offset into r3 */
1525 bl .reloc_offset
1526
1527 LOADADDR(r2,__toc_start)
1528 addi r2,r2,0x4000
1529 addi r2,r2,0x4000
1530
1531 /* Relocate the TOC from a virt addr to a real addr */
1532 sub r2,r2,r3
1533
1534 /* Restore parameters */
1535 mr r3,r31
1536 mr r4,r30
1537 mr r5,r29
1538 mr r6,r28
1539 mr r7,r27
1540
1541 /* Do all of the interaction with OF client interface */
1542 bl .prom_init
1543 /* We never return */
1544 trap
1545
1546/*
1547 * At this point, r3 contains the physical address we are running at,
1548 * returned by prom_init()
1549 */
1550_STATIC(__after_prom_start)
1551
1552/*
1553 * We need to run with __start at physical address 0.
1554 * This will leave some code in the first 256B of
1555 * real memory, which are reserved for software use.
1556 * The remainder of the first page is loaded with the fixed
1557 * interrupt vectors. The next two pages are filled with
1558 * unknown exception placeholders.
1559 *
1560 * Note: This process overwrites the OF exception vectors.
1561 * r26 == relocation offset
1562 * r27 == KERNELBASE
1563 */
1564 bl .reloc_offset
1565 mr r26,r3
1566 SET_REG_TO_CONST(r27,KERNELBASE)
1567
1568 li r3,0 /* target addr */
1569
1570 // XXX FIXME: Use phys returned by OF (r30)
1571 sub r4,r27,r26 /* source addr */
1572 /* current address of _start */
1573 /* i.e. where we are running */
1574 /* the source addr */
1575
1576 LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */
1577 sub r5,r5,r27
1578
1579 li r6,0x100 /* Start offset, the first 0x100 */
1580 /* bytes were copied earlier. */
1581
1582 bl .copy_and_flush /* copy the first n bytes */
1583 /* this includes the code being */
1584 /* executed here. */
1585
1586 LOADADDR(r0, 4f) /* Jump to the copy of this code */
1587 mtctr r0 /* that we just made/relocated */
1588 bctr
1589
15904: LOADADDR(r5,klimit)
1591 sub r5,r5,r26
1592 ld r5,0(r5) /* get the value of klimit */
1593 sub r5,r5,r27
1594 bl .copy_and_flush /* copy the rest */
1595 b .start_here_multiplatform
1596
1597#endif /* CONFIG_PPC_MULTIPLATFORM */
1598
1599/*
1600 * Copy routine used to copy the kernel to start at physical address 0
1601 * and flush and invalidate the caches as needed.
1602 * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
1603 * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
1604 *
1605 * Note: this routine *only* clobbers r0, r6 and lr
1606 */
1607_GLOBAL(copy_and_flush)
1608 addi r5,r5,-8
1609 addi r6,r6,-8
16104: li r0,16 /* Use the least common */
1611 /* denominator cache line */
1612 /* size. This results in */
1613 /* extra cache line flushes */
1614 /* but operation is correct. */
1615 /* Can't get cache line size */
1616 /* from NACA as it is being */
1617 /* moved too. */
1618
1619 mtctr r0 /* put # words/line in ctr */
16203: addi r6,r6,8 /* copy a cache line */
1621 ldx r0,r6,r4
1622 stdx r0,r6,r3
1623 bdnz 3b
1624 dcbst r6,r3 /* write it to memory */
1625 sync
1626 icbi r6,r3 /* flush the icache line */
1627 cmpld 0,r6,r5
1628 blt 4b
1629 sync
1630 addi r5,r5,8
1631 addi r6,r6,8
1632 blr
1633
1634.align 8
1635copy_to_here:
1636
1637#ifdef CONFIG_SMP
1638#ifdef CONFIG_PPC_PMAC
1639/*
1640 * On PowerMac, secondary processors starts from the reset vector, which
1641 * is temporarily turned into a call to one of the functions below.
1642 */
1643 .section ".text";
1644 .align 2 ;
1645
1646 .globl __secondary_start_pmac_0
1647__secondary_start_pmac_0:
1648 /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
1649 li r24,0
1650 b 1f
1651 li r24,1
1652 b 1f
1653 li r24,2
1654 b 1f
1655 li r24,3
16561:
1657
1658_GLOBAL(pmac_secondary_start)
1659 /* turn on 64-bit mode */
1660 bl .enable_64b_mode
1661 isync
1662
1663 /* Copy some CPU settings from CPU 0 */
1664 bl .__restore_cpu_setup
1665
1666 /* pSeries do that early though I don't think we really need it */
1667 mfmsr r3
1668 ori r3,r3,MSR_RI
1669 mtmsrd r3 /* RI on */
1670
1671 /* Set up a paca value for this processor. */
1672 LOADADDR(r4, paca) /* Get base vaddr of paca array */
1673 mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
1674 add r13,r13,r4 /* for this processor. */
1675 mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
1676
1677 /* Create a temp kernel stack for use before relocation is on. */
1678 ld r1,PACAEMERGSP(r13)
1679 subi r1,r1,STACK_FRAME_OVERHEAD
1680
1681 b .__secondary_start
1682
1683#endif /* CONFIG_PPC_PMAC */
1684
1685/*
1686 * This function is called after the master CPU has released the
1687 * secondary processors. The execution environment is relocation off.
1688 * The paca for this processor has the following fields initialized at
1689 * this point:
1690 * 1. Processor number
1691 * 2. Segment table pointer (virtual address)
1692 * On entry the following are set:
1693 * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
1694 * r24 = cpu# (in Linux terms)
1695 * r13 = paca virtual address
1696 * SPRG3 = paca virtual address
1697 */
1698_GLOBAL(__secondary_start)
1699
1700 HMT_MEDIUM /* Set thread priority to MEDIUM */
1701
1702 ld r2,PACATOC(r13)
1703
1704 /* Do early setup for that CPU */
1705 bl .early_setup_secondary
1706
1707 /* Initialize the kernel stack. Just a repeat for iSeries. */
1708 LOADADDR(r3,current_set)
1709 sldi r28,r24,3 /* get current_set[cpu#] */
1710 ldx r1,r3,r28
1711 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1712 std r1,PACAKSAVE(r13)
1713
1714 li r7,0
1715 mtlr r7
1716
1717 /* enable MMU and jump to start_secondary */
1718 LOADADDR(r3,.start_secondary_prolog)
1719 SET_REG_TO_CONST(r4, MSR_KERNEL)
1720#ifdef DO_SOFT_DISABLE
1721 ori r4,r4,MSR_EE
1722#endif
1723 mtspr SPRN_SRR0,r3
1724 mtspr SPRN_SRR1,r4
1725 rfid
1726 b . /* prevent speculative execution */
1727
1728/*
1729 * Running with relocation on at this point. All we want to do is
1730 * zero the stack back-chain pointer before going into C code.
1731 */
1732_GLOBAL(start_secondary_prolog)
1733 li r3,0
1734 std r3,0(r1) /* Zero the stack frame pointer */
1735 bl .start_secondary
1736#endif
1737
1738/*
1739 * This subroutine clobbers r11 and r12
1740 */
1741_GLOBAL(enable_64b_mode)
1742 mfmsr r11 /* grab the current MSR */
1743 li r12,1
1744 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
1745 or r11,r11,r12
1746 li r12,1
1747 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
1748 or r11,r11,r12
1749 mtmsrd r11
1750 isync
1751 blr
1752
1753#ifdef CONFIG_PPC_MULTIPLATFORM
1754/*
1755 * This is where the main kernel code starts.
1756 */
1757_STATIC(start_here_multiplatform)
1758 /* get a new offset, now that the kernel has moved. */
1759 bl .reloc_offset
1760 mr r26,r3
1761
1762 /* Clear out the BSS. It may have been done in prom_init,
1763 * already but that's irrelevant since prom_init will soon
1764 * be detached from the kernel completely. Besides, we need
1765 * to clear it now for kexec-style entry.
1766 */
1767 LOADADDR(r11,__bss_stop)
1768 LOADADDR(r8,__bss_start)
1769 sub r11,r11,r8 /* bss size */
1770 addi r11,r11,7 /* round up to an even double word */
1771 rldicl. r11,r11,61,3 /* shift right by 3 */
1772 beq 4f
1773 addi r8,r8,-8
1774 li r0,0
1775 mtctr r11 /* zero this many doublewords */
17763: stdu r0,8(r8)
1777 bdnz 3b
17784:
1779
1780 mfmsr r6
1781 ori r6,r6,MSR_RI
1782 mtmsrd r6 /* RI on */
1783
1784#ifdef CONFIG_HMT
1785 /* Start up the second thread on cpu 0 */
1786 mfspr r3,SPRN_PVR
1787 srwi r3,r3,16
1788 cmpwi r3,0x34 /* Pulsar */
1789 beq 90f
1790 cmpwi r3,0x36 /* Icestar */
1791 beq 90f
1792 cmpwi r3,0x37 /* SStar */
1793 beq 90f
1794 b 91f /* HMT not supported */
179590: li r3,0
1796 bl .hmt_start_secondary
179791:
1798#endif
1799
1800 /* The following gets the stack and TOC set up with the regs */
1801 /* pointing to the real addr of the kernel stack. This is */
1802 /* all done to support the C function call below which sets */
1803 /* up the htab. This is done because we have relocated the */
1804 /* kernel but are still running in real mode. */
1805
1806 LOADADDR(r3,init_thread_union)
1807 sub r3,r3,r26
1808
1809 /* set up a stack pointer (physical address) */
1810 addi r1,r3,THREAD_SIZE
1811 li r0,0
1812 stdu r0,-STACK_FRAME_OVERHEAD(r1)
1813
1814 /* set up the TOC (physical address) */
1815 LOADADDR(r2,__toc_start)
1816 addi r2,r2,0x4000
1817 addi r2,r2,0x4000
1818 sub r2,r2,r26
1819
1820 LOADADDR(r3,cpu_specs)
1821 sub r3,r3,r26
1822 LOADADDR(r4,cur_cpu_spec)
1823 sub r4,r4,r26
1824 mr r5,r26
1825 bl .identify_cpu
1826
1827 /* Save some low level config HIDs of CPU0 to be copied to
1828 * other CPUs later on, or used for suspend/resume
1829 */
1830 bl .__save_cpu_setup
1831 sync
1832
1833 /* Setup a valid physical PACA pointer in SPRG3 for early_setup
1834 * note that boot_cpuid can always be 0 nowadays since there is
1835 * nowhere it can be initialized differently before we reach this
1836 * code
1837 */
1838 LOADADDR(r27, boot_cpuid)
1839 sub r27,r27,r26
1840 lwz r27,0(r27)
1841
1842 LOADADDR(r24, paca) /* Get base vaddr of paca array */
1843 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1844 add r13,r13,r24 /* for this processor. */
1845 sub r13,r13,r26 /* convert to physical addr */
1846 mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */
1847
1848 /* Do very early kernel initializations, including initial hash table,
1849 * stab and slb setup before we turn on relocation. */
1850
1851 /* Restore parameters passed from prom_init/kexec */
1852 mr r3,r31
1853 bl .early_setup
1854
1855 LOADADDR(r3,.start_here_common)
1856 SET_REG_TO_CONST(r4, MSR_KERNEL)
1857 mtspr SPRN_SRR0,r3
1858 mtspr SPRN_SRR1,r4
1859 rfid
1860 b . /* prevent speculative execution */
1861#endif /* CONFIG_PPC_MULTIPLATFORM */
1862
1863 /* This is where all platforms converge execution */
1864_STATIC(start_here_common)
1865 /* relocation is on at this point */
1866
1867 /* The following code sets up the SP and TOC now that we are */
1868 /* running with translation enabled. */
1869
1870 LOADADDR(r3,init_thread_union)
1871
1872 /* set up the stack */
1873 addi r1,r3,THREAD_SIZE
1874 li r0,0
1875 stdu r0,-STACK_FRAME_OVERHEAD(r1)
1876
1877 /* Apply the CPUs-specific fixups (nop out sections not relevant
1878 * to this CPU
1879 */
1880 li r3,0
1881 bl .do_cpu_ftr_fixups
1882
1883 LOADADDR(r26, boot_cpuid)
1884 lwz r26,0(r26)
1885
1886 LOADADDR(r24, paca) /* Get base vaddr of paca array */
1887 mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
1888 add r13,r13,r24 /* for this processor. */
1889 mtspr SPRN_SPRG3,r13
1890
1891 /* ptr to current */
1892 LOADADDR(r4,init_task)
1893 std r4,PACACURRENT(r13)
1894
1895 /* Load the TOC */
1896 ld r2,PACATOC(r13)
1897 std r1,PACAKSAVE(r13)
1898
1899 bl .setup_system
1900
1901 /* Load up the kernel context */
19025:
1903#ifdef DO_SOFT_DISABLE
1904 li r5,0
1905 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
1906 mfmsr r5
1907 ori r5,r5,MSR_EE /* Hard Enabled */
1908 mtmsrd r5
1909#endif
1910
1911 bl .start_kernel
1912
1913_GLOBAL(hmt_init)
1914#ifdef CONFIG_HMT
1915 LOADADDR(r5, hmt_thread_data)
1916 mfspr r7,SPRN_PVR
1917 srwi r7,r7,16
1918 cmpwi r7,0x34 /* Pulsar */
1919 beq 90f
1920 cmpwi r7,0x36 /* Icestar */
1921 beq 91f
1922 cmpwi r7,0x37 /* SStar */
1923 beq 91f
1924 b 101f
192590: mfspr r6,SPRN_PIR
1926 andi. r6,r6,0x1f
1927 b 92f
192891: mfspr r6,SPRN_PIR
1929 andi. r6,r6,0x3ff
193092: sldi r4,r24,3
1931 stwx r6,r5,r4
1932 bl .hmt_start_secondary
1933 b 101f
1934
1935__hmt_secondary_hold:
1936 LOADADDR(r5, hmt_thread_data)
1937 clrldi r5,r5,4
1938 li r7,0
1939 mfspr r6,SPRN_PIR
1940 mfspr r8,SPRN_PVR
1941 srwi r8,r8,16
1942 cmpwi r8,0x34
1943 bne 93f
1944 andi. r6,r6,0x1f
1945 b 103f
194693: andi. r6,r6,0x3f
1947
1948103: lwzx r8,r5,r7
1949 cmpw r8,r6
1950 beq 104f
1951 addi r7,r7,8
1952 b 103b
1953
1954104: addi r7,r7,4
1955 lwzx r9,r5,r7
1956 mr r24,r9
1957101:
1958#endif
1959 mr r3,r24
1960 b .pSeries_secondary_smp_init
1961
1962#ifdef CONFIG_HMT
1963_GLOBAL(hmt_start_secondary)
1964 LOADADDR(r4,__hmt_secondary_hold)
1965 clrldi r4,r4,4
1966 mtspr SPRN_NIADORM, r4
1967 mfspr r4, SPRN_MSRDORM
1968 li r5, -65
1969 and r4, r4, r5
1970 mtspr SPRN_MSRDORM, r4
1971 lis r4,0xffef
1972 ori r4,r4,0x7403
1973 mtspr SPRN_TSC, r4
1974 li r4,0x1f4
1975 mtspr SPRN_TST, r4
1976 mfspr r4, SPRN_HID0
1977 ori r4, r4, 0x1
1978 mtspr SPRN_HID0, r4
1979 mfspr r4, SPRN_CTRLF
1980 oris r4, r4, 0x40
1981 mtspr SPRN_CTRLT, r4
1982 blr
1983#endif
1984
1985/*
1986 * We put a few things here that have to be page-aligned.
1987 * This stuff goes at the beginning of the bss, which is page-aligned.
1988 */
1989 .section ".bss"
1990
1991 .align PAGE_SHIFT
1992
1993 .globl empty_zero_page
1994empty_zero_page:
1995 .space PAGE_SIZE
1996
1997 .globl swapper_pg_dir
1998swapper_pg_dir:
1999 .space PAGE_SIZE
2000
2001/*
2002 * This space gets a copy of optional info passed to us by the bootstrap
2003 * Used to pass parameters into the kernel like root=/dev/sda1, etc.
2004 */
2005 .globl cmd_line
2006cmd_line:
2007 .space COMMAND_LINE_SIZE
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
deleted file mode 100644
index 5e089deb0a2b..000000000000
--- a/arch/ppc64/kernel/misc.S
+++ /dev/null
@@ -1,940 +0,0 @@
1/*
2 * arch/ppc/kernel/misc.S
3 *
4 *
5 *
6 * This file contains miscellaneous low-level functions.
7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8 *
9 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
10 * and Paul Mackerras.
11 * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
12 * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 *
19 */
20
21#include <linux/config.h>
22#include <linux/sys.h>
23#include <asm/unistd.h>
24#include <asm/errno.h>
25#include <asm/processor.h>
26#include <asm/page.h>
27#include <asm/cache.h>
28#include <asm/ppc_asm.h>
29#include <asm/asm-offsets.h>
30#include <asm/cputable.h>
31#include <asm/thread_info.h>
32
33 .text
34
35/*
36 * Returns (address we were linked at) - (address we are running at)
37 * for use before the text and data are mapped to KERNELBASE.
38 */
39
40_GLOBAL(reloc_offset)
41 mflr r0
42 bl 1f
431: mflr r3
44 LOADADDR(r4,1b)
45 sub r3,r4,r3
46 mtlr r0
47 blr
48
49_GLOBAL(get_msr)
50 mfmsr r3
51 blr
52
53_GLOBAL(get_dar)
54 mfdar r3
55 blr
56
57_GLOBAL(get_srr0)
58 mfsrr0 r3
59 blr
60
61_GLOBAL(get_srr1)
62 mfsrr1 r3
63 blr
64
65_GLOBAL(get_sp)
66 mr r3,r1
67 blr
68
69#ifdef CONFIG_IRQSTACKS
70_GLOBAL(call_do_softirq)
71 mflr r0
72 std r0,16(r1)
73 stdu r1,THREAD_SIZE-112(r3)
74 mr r1,r3
75 bl .__do_softirq
76 ld r1,0(r1)
77 ld r0,16(r1)
78 mtlr r0
79 blr
80
81_GLOBAL(call___do_IRQ)
82 mflr r0
83 std r0,16(r1)
84 stdu r1,THREAD_SIZE-112(r5)
85 mr r1,r5
86 bl .__do_IRQ
87 ld r1,0(r1)
88 ld r0,16(r1)
89 mtlr r0
90 blr
91#endif /* CONFIG_IRQSTACKS */
92
93 /*
94 * To be called by C code which needs to do some operations with MMU
95 * disabled. Note that interrupts have to be disabled by the caller
96 * prior to calling us. The code called _MUST_ be in the RMO of course
97 * and part of the linear mapping as we don't attempt to translate the
98 * stack pointer at all. The function is called with the stack switched
99 * to this CPU emergency stack
100 *
101 * prototype is void *call_with_mmu_off(void *func, void *data);
102 *
103 * the called function is expected to be of the form
104 *
105 * void *called(void *data);
106 */
107_GLOBAL(call_with_mmu_off)
108 mflr r0 /* get link, save it on stackframe */
109 std r0,16(r1)
110 mr r1,r5 /* save old stack ptr */
111 ld r1,PACAEMERGSP(r13) /* get emerg. stack */
112 subi r1,r1,STACK_FRAME_OVERHEAD
113 std r0,16(r1) /* save link on emerg. stack */
114 std r5,0(r1) /* save old stack ptr in backchain */
115 ld r3,0(r3) /* get to real function ptr (assume same TOC) */
116 bl 2f /* we need LR to return, continue at label 2 */
117
118 ld r0,16(r1) /* we return here from the call, get LR and */
119 ld r1,0(r1) /* .. old stack ptr */
120 mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */
121 mfmsr r4
122 ori r4,r4,MSR_IR|MSR_DR
123 mtspr SPRN_SRR1,r4
124 rfid
125
1262: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */
127 mr r3,r4 /* get parameter */
128 mfmsr r0
129 ori r0,r0,MSR_IR|MSR_DR
130 xori r0,r0,MSR_IR|MSR_DR
131 mtspr SPRN_SRR1,r0
132 rfid
133
134
135 .section ".toc","aw"
136PPC64_CACHES:
137 .tc ppc64_caches[TC],ppc64_caches
138 .section ".text"
139
140/*
141 * Write any modified data cache blocks out to memory
142 * and invalidate the corresponding instruction cache blocks.
143 *
144 * flush_icache_range(unsigned long start, unsigned long stop)
145 *
146 * flush all bytes from start through stop-1 inclusive
147 */
148
149_KPROBE(__flush_icache_range)
150
151/*
152 * Flush the data cache to memory
153 *
154 * Different systems have different cache line sizes
155 * and in some cases i-cache and d-cache line sizes differ from
156 * each other.
157 */
158 ld r10,PPC64_CACHES@toc(r2)
159 lwz r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
160 addi r5,r7,-1
161 andc r6,r3,r5 /* round low to line bdy */
162 subf r8,r6,r4 /* compute length */
163 add r8,r8,r5 /* ensure we get enough */
164 lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of cache line size */
165 srw. r8,r8,r9 /* compute line count */
166 beqlr /* nothing to do? */
167 mtctr r8
1681: dcbst 0,r6
169 add r6,r6,r7
170 bdnz 1b
171 sync
172
173/* Now invalidate the instruction cache */
174
175 lwz r7,ICACHEL1LINESIZE(r10) /* Get Icache line size */
176 addi r5,r7,-1
177 andc r6,r3,r5 /* round low to line bdy */
178 subf r8,r6,r4 /* compute length */
179 add r8,r8,r5
180 lwz r9,ICACHEL1LOGLINESIZE(r10) /* Get log-2 of Icache line size */
181 srw. r8,r8,r9 /* compute line count */
182 beqlr /* nothing to do? */
183 mtctr r8
1842: icbi 0,r6
185 add r6,r6,r7
186 bdnz 2b
187 isync
188 blr
189
190 .text
191/*
192 * Like above, but only do the D-cache.
193 *
194 * flush_dcache_range(unsigned long start, unsigned long stop)
195 *
196 * flush all bytes from start to stop-1 inclusive
197 */
198_GLOBAL(flush_dcache_range)
199
200/*
201 * Flush the data cache to memory
202 *
203 * Different systems have different cache line sizes
204 */
205 ld r10,PPC64_CACHES@toc(r2)
206 lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
207 addi r5,r7,-1
208 andc r6,r3,r5 /* round low to line bdy */
209 subf r8,r6,r4 /* compute length */
210 add r8,r8,r5 /* ensure we get enough */
211 lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
212 srw. r8,r8,r9 /* compute line count */
213 beqlr /* nothing to do? */
214 mtctr r8
2150: dcbst 0,r6
216 add r6,r6,r7
217 bdnz 0b
218 sync
219 blr
220
221/*
222 * Like above, but works on non-mapped physical addresses.
223 * Use only for non-LPAR setups ! It also assumes real mode
224 * is cacheable. Used for flushing out the DART before using
225 * it as uncacheable memory
226 *
227 * flush_dcache_phys_range(unsigned long start, unsigned long stop)
228 *
229 * flush all bytes from start to stop-1 inclusive
230 */
231_GLOBAL(flush_dcache_phys_range)
232 ld r10,PPC64_CACHES@toc(r2)
233 lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
234 addi r5,r7,-1
235 andc r6,r3,r5 /* round low to line bdy */
236 subf r8,r6,r4 /* compute length */
237 add r8,r8,r5 /* ensure we get enough */
238 lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
239 srw. r8,r8,r9 /* compute line count */
240 beqlr /* nothing to do? */
241 mfmsr r5 /* Disable MMU Data Relocation */
242 ori r0,r5,MSR_DR
243 xori r0,r0,MSR_DR
244 sync
245 mtmsr r0
246 sync
247 isync
248 mtctr r8
2490: dcbst 0,r6
250 add r6,r6,r7
251 bdnz 0b
252 sync
253 isync
254 mtmsr r5 /* Re-enable MMU Data Relocation */
255 sync
256 isync
257 blr
258
259_GLOBAL(flush_inval_dcache_range)
260 ld r10,PPC64_CACHES@toc(r2)
261 lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
262 addi r5,r7,-1
263 andc r6,r3,r5 /* round low to line bdy */
264 subf r8,r6,r4 /* compute length */
265 add r8,r8,r5 /* ensure we get enough */
266 lwz r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
267 srw. r8,r8,r9 /* compute line count */
268 beqlr /* nothing to do? */
269 sync
270 isync
271 mtctr r8
2720: dcbf 0,r6
273 add r6,r6,r7
274 bdnz 0b
275 sync
276 isync
277 blr
278
279
280/*
281 * Flush a particular page from the data cache to RAM.
282 * Note: this is necessary because the instruction cache does *not*
283 * snoop from the data cache.
284 *
285 * void __flush_dcache_icache(void *page)
286 */
287_GLOBAL(__flush_dcache_icache)
288/*
289 * Flush the data cache to memory
290 *
291 * Different systems have different cache line sizes
292 */
293
294/* Flush the dcache */
295 ld r7,PPC64_CACHES@toc(r2)
296 clrrdi r3,r3,PAGE_SHIFT /* Page align */
297 lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */
298 lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */
299 mr r6,r3
300 mtctr r4
3010: dcbst 0,r6
302 add r6,r6,r5
303 bdnz 0b
304 sync
305
306/* Now invalidate the icache */
307
308 lwz r4,ICACHEL1LINESPERPAGE(r7) /* Get # icache lines per page */
309 lwz r5,ICACHEL1LINESIZE(r7) /* Get icache line size */
310 mtctr r4
3111: icbi 0,r3
312 add r3,r3,r5
313 bdnz 1b
314 isync
315 blr
316
317/*
318 * I/O string operations
319 *
320 * insb(port, buf, len)
321 * outsb(port, buf, len)
322 * insw(port, buf, len)
323 * outsw(port, buf, len)
324 * insl(port, buf, len)
325 * outsl(port, buf, len)
326 * insw_ns(port, buf, len)
327 * outsw_ns(port, buf, len)
328 * insl_ns(port, buf, len)
329 * outsl_ns(port, buf, len)
330 *
331 * The *_ns versions don't do byte-swapping.
332 */
333_GLOBAL(_insb)
334 cmpwi 0,r5,0
335 mtctr r5
336 subi r4,r4,1
337 blelr-
33800: lbz r5,0(r3)
339 eieio
340 stbu r5,1(r4)
341 bdnz 00b
342 twi 0,r5,0
343 isync
344 blr
345
346_GLOBAL(_outsb)
347 cmpwi 0,r5,0
348 mtctr r5
349 subi r4,r4,1
350 blelr-
35100: lbzu r5,1(r4)
352 stb r5,0(r3)
353 bdnz 00b
354 sync
355 blr
356
357_GLOBAL(_insw)
358 cmpwi 0,r5,0
359 mtctr r5
360 subi r4,r4,2
361 blelr-
36200: lhbrx r5,0,r3
363 eieio
364 sthu r5,2(r4)
365 bdnz 00b
366 twi 0,r5,0
367 isync
368 blr
369
370_GLOBAL(_outsw)
371 cmpwi 0,r5,0
372 mtctr r5
373 subi r4,r4,2
374 blelr-
37500: lhzu r5,2(r4)
376 sthbrx r5,0,r3
377 bdnz 00b
378 sync
379 blr
380
381_GLOBAL(_insl)
382 cmpwi 0,r5,0
383 mtctr r5
384 subi r4,r4,4
385 blelr-
38600: lwbrx r5,0,r3
387 eieio
388 stwu r5,4(r4)
389 bdnz 00b
390 twi 0,r5,0
391 isync
392 blr
393
394_GLOBAL(_outsl)
395 cmpwi 0,r5,0
396 mtctr r5
397 subi r4,r4,4
398 blelr-
39900: lwzu r5,4(r4)
400 stwbrx r5,0,r3
401 bdnz 00b
402 sync
403 blr
404
405/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
406_GLOBAL(_insw_ns)
407 cmpwi 0,r5,0
408 mtctr r5
409 subi r4,r4,2
410 blelr-
41100: lhz r5,0(r3)
412 eieio
413 sthu r5,2(r4)
414 bdnz 00b
415 twi 0,r5,0
416 isync
417 blr
418
419/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
420_GLOBAL(_outsw_ns)
421 cmpwi 0,r5,0
422 mtctr r5
423 subi r4,r4,2
424 blelr-
42500: lhzu r5,2(r4)
426 sth r5,0(r3)
427 bdnz 00b
428 sync
429 blr
430
431_GLOBAL(_insl_ns)
432 cmpwi 0,r5,0
433 mtctr r5
434 subi r4,r4,4
435 blelr-
43600: lwz r5,0(r3)
437 eieio
438 stwu r5,4(r4)
439 bdnz 00b
440 twi 0,r5,0
441 isync
442 blr
443
444_GLOBAL(_outsl_ns)
445 cmpwi 0,r5,0
446 mtctr r5
447 subi r4,r4,4
448 blelr-
44900: lwzu r5,4(r4)
450 stw r5,0(r3)
451 bdnz 00b
452 sync
453 blr
454
455/*
456 * identify_cpu and calls setup_cpu
457 * In: r3 = base of the cpu_specs array
458 * r4 = address of cur_cpu_spec
459 * r5 = relocation offset
460 */
461_GLOBAL(identify_cpu)
462 mfpvr r7
4631:
464 lwz r8,CPU_SPEC_PVR_MASK(r3)
465 and r8,r8,r7
466 lwz r9,CPU_SPEC_PVR_VALUE(r3)
467 cmplw 0,r9,r8
468 beq 1f
469 addi r3,r3,CPU_SPEC_ENTRY_SIZE
470 b 1b
4711:
472 add r0,r3,r5
473 std r0,0(r4)
474 ld r4,CPU_SPEC_SETUP(r3)
475 sub r4,r4,r5
476 ld r4,0(r4)
477 sub r4,r4,r5
478 mtctr r4
479 /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
480 mr r4,r3
481 mr r3,r5
482 bctr
483
484/*
485 * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
486 * and writes nop's over sections of code that don't apply for this cpu.
487 * r3 = data offset (not changed)
488 */
489_GLOBAL(do_cpu_ftr_fixups)
490 /* Get CPU 0 features */
491 LOADADDR(r6,cur_cpu_spec)
492 sub r6,r6,r3
493 ld r4,0(r6)
494 sub r4,r4,r3
495 ld r4,CPU_SPEC_FEATURES(r4)
496 /* Get the fixup table */
497 LOADADDR(r6,__start___ftr_fixup)
498 sub r6,r6,r3
499 LOADADDR(r7,__stop___ftr_fixup)
500 sub r7,r7,r3
501 /* Do the fixup */
5021: cmpld r6,r7
503 bgelr
504 addi r6,r6,32
505 ld r8,-32(r6) /* mask */
506 and r8,r8,r4
507 ld r9,-24(r6) /* value */
508 cmpld r8,r9
509 beq 1b
510 ld r8,-16(r6) /* section begin */
511 ld r9,-8(r6) /* section end */
512 subf. r9,r8,r9
513 beq 1b
514 /* write nops over the section of code */
515 /* todo: if large section, add a branch at the start of it */
516 srwi r9,r9,2
517 mtctr r9
518 sub r8,r8,r3
519 lis r0,0x60000000@h /* nop */
5203: stw r0,0(r8)
521 andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
522 beq 2f
523 dcbst 0,r8 /* suboptimal, but simpler */
524 sync
525 icbi 0,r8
5262: addi r8,r8,4
527 bdnz 3b
528 sync /* additional sync needed on g4 */
529 isync
530 b 1b
531
532#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
533/*
534 * Do an IO access in real mode
535 */
536_GLOBAL(real_readb)
537 mfmsr r7
538 ori r0,r7,MSR_DR
539 xori r0,r0,MSR_DR
540 sync
541 mtmsrd r0
542 sync
543 isync
544 mfspr r6,SPRN_HID4
545 rldicl r5,r6,32,0
546 ori r5,r5,0x100
547 rldicl r5,r5,32,0
548 sync
549 mtspr SPRN_HID4,r5
550 isync
551 slbia
552 isync
553 lbz r3,0(r3)
554 sync
555 mtspr SPRN_HID4,r6
556 isync
557 slbia
558 isync
559 mtmsrd r7
560 sync
561 isync
562 blr
563
564/*
565 * Do an IO access in real mode
566 */
567_GLOBAL(real_writeb)
568 mfmsr r7
569 ori r0,r7,MSR_DR
570 xori r0,r0,MSR_DR
571 sync
572 mtmsrd r0
573 sync
574 isync
575 mfspr r6,SPRN_HID4
576 rldicl r5,r6,32,0
577 ori r5,r5,0x100
578 rldicl r5,r5,32,0
579 sync
580 mtspr SPRN_HID4,r5
581 isync
582 slbia
583 isync
584 stb r3,0(r4)
585 sync
586 mtspr SPRN_HID4,r6
587 isync
588 slbia
589 isync
590 mtmsrd r7
591 sync
592 isync
593 blr
594#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
595
596/*
597 * SCOM access functions for 970 (FX only for now)
598 *
599 * unsigned long scom970_read(unsigned int address);
600 * void scom970_write(unsigned int address, unsigned long value);
601 *
602 * The address passed in is the 24 bits register address. This code
603 * is 970 specific and will not check the status bits, so you should
604 * know what you are doing.
605 */
606_GLOBAL(scom970_read)
607 /* interrupts off */
608 mfmsr r4
609 ori r0,r4,MSR_EE
610 xori r0,r0,MSR_EE
611 mtmsrd r0,1
612
613 /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
614 * (including parity). On current CPUs they must be 0'd,
615 * and finally or in RW bit
616 */
617 rlwinm r3,r3,8,0,15
618 ori r3,r3,0x8000
619
620 /* do the actual scom read */
621 sync
622 mtspr SPRN_SCOMC,r3
623 isync
624 mfspr r3,SPRN_SCOMD
625 isync
626 mfspr r0,SPRN_SCOMC
627 isync
628
629 /* XXX: fixup result on some buggy 970's (ouch ! we lost a bit, bah
630 * that's the best we can do). Not implemented yet as we don't use
631 * the scom on any of the bogus CPUs yet, but may have to be done
632 * ultimately
633 */
634
635 /* restore interrupts */
636 mtmsrd r4,1
637 blr
638
639
640_GLOBAL(scom970_write)
641 /* interrupts off */
642 mfmsr r5
643 ori r0,r5,MSR_EE
644 xori r0,r0,MSR_EE
645 mtmsrd r0,1
646
647 /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
648 * (including parity). On current CPUs they must be 0'd.
649 */
650
651 rlwinm r3,r3,8,0,15
652
653 sync
654 mtspr SPRN_SCOMD,r4 /* write data */
655 isync
656 mtspr SPRN_SCOMC,r3 /* write command */
657 isync
658 mfspr 3,SPRN_SCOMC
659 isync
660
661 /* restore interrupts */
662 mtmsrd r5,1
663 blr
664
665
666/*
667 * Create a kernel thread
668 * kernel_thread(fn, arg, flags)
669 */
670_GLOBAL(kernel_thread)
671 std r29,-24(r1)
672 std r30,-16(r1)
673 stdu r1,-STACK_FRAME_OVERHEAD(r1)
674 mr r29,r3
675 mr r30,r4
676 ori r3,r5,CLONE_VM /* flags */
677 oris r3,r3,(CLONE_UNTRACED>>16)
678 li r4,0 /* new sp (unused) */
679 li r0,__NR_clone
680 sc
681 cmpdi 0,r3,0 /* parent or child? */
682 bne 1f /* return if parent */
683 li r0,0
684 stdu r0,-STACK_FRAME_OVERHEAD(r1)
685 ld r2,8(r29)
686 ld r29,0(r29)
687 mtlr r29 /* fn addr in lr */
688 mr r3,r30 /* load arg and call fn */
689 blrl
690 li r0,__NR_exit /* exit after child exits */
691 li r3,0
692 sc
6931: addi r1,r1,STACK_FRAME_OVERHEAD
694 ld r29,-24(r1)
695 ld r30,-16(r1)
696 blr
697
698/*
699 * disable_kernel_fp()
700 * Disable the FPU.
701 */
702_GLOBAL(disable_kernel_fp)
703 mfmsr r3
704 rldicl r0,r3,(63-MSR_FP_LG),1
705 rldicl r3,r0,(MSR_FP_LG+1),0
706 mtmsrd r3 /* disable use of fpu now */
707 isync
708 blr
709
710#ifdef CONFIG_ALTIVEC
711
712#if 0 /* this has no callers for now */
713/*
714 * disable_kernel_altivec()
715 * Disable the VMX.
716 */
717_GLOBAL(disable_kernel_altivec)
718 mfmsr r3
719 rldicl r0,r3,(63-MSR_VEC_LG),1
720 rldicl r3,r0,(MSR_VEC_LG+1),0
721 mtmsrd r3 /* disable use of VMX now */
722 isync
723 blr
724#endif /* 0 */
725
726/*
727 * giveup_altivec(tsk)
728 * Disable VMX for the task given as the argument,
729 * and save the vector registers in its thread_struct.
730 * Enables the VMX for use in the kernel on return.
731 */
732_GLOBAL(giveup_altivec)
733 mfmsr r5
734 oris r5,r5,MSR_VEC@h
735 mtmsrd r5 /* enable use of VMX now */
736 isync
737 cmpdi 0,r3,0
738 beqlr- /* if no previous owner, done */
739 addi r3,r3,THREAD /* want THREAD of task */
740 ld r5,PT_REGS(r3)
741 cmpdi 0,r5,0
742 SAVE_32VRS(0,r4,r3)
743 mfvscr vr0
744 li r4,THREAD_VSCR
745 stvx vr0,r4,r3
746 beq 1f
747 ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
748 lis r3,MSR_VEC@h
749 andc r4,r4,r3 /* disable FP for previous task */
750 std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
7511:
752#ifndef CONFIG_SMP
753 li r5,0
754 ld r4,last_task_used_altivec@got(r2)
755 std r5,0(r4)
756#endif /* CONFIG_SMP */
757 blr
758
759#endif /* CONFIG_ALTIVEC */
760
761_GLOBAL(__setup_cpu_power3)
762 blr
763
764_GLOBAL(execve)
765 li r0,__NR_execve
766 sc
767 bnslr
768 neg r3,r3
769 blr
770
771/* kexec_wait(phys_cpu)
772 *
773 * wait for the flag to change, indicating this kernel is going away but
774 * the slave code for the next one is at addresses 0 to 100.
775 *
776 * This is used by all slaves.
777 *
778 * Physical (hardware) cpu id should be in r3.
779 */
780_GLOBAL(kexec_wait)
781 bl 1f
7821: mflr r5
783 addi r5,r5,kexec_flag-1b
784
78599: HMT_LOW
786#ifdef CONFIG_KEXEC /* use no memory without kexec */
787 lwz r4,0(r5)
788 cmpwi 0,r4,0
789 bnea 0x60
790#endif
791 b 99b
792
793/* this can be in text because we won't change it until we are
794 * running in real anyways
795 */
796kexec_flag:
797 .long 0
798
799
800#ifdef CONFIG_KEXEC
801
802/* kexec_smp_wait(void)
803 *
804 * call with interrupts off
805 * note: this is a terminal routine, it does not save lr
806 *
807 * get phys id from paca
808 * set paca id to -1 to say we got here
809 * switch to real mode
810 * join other cpus in kexec_wait(phys_id)
811 */
812_GLOBAL(kexec_smp_wait)
813 lhz r3,PACAHWCPUID(r13)
814 li r4,-1
815 sth r4,PACAHWCPUID(r13) /* let others know we left */
816 bl real_mode
817 b .kexec_wait
818
819/*
820 * switch to real mode (turn mmu off)
821 * we use the early kernel trick that the hardware ignores bits
822 * 0 and 1 (big endian) of the effective address in real mode
823 *
824 * don't overwrite r3 here, it is live for kexec_wait above.
825 */
826real_mode: /* assume normal blr return */
8271: li r9,MSR_RI
828 li r10,MSR_DR|MSR_IR
829 mflr r11 /* return address to SRR0 */
830 mfmsr r12
831 andc r9,r12,r9
832 andc r10,r12,r10
833
834 mtmsrd r9,1
835 mtspr SPRN_SRR1,r10
836 mtspr SPRN_SRR0,r11
837 rfid
838
839
840/*
841 * kexec_sequence(newstack, start, image, control, clear_all())
842 *
843 * does the grungy work with stack switching and real mode switches
844 * also does simple calls to other code
845 */
846
847_GLOBAL(kexec_sequence)
848 mflr r0
849 std r0,16(r1)
850
851 /* switch stacks to newstack -- &kexec_stack.stack */
852 stdu r1,THREAD_SIZE-112(r3)
853 mr r1,r3
854
855 li r0,0
856 std r0,16(r1)
857
858 /* save regs for local vars on new stack.
859 * yes, we won't go back, but ...
860 */
861 std r31,-8(r1)
862 std r30,-16(r1)
863 std r29,-24(r1)
864 std r28,-32(r1)
865 std r27,-40(r1)
866 std r26,-48(r1)
867 std r25,-56(r1)
868
869 stdu r1,-112-64(r1)
870
871 /* save args into preserved regs */
872 mr r31,r3 /* newstack (both) */
873 mr r30,r4 /* start (real) */
874 mr r29,r5 /* image (virt) */
875 mr r28,r6 /* control, unused */
876 mr r27,r7 /* clear_all() fn desc */
877 mr r26,r8 /* spare */
878 lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */
879
880 /* disable interrupts, we are overwriting kernel data next */
881 mfmsr r3
882 rlwinm r3,r3,0,17,15
883 mtmsrd r3,1
884
885 /* copy dest pages, flush whole dest image */
886 mr r3,r29
887 bl .kexec_copy_flush /* (image) */
888
889 /* turn off mmu */
890 bl real_mode
891
892 /* clear out hardware hash page table and tlb */
893 ld r5,0(r27) /* deref function descriptor */
894 mtctr r5
895 bctrl /* ppc_md.hash_clear_all(void); */
896
897/*
898 * kexec image calling is:
899 * the first 0x100 bytes of the entry point are copied to 0
900 *
901 * all slaves branch to slave = 0x60 (absolute)
902 * slave(phys_cpu_id);
903 *
904 * master goes to start = entry point
905 * start(phys_cpu_id, start, 0);
906 *
907 *
908 * a wrapper is needed to call existing kernels, here is an approximate
909 * description of one method:
910 *
911 * v2: (2.6.10)
912 * start will be near the boot_block (maybe 0x100 bytes before it?)
913 * it will have a 0x60, which will b to boot_block, where it will wait
914 * and 0 will store phys into struct boot-block and load r3 from there,
915 * copy kernel 0-0x100 and tell slaves to back down to 0x60 again
916 *
917 * v1: (2.6.9)
918 * boot block will have all cpus scanning device tree to see if they
919 * are the boot cpu ?????
920 * other device tree differences (prop sizes, va vs pa, etc)...
921 */
922
923 /* copy 0x100 bytes starting at start to 0 */
924 li r3,0
925 mr r4,r30
926 li r5,0x100
927 li r6,0
928 bl .copy_and_flush /* (dest, src, copy limit, start offset) */
9291: /* assume normal blr return */
930
931 /* release other cpus to the new kernel secondary start at 0x60 */
932 mflr r5
933 li r6,1
934 stw r6,kexec_flag-1b(5)
935 mr r3,r25 # my phys cpu
936 mr r4,r30 # start, aka phys mem offset
937 mtlr 4
938 li r5,0
939 blr /* image->start(physid, image->start, 0); */
940#endif /* CONFIG_KEXEC */
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
deleted file mode 100644
index 84006e26342c..000000000000
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 * c 2001 PPC 64 Team, IBM Corp
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/config.h>
10#include <linux/module.h>
11#include <linux/string.h>
12#include <linux/console.h>
13#include <net/checksum.h>
14
15#include <asm/processor.h>
16#include <asm/uaccess.h>
17#include <asm/io.h>
18#include <asm/system.h>
19#include <asm/hw_irq.h>
20#include <asm/abs_addr.h>
21#include <asm/cacheflush.h>
22
23EXPORT_SYMBOL(strcpy);
24EXPORT_SYMBOL(strncpy);
25EXPORT_SYMBOL(strcat);
26EXPORT_SYMBOL(strncat);
27EXPORT_SYMBOL(strchr);
28EXPORT_SYMBOL(strrchr);
29EXPORT_SYMBOL(strpbrk);
30EXPORT_SYMBOL(strstr);
31EXPORT_SYMBOL(strlen);
32EXPORT_SYMBOL(strnlen);
33EXPORT_SYMBOL(strcmp);
34EXPORT_SYMBOL(strncmp);
35
36EXPORT_SYMBOL(csum_partial);
37EXPORT_SYMBOL(csum_partial_copy_generic);
38EXPORT_SYMBOL(ip_fast_csum);
39EXPORT_SYMBOL(csum_tcpudp_magic);
40
41EXPORT_SYMBOL(__copy_tofrom_user);
42EXPORT_SYMBOL(__clear_user);
43EXPORT_SYMBOL(__strncpy_from_user);
44EXPORT_SYMBOL(__strnlen_user);
45
46EXPORT_SYMBOL(reloc_offset);
47
48EXPORT_SYMBOL(_insb);
49EXPORT_SYMBOL(_outsb);
50EXPORT_SYMBOL(_insw);
51EXPORT_SYMBOL(_outsw);
52EXPORT_SYMBOL(_insl);
53EXPORT_SYMBOL(_outsl);
54EXPORT_SYMBOL(_insw_ns);
55EXPORT_SYMBOL(_outsw_ns);
56EXPORT_SYMBOL(_insl_ns);
57EXPORT_SYMBOL(_outsl_ns);
58
59EXPORT_SYMBOL(kernel_thread);
60
61EXPORT_SYMBOL(giveup_fpu);
62#ifdef CONFIG_ALTIVEC
63EXPORT_SYMBOL(giveup_altivec);
64#endif
65EXPORT_SYMBOL(__flush_icache_range);
66EXPORT_SYMBOL(flush_dcache_range);
67
68EXPORT_SYMBOL(memcpy);
69EXPORT_SYMBOL(memset);
70EXPORT_SYMBOL(memmove);
71EXPORT_SYMBOL(memscan);
72EXPORT_SYMBOL(memcmp);
73EXPORT_SYMBOL(memchr);
74
75EXPORT_SYMBOL(timer_interrupt);
76EXPORT_SYMBOL(console_drivers);
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
deleted file mode 100644
index fbad2c360784..000000000000
--- a/arch/ppc64/kernel/prom.c
+++ /dev/null
@@ -1,1954 +0,0 @@
1/*
2 *
3 *
4 * Procedures for interfacing to Open Firmware.
5 *
6 * Paul Mackerras August 1996.
7 * Copyright (C) 1996 Paul Mackerras.
8 *
9 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
10 * {engebret|bergner}@us.ibm.com
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#undef DEBUG
19
20#include <stdarg.h>
21#include <linux/config.h>
22#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/threads.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28#include <linux/pci.h>
29#include <linux/stringify.h>
30#include <linux/delay.h>
31#include <linux/initrd.h>
32#include <linux/bitops.h>
33#include <linux/module.h>
34#include <linux/module.h>
35
36#include <asm/prom.h>
37#include <asm/rtas.h>
38#include <asm/lmb.h>
39#include <asm/abs_addr.h>
40#include <asm/page.h>
41#include <asm/processor.h>
42#include <asm/irq.h>
43#include <asm/io.h>
44#include <asm/smp.h>
45#include <asm/system.h>
46#include <asm/mmu.h>
47#include <asm/pgtable.h>
48#include <asm/pci.h>
49#include <asm/iommu.h>
50#include <asm/btext.h>
51#include <asm/sections.h>
52#include <asm/machdep.h>
53#include <asm/pSeries_reconfig.h>
54
55#ifdef DEBUG
56#define DBG(fmt...) udbg_printf(fmt)
57#else
58#define DBG(fmt...)
59#endif
60
61struct pci_reg_property {
62 struct pci_address addr;
63 u32 size_hi;
64 u32 size_lo;
65};
66
67struct isa_reg_property {
68 u32 space;
69 u32 address;
70 u32 size;
71};
72
73
74typedef int interpret_func(struct device_node *, unsigned long *,
75 int, int, int);
76
77extern struct rtas_t rtas;
78extern struct lmb lmb;
79extern unsigned long klimit;
80extern unsigned long memory_limit;
81
82static int __initdata dt_root_addr_cells;
83static int __initdata dt_root_size_cells;
84static int __initdata iommu_is_off;
85int __initdata iommu_force_on;
86unsigned long tce_alloc_start, tce_alloc_end;
87
88typedef u32 cell_t;
89
90#if 0
91static struct boot_param_header *initial_boot_params __initdata;
92#else
93struct boot_param_header *initial_boot_params;
94#endif
95
96static struct device_node *allnodes = NULL;
97
98/* use when traversing tree through the allnext, child, sibling,
99 * or parent members of struct device_node.
100 */
101static DEFINE_RWLOCK(devtree_lock);
102
103/* export that to outside world */
104struct device_node *of_chosen;
105
106/*
107 * Wrapper for allocating memory for various data that needs to be
108 * attached to device nodes as they are processed at boot or when
109 * added to the device tree later (e.g. DLPAR). At boot there is
110 * already a region reserved so we just increment *mem_start by size;
111 * otherwise we call kmalloc.
112 */
113static void * prom_alloc(unsigned long size, unsigned long *mem_start)
114{
115 unsigned long tmp;
116
117 if (!mem_start)
118 return kmalloc(size, GFP_KERNEL);
119
120 tmp = *mem_start;
121 *mem_start += size;
122 return (void *)tmp;
123}
124
125/*
126 * Find the device_node with a given phandle.
127 */
128static struct device_node * find_phandle(phandle ph)
129{
130 struct device_node *np;
131
132 for (np = allnodes; np != 0; np = np->allnext)
133 if (np->linux_phandle == ph)
134 return np;
135 return NULL;
136}
137
138/*
139 * Find the interrupt parent of a node.
140 */
141static struct device_node * __devinit intr_parent(struct device_node *p)
142{
143 phandle *parp;
144
145 parp = (phandle *) get_property(p, "interrupt-parent", NULL);
146 if (parp == NULL)
147 return p->parent;
148 return find_phandle(*parp);
149}
150
151/*
152 * Find out the size of each entry of the interrupts property
153 * for a node.
154 */
155int __devinit prom_n_intr_cells(struct device_node *np)
156{
157 struct device_node *p;
158 unsigned int *icp;
159
160 for (p = np; (p = intr_parent(p)) != NULL; ) {
161 icp = (unsigned int *)
162 get_property(p, "#interrupt-cells", NULL);
163 if (icp != NULL)
164 return *icp;
165 if (get_property(p, "interrupt-controller", NULL) != NULL
166 || get_property(p, "interrupt-map", NULL) != NULL) {
167 printk("oops, node %s doesn't have #interrupt-cells\n",
168 p->full_name);
169 return 1;
170 }
171 }
172#ifdef DEBUG_IRQ
173 printk("prom_n_intr_cells failed for %s\n", np->full_name);
174#endif
175 return 1;
176}
177
178/*
179 * Map an interrupt from a device up to the platform interrupt
180 * descriptor.
181 */
182static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
183 struct device_node *np, unsigned int *ints,
184 int nintrc)
185{
186 struct device_node *p, *ipar;
187 unsigned int *imap, *imask, *ip;
188 int i, imaplen, match;
189 int newintrc = 0, newaddrc = 0;
190 unsigned int *reg;
191 int naddrc;
192
193 reg = (unsigned int *) get_property(np, "reg", NULL);
194 naddrc = prom_n_addr_cells(np);
195 p = intr_parent(np);
196 while (p != NULL) {
197 if (get_property(p, "interrupt-controller", NULL) != NULL)
198 /* this node is an interrupt controller, stop here */
199 break;
200 imap = (unsigned int *)
201 get_property(p, "interrupt-map", &imaplen);
202 if (imap == NULL) {
203 p = intr_parent(p);
204 continue;
205 }
206 imask = (unsigned int *)
207 get_property(p, "interrupt-map-mask", NULL);
208 if (imask == NULL) {
209 printk("oops, %s has interrupt-map but no mask\n",
210 p->full_name);
211 return 0;
212 }
213 imaplen /= sizeof(unsigned int);
214 match = 0;
215 ipar = NULL;
216 while (imaplen > 0 && !match) {
217 /* check the child-interrupt field */
218 match = 1;
219 for (i = 0; i < naddrc && match; ++i)
220 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
221 for (; i < naddrc + nintrc && match; ++i)
222 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
223 imap += naddrc + nintrc;
224 imaplen -= naddrc + nintrc;
225 /* grab the interrupt parent */
226 ipar = find_phandle((phandle) *imap++);
227 --imaplen;
228 if (ipar == NULL) {
229 printk("oops, no int parent %x in map of %s\n",
230 imap[-1], p->full_name);
231 return 0;
232 }
233 /* find the parent's # addr and intr cells */
234 ip = (unsigned int *)
235 get_property(ipar, "#interrupt-cells", NULL);
236 if (ip == NULL) {
237 printk("oops, no #interrupt-cells on %s\n",
238 ipar->full_name);
239 return 0;
240 }
241 newintrc = *ip;
242 ip = (unsigned int *)
243 get_property(ipar, "#address-cells", NULL);
244 newaddrc = (ip == NULL)? 0: *ip;
245 imap += newaddrc + newintrc;
246 imaplen -= newaddrc + newintrc;
247 }
248 if (imaplen < 0) {
249 printk("oops, error decoding int-map on %s, len=%d\n",
250 p->full_name, imaplen);
251 return 0;
252 }
253 if (!match) {
254#ifdef DEBUG_IRQ
255 printk("oops, no match in %s int-map for %s\n",
256 p->full_name, np->full_name);
257#endif
258 return 0;
259 }
260 p = ipar;
261 naddrc = newaddrc;
262 nintrc = newintrc;
263 ints = imap - nintrc;
264 reg = ints - naddrc;
265 }
266 if (p == NULL) {
267#ifdef DEBUG_IRQ
268 printk("hmmm, int tree for %s doesn't have ctrler\n",
269 np->full_name);
270#endif
271 return 0;
272 }
273 *irq = ints;
274 *ictrler = p;
275 return nintrc;
276}
277
278static int __devinit finish_node_interrupts(struct device_node *np,
279 unsigned long *mem_start,
280 int measure_only)
281{
282 unsigned int *ints;
283 int intlen, intrcells, intrcount;
284 int i, j, n;
285 unsigned int *irq, virq;
286 struct device_node *ic;
287
288 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
289 if (ints == NULL)
290 return 0;
291 intrcells = prom_n_intr_cells(np);
292 intlen /= intrcells * sizeof(unsigned int);
293
294 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
295 if (!np->intrs)
296 return -ENOMEM;
297
298 if (measure_only)
299 return 0;
300
301 intrcount = 0;
302 for (i = 0; i < intlen; ++i, ints += intrcells) {
303 n = map_interrupt(&irq, &ic, np, ints, intrcells);
304 if (n <= 0)
305 continue;
306
307 /* don't map IRQ numbers under a cascaded 8259 controller */
308 if (ic && device_is_compatible(ic, "chrp,iic")) {
309 np->intrs[intrcount].line = irq[0];
310 } else {
311 virq = virt_irq_create_mapping(irq[0]);
312 if (virq == NO_IRQ) {
313 printk(KERN_CRIT "Could not allocate interrupt"
314 " number for %s\n", np->full_name);
315 continue;
316 }
317 np->intrs[intrcount].line = irq_offset_up(virq);
318 }
319
320 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
321 if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
322 char *name = get_property(ic->parent, "name", NULL);
323 if (name && !strcmp(name, "u3"))
324 np->intrs[intrcount].line += 128;
325 else if (!(name && !strcmp(name, "mac-io")))
326 /* ignore other cascaded controllers, such as
327 the k2-sata-root */
328 break;
329 }
330 np->intrs[intrcount].sense = 1;
331 if (n > 1)
332 np->intrs[intrcount].sense = irq[1];
333 if (n > 2) {
334 printk("hmmm, got %d intr cells for %s:", n,
335 np->full_name);
336 for (j = 0; j < n; ++j)
337 printk(" %d", irq[j]);
338 printk("\n");
339 }
340 ++intrcount;
341 }
342 np->n_intrs = intrcount;
343
344 return 0;
345}
346
347static int __devinit interpret_pci_props(struct device_node *np,
348 unsigned long *mem_start,
349 int naddrc, int nsizec,
350 int measure_only)
351{
352 struct address_range *adr;
353 struct pci_reg_property *pci_addrs;
354 int i, l, n_addrs;
355
356 pci_addrs = (struct pci_reg_property *)
357 get_property(np, "assigned-addresses", &l);
358 if (!pci_addrs)
359 return 0;
360
361 n_addrs = l / sizeof(*pci_addrs);
362
363 adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
364 if (!adr)
365 return -ENOMEM;
366
367 if (measure_only)
368 return 0;
369
370 np->addrs = adr;
371 np->n_addrs = n_addrs;
372
373 for (i = 0; i < n_addrs; i++) {
374 adr[i].space = pci_addrs[i].addr.a_hi;
375 adr[i].address = pci_addrs[i].addr.a_lo |
376 ((u64)pci_addrs[i].addr.a_mid << 32);
377 adr[i].size = pci_addrs[i].size_lo;
378 }
379
380 return 0;
381}
382
383static int __init interpret_dbdma_props(struct device_node *np,
384 unsigned long *mem_start,
385 int naddrc, int nsizec,
386 int measure_only)
387{
388 struct reg_property32 *rp;
389 struct address_range *adr;
390 unsigned long base_address;
391 int i, l;
392 struct device_node *db;
393
394 base_address = 0;
395 if (!measure_only) {
396 for (db = np->parent; db != NULL; db = db->parent) {
397 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
398 base_address = db->addrs[0].address;
399 break;
400 }
401 }
402 }
403
404 rp = (struct reg_property32 *) get_property(np, "reg", &l);
405 if (rp != 0 && l >= sizeof(struct reg_property32)) {
406 i = 0;
407 adr = (struct address_range *) (*mem_start);
408 while ((l -= sizeof(struct reg_property32)) >= 0) {
409 if (!measure_only) {
410 adr[i].space = 2;
411 adr[i].address = rp[i].address + base_address;
412 adr[i].size = rp[i].size;
413 }
414 ++i;
415 }
416 np->addrs = adr;
417 np->n_addrs = i;
418 (*mem_start) += i * sizeof(struct address_range);
419 }
420
421 return 0;
422}
423
424static int __init interpret_macio_props(struct device_node *np,
425 unsigned long *mem_start,
426 int naddrc, int nsizec,
427 int measure_only)
428{
429 struct reg_property32 *rp;
430 struct address_range *adr;
431 unsigned long base_address;
432 int i, l;
433 struct device_node *db;
434
435 base_address = 0;
436 if (!measure_only) {
437 for (db = np->parent; db != NULL; db = db->parent) {
438 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
439 base_address = db->addrs[0].address;
440 break;
441 }
442 }
443 }
444
445 rp = (struct reg_property32 *) get_property(np, "reg", &l);
446 if (rp != 0 && l >= sizeof(struct reg_property32)) {
447 i = 0;
448 adr = (struct address_range *) (*mem_start);
449 while ((l -= sizeof(struct reg_property32)) >= 0) {
450 if (!measure_only) {
451 adr[i].space = 2;
452 adr[i].address = rp[i].address + base_address;
453 adr[i].size = rp[i].size;
454 }
455 ++i;
456 }
457 np->addrs = adr;
458 np->n_addrs = i;
459 (*mem_start) += i * sizeof(struct address_range);
460 }
461
462 return 0;
463}
464
465static int __init interpret_isa_props(struct device_node *np,
466 unsigned long *mem_start,
467 int naddrc, int nsizec,
468 int measure_only)
469{
470 struct isa_reg_property *rp;
471 struct address_range *adr;
472 int i, l;
473
474 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
475 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
476 i = 0;
477 adr = (struct address_range *) (*mem_start);
478 while ((l -= sizeof(struct isa_reg_property)) >= 0) {
479 if (!measure_only) {
480 adr[i].space = rp[i].space;
481 adr[i].address = rp[i].address;
482 adr[i].size = rp[i].size;
483 }
484 ++i;
485 }
486 np->addrs = adr;
487 np->n_addrs = i;
488 (*mem_start) += i * sizeof(struct address_range);
489 }
490
491 return 0;
492}
493
494static int __init interpret_root_props(struct device_node *np,
495 unsigned long *mem_start,
496 int naddrc, int nsizec,
497 int measure_only)
498{
499 struct address_range *adr;
500 int i, l;
501 unsigned int *rp;
502 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
503
504 rp = (unsigned int *) get_property(np, "reg", &l);
505 if (rp != 0 && l >= rpsize) {
506 i = 0;
507 adr = (struct address_range *) (*mem_start);
508 while ((l -= rpsize) >= 0) {
509 if (!measure_only) {
510 adr[i].space = 0;
511 adr[i].address = rp[naddrc - 1];
512 adr[i].size = rp[naddrc + nsizec - 1];
513 }
514 ++i;
515 rp += naddrc + nsizec;
516 }
517 np->addrs = adr;
518 np->n_addrs = i;
519 (*mem_start) += i * sizeof(struct address_range);
520 }
521
522 return 0;
523}
524
525static int __devinit finish_node(struct device_node *np,
526 unsigned long *mem_start,
527 interpret_func *ifunc,
528 int naddrc, int nsizec,
529 int measure_only)
530{
531 struct device_node *child;
532 int *ip, rc = 0;
533
534 /* get the device addresses and interrupts */
535 if (ifunc != NULL)
536 rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
537 if (rc)
538 goto out;
539
540 rc = finish_node_interrupts(np, mem_start, measure_only);
541 if (rc)
542 goto out;
543
544 /* Look for #address-cells and #size-cells properties. */
545 ip = (int *) get_property(np, "#address-cells", NULL);
546 if (ip != NULL)
547 naddrc = *ip;
548 ip = (int *) get_property(np, "#size-cells", NULL);
549 if (ip != NULL)
550 nsizec = *ip;
551
552 if (!strcmp(np->name, "device-tree") || np->parent == NULL)
553 ifunc = interpret_root_props;
554 else if (np->type == 0)
555 ifunc = NULL;
556 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
557 ifunc = interpret_pci_props;
558 else if (!strcmp(np->type, "dbdma"))
559 ifunc = interpret_dbdma_props;
560 else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
561 ifunc = interpret_macio_props;
562 else if (!strcmp(np->type, "isa"))
563 ifunc = interpret_isa_props;
564 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
565 ifunc = interpret_root_props;
566 else if (!((ifunc == interpret_dbdma_props
567 || ifunc == interpret_macio_props)
568 && (!strcmp(np->type, "escc")
569 || !strcmp(np->type, "media-bay"))))
570 ifunc = NULL;
571
572 for (child = np->child; child != NULL; child = child->sibling) {
573 rc = finish_node(child, mem_start, ifunc,
574 naddrc, nsizec, measure_only);
575 if (rc)
576 goto out;
577 }
578out:
579 return rc;
580}
581
582/**
583 * finish_device_tree is called once things are running normally
584 * (i.e. with text and data mapped to the address they were linked at).
585 * It traverses the device tree and fills in some of the additional,
586 * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
587 * mapping is also initialized at this point.
588 */
589void __init finish_device_tree(void)
590{
591 unsigned long start, end, size = 0;
592
593 DBG(" -> finish_device_tree\n");
594
595 if (ppc64_interrupt_controller == IC_INVALID) {
596 DBG("failed to configure interrupt controller type\n");
597 panic("failed to configure interrupt controller type\n");
598 }
599
600 /* Initialize virtual IRQ map */
601 virt_irq_init();
602
603 /*
604 * Finish device-tree (pre-parsing some properties etc...)
605 * We do this in 2 passes. One with "measure_only" set, which
606 * will only measure the amount of memory needed, then we can
607 * allocate that memory, and call finish_node again. However,
608 * we must be careful as most routines will fail nowadays when
609 * prom_alloc() returns 0, so we must make sure our first pass
610 * doesn't start at 0. We pre-initialize size to 16 for that
611 * reason and then remove those additional 16 bytes
612 */
613 size = 16;
614 finish_node(allnodes, &size, NULL, 0, 0, 1);
615 size -= 16;
616 end = start = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
617 finish_node(allnodes, &end, NULL, 0, 0, 0);
618 BUG_ON(end != start + size);
619
620 DBG(" <- finish_device_tree\n");
621}
622
623#ifdef DEBUG
624#define printk udbg_printf
625#endif
626
627static inline char *find_flat_dt_string(u32 offset)
628{
629 return ((char *)initial_boot_params) +
630 initial_boot_params->off_dt_strings + offset;
631}
632
633/**
634 * This function is used to scan the flattened device-tree, it is
635 * used to extract the memory informations at boot before we can
636 * unflatten the tree
637 */
638int __init of_scan_flat_dt(int (*it)(unsigned long node,
639 const char *uname, int depth,
640 void *data),
641 void *data)
642{
643 unsigned long p = ((unsigned long)initial_boot_params) +
644 initial_boot_params->off_dt_struct;
645 int rc = 0;
646 int depth = -1;
647
648 do {
649 u32 tag = *((u32 *)p);
650 char *pathp;
651
652 p += 4;
653 if (tag == OF_DT_END_NODE) {
654 depth --;
655 continue;
656 }
657 if (tag == OF_DT_NOP)
658 continue;
659 if (tag == OF_DT_END)
660 break;
661 if (tag == OF_DT_PROP) {
662 u32 sz = *((u32 *)p);
663 p += 8;
664 if (initial_boot_params->version < 0x10)
665 p = _ALIGN(p, sz >= 8 ? 8 : 4);
666 p += sz;
667 p = _ALIGN(p, 4);
668 continue;
669 }
670 if (tag != OF_DT_BEGIN_NODE) {
671 printk(KERN_WARNING "Invalid tag %x scanning flattened"
672 " device tree !\n", tag);
673 return -EINVAL;
674 }
675 depth++;
676 pathp = (char *)p;
677 p = _ALIGN(p + strlen(pathp) + 1, 4);
678 if ((*pathp) == '/') {
679 char *lp, *np;
680 for (lp = NULL, np = pathp; *np; np++)
681 if ((*np) == '/')
682 lp = np+1;
683 if (lp != NULL)
684 pathp = lp;
685 }
686 rc = it(p, pathp, depth, data);
687 if (rc != 0)
688 break;
689 } while(1);
690
691 return rc;
692}
693
694/**
695 * This function can be used within scan_flattened_dt callback to get
696 * access to properties
697 */
698void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
699 unsigned long *size)
700{
701 unsigned long p = node;
702
703 do {
704 u32 tag = *((u32 *)p);
705 u32 sz, noff;
706 const char *nstr;
707
708 p += 4;
709 if (tag == OF_DT_NOP)
710 continue;
711 if (tag != OF_DT_PROP)
712 return NULL;
713
714 sz = *((u32 *)p);
715 noff = *((u32 *)(p + 4));
716 p += 8;
717 if (initial_boot_params->version < 0x10)
718 p = _ALIGN(p, sz >= 8 ? 8 : 4);
719
720 nstr = find_flat_dt_string(noff);
721 if (nstr == NULL) {
722 printk(KERN_WARNING "Can't find property index"
723 " name !\n");
724 return NULL;
725 }
726 if (strcmp(name, nstr) == 0) {
727 if (size)
728 *size = sz;
729 return (void *)p;
730 }
731 p += sz;
732 p = _ALIGN(p, 4);
733 } while(1);
734}
735
736static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
737 unsigned long align)
738{
739 void *res;
740
741 *mem = _ALIGN(*mem, align);
742 res = (void *)*mem;
743 *mem += size;
744
745 return res;
746}
747
748static unsigned long __init unflatten_dt_node(unsigned long mem,
749 unsigned long *p,
750 struct device_node *dad,
751 struct device_node ***allnextpp,
752 unsigned long fpsize)
753{
754 struct device_node *np;
755 struct property *pp, **prev_pp = NULL;
756 char *pathp;
757 u32 tag;
758 unsigned int l, allocl;
759 int has_name = 0;
760 int new_format = 0;
761
762 tag = *((u32 *)(*p));
763 if (tag != OF_DT_BEGIN_NODE) {
764 printk("Weird tag at start of node: %x\n", tag);
765 return mem;
766 }
767 *p += 4;
768 pathp = (char *)*p;
769 l = allocl = strlen(pathp) + 1;
770 *p = _ALIGN(*p + l, 4);
771
772 /* version 0x10 has a more compact unit name here instead of the full
773 * path. we accumulate the full path size using "fpsize", we'll rebuild
774 * it later. We detect this because the first character of the name is
775 * not '/'.
776 */
777 if ((*pathp) != '/') {
778 new_format = 1;
779 if (fpsize == 0) {
780 /* root node: special case. fpsize accounts for path
781 * plus terminating zero. root node only has '/', so
782 * fpsize should be 2, but we want to avoid the first
783 * level nodes to have two '/' so we use fpsize 1 here
784 */
785 fpsize = 1;
786 allocl = 2;
787 } else {
788 /* account for '/' and path size minus terminal 0
789 * already in 'l'
790 */
791 fpsize += l;
792 allocl = fpsize;
793 }
794 }
795
796
797 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
798 __alignof__(struct device_node));
799 if (allnextpp) {
800 memset(np, 0, sizeof(*np));
801 np->full_name = ((char*)np) + sizeof(struct device_node);
802 if (new_format) {
803 char *p = np->full_name;
804 /* rebuild full path for new format */
805 if (dad && dad->parent) {
806 strcpy(p, dad->full_name);
807#ifdef DEBUG
808 if ((strlen(p) + l + 1) != allocl) {
809 DBG("%s: p: %d, l: %d, a: %d\n",
810 pathp, strlen(p), l, allocl);
811 }
812#endif
813 p += strlen(p);
814 }
815 *(p++) = '/';
816 memcpy(p, pathp, l);
817 } else
818 memcpy(np->full_name, pathp, l);
819 prev_pp = &np->properties;
820 **allnextpp = np;
821 *allnextpp = &np->allnext;
822 if (dad != NULL) {
823 np->parent = dad;
824 /* we temporarily use the next field as `last_child'*/
825 if (dad->next == 0)
826 dad->child = np;
827 else
828 dad->next->sibling = np;
829 dad->next = np;
830 }
831 kref_init(&np->kref);
832 }
833 while(1) {
834 u32 sz, noff;
835 char *pname;
836
837 tag = *((u32 *)(*p));
838 if (tag == OF_DT_NOP) {
839 *p += 4;
840 continue;
841 }
842 if (tag != OF_DT_PROP)
843 break;
844 *p += 4;
845 sz = *((u32 *)(*p));
846 noff = *((u32 *)((*p) + 4));
847 *p += 8;
848 if (initial_boot_params->version < 0x10)
849 *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
850
851 pname = find_flat_dt_string(noff);
852 if (pname == NULL) {
853 printk("Can't find property name in list !\n");
854 break;
855 }
856 if (strcmp(pname, "name") == 0)
857 has_name = 1;
858 l = strlen(pname) + 1;
859 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
860 __alignof__(struct property));
861 if (allnextpp) {
862 if (strcmp(pname, "linux,phandle") == 0) {
863 np->node = *((u32 *)*p);
864 if (np->linux_phandle == 0)
865 np->linux_phandle = np->node;
866 }
867 if (strcmp(pname, "ibm,phandle") == 0)
868 np->linux_phandle = *((u32 *)*p);
869 pp->name = pname;
870 pp->length = sz;
871 pp->value = (void *)*p;
872 *prev_pp = pp;
873 prev_pp = &pp->next;
874 }
875 *p = _ALIGN((*p) + sz, 4);
876 }
877 /* with version 0x10 we may not have the name property, recreate
878 * it here from the unit name if absent
879 */
880 if (!has_name) {
881 char *p = pathp, *ps = pathp, *pa = NULL;
882 int sz;
883
884 while (*p) {
885 if ((*p) == '@')
886 pa = p;
887 if ((*p) == '/')
888 ps = p + 1;
889 p++;
890 }
891 if (pa < ps)
892 pa = p;
893 sz = (pa - ps) + 1;
894 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
895 __alignof__(struct property));
896 if (allnextpp) {
897 pp->name = "name";
898 pp->length = sz;
899 pp->value = (unsigned char *)(pp + 1);
900 *prev_pp = pp;
901 prev_pp = &pp->next;
902 memcpy(pp->value, ps, sz - 1);
903 ((char *)pp->value)[sz - 1] = 0;
904 DBG("fixed up name for %s -> %s\n", pathp, pp->value);
905 }
906 }
907 if (allnextpp) {
908 *prev_pp = NULL;
909 np->name = get_property(np, "name", NULL);
910 np->type = get_property(np, "device_type", NULL);
911
912 if (!np->name)
913 np->name = "<NULL>";
914 if (!np->type)
915 np->type = "<NULL>";
916 }
917 while (tag == OF_DT_BEGIN_NODE) {
918 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
919 tag = *((u32 *)(*p));
920 }
921 if (tag != OF_DT_END_NODE) {
922 printk("Weird tag at end of node: %x\n", tag);
923 return mem;
924 }
925 *p += 4;
926 return mem;
927}
928
929
930/**
931 * unflattens the device-tree passed by the firmware, creating the
932 * tree of struct device_node. It also fills the "name" and "type"
933 * pointers of the nodes so the normal device-tree walking functions
934 * can be used (this used to be done by finish_device_tree)
935 */
936void __init unflatten_device_tree(void)
937{
938 unsigned long start, mem, size;
939 struct device_node **allnextp = &allnodes;
940 char *p = NULL;
941 int l = 0;
942
943 DBG(" -> unflatten_device_tree()\n");
944
945 /* First pass, scan for size */
946 start = ((unsigned long)initial_boot_params) +
947 initial_boot_params->off_dt_struct;
948 size = unflatten_dt_node(0, &start, NULL, NULL, 0);
949 size = (size | 3) + 1;
950
951 DBG(" size is %lx, allocating...\n", size);
952
953 /* Allocate memory for the expanded device tree */
954 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
955 if (!mem) {
956 DBG("Couldn't allocate memory with lmb_alloc()!\n");
957 panic("Couldn't allocate memory with lmb_alloc()!\n");
958 }
959 mem = (unsigned long)abs_to_virt(mem);
960
961 ((u32 *)mem)[size / 4] = 0xdeadbeef;
962
963 DBG(" unflattening...\n", mem);
964
965 /* Second pass, do actual unflattening */
966 start = ((unsigned long)initial_boot_params) +
967 initial_boot_params->off_dt_struct;
968 unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
969 if (*((u32 *)start) != OF_DT_END)
970 printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
971 if (((u32 *)mem)[size / 4] != 0xdeadbeef)
972 printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
973 ((u32 *)mem)[size / 4] );
974 *allnextp = NULL;
975
976 /* Get pointer to OF "/chosen" node for use everywhere */
977 of_chosen = of_find_node_by_path("/chosen");
978
979 /* Retreive command line */
980 if (of_chosen != NULL) {
981 p = (char *)get_property(of_chosen, "bootargs", &l);
982 if (p != NULL && l > 0)
983 strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
984 }
985#ifdef CONFIG_CMDLINE
986 if (l == 0 || (l == 1 && (*p) == 0))
987 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
988#endif /* CONFIG_CMDLINE */
989
990 DBG("Command line is: %s\n", cmd_line);
991
992 DBG(" <- unflatten_device_tree()\n");
993}
994
995
996static int __init early_init_dt_scan_cpus(unsigned long node,
997 const char *uname, int depth, void *data)
998{
999 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
1000 u32 *prop;
1001 unsigned long size;
1002
1003 /* We are scanning "cpu" nodes only */
1004 if (type == NULL || strcmp(type, "cpu") != 0)
1005 return 0;
1006
1007 if (initial_boot_params && initial_boot_params->version >= 2) {
1008 /* version 2 of the kexec param format adds the phys cpuid
1009 * of booted proc.
1010 */
1011 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
1012 boot_cpuid = 0;
1013 } else {
1014 /* Check if it's the boot-cpu, set it's hw index in paca now */
1015 if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL)
1016 != NULL) {
1017 u32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
1018 set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
1019 boot_cpuid_phys = get_hard_smp_processor_id(0);
1020 }
1021 }
1022
1023#ifdef CONFIG_ALTIVEC
1024 /* Check if we have a VMX and eventually update CPU features */
1025 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
1026 if (prop && (*prop) > 0) {
1027 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
1028 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
1029 }
1030
1031 /* Same goes for Apple's "altivec" property */
1032 prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL);
1033 if (prop) {
1034 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
1035 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
1036 }
1037#endif /* CONFIG_ALTIVEC */
1038
1039 /*
1040 * Check for an SMT capable CPU and set the CPU feature. We do
1041 * this by looking at the size of the ibm,ppc-interrupt-server#s
1042 * property
1043 */
1044 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
1045 &size);
1046 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
1047 if (prop && ((size / sizeof(u32)) > 1))
1048 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
1049
1050 return 0;
1051}
1052
1053static int __init early_init_dt_scan_chosen(unsigned long node,
1054 const char *uname, int depth, void *data)
1055{
1056 u32 *prop;
1057 u64 *prop64;
1058
1059 DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
1060
1061 if (depth != 1 || strcmp(uname, "chosen") != 0)
1062 return 0;
1063
1064 /* get platform type */
1065 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
1066 if (prop == NULL)
1067 return 0;
1068 _machine = *prop;
1069
1070 /* check if iommu is forced on or off */
1071 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
1072 iommu_is_off = 1;
1073 if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
1074 iommu_force_on = 1;
1075
1076 prop64 = (u64*)of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
1077 if (prop64)
1078 memory_limit = *prop64;
1079
1080 prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-start",NULL);
1081 if (prop64)
1082 tce_alloc_start = *prop64;
1083
1084 prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
1085 if (prop64)
1086 tce_alloc_end = *prop64;
1087
1088#ifdef CONFIG_PPC_RTAS
1089 /* To help early debugging via the front panel, we retreive a minimal
1090 * set of RTAS infos now if available
1091 */
1092 {
1093 u64 *basep, *entryp;
1094
1095 basep = (u64*)of_get_flat_dt_prop(node,
1096 "linux,rtas-base", NULL);
1097 entryp = (u64*)of_get_flat_dt_prop(node,
1098 "linux,rtas-entry", NULL);
1099 prop = (u32*)of_get_flat_dt_prop(node,
1100 "linux,rtas-size", NULL);
1101 if (basep && entryp && prop) {
1102 rtas.base = *basep;
1103 rtas.entry = *entryp;
1104 rtas.size = *prop;
1105 }
1106 }
1107#endif /* CONFIG_PPC_RTAS */
1108
1109 /* break now */
1110 return 1;
1111}
1112
1113static int __init early_init_dt_scan_root(unsigned long node,
1114 const char *uname, int depth, void *data)
1115{
1116 u32 *prop;
1117
1118 if (depth != 0)
1119 return 0;
1120
1121 prop = (u32 *)of_get_flat_dt_prop(node, "#size-cells", NULL);
1122 dt_root_size_cells = (prop == NULL) ? 1 : *prop;
1123 DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
1124
1125 prop = (u32 *)of_get_flat_dt_prop(node, "#address-cells", NULL);
1126 dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
1127 DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
1128
1129 /* break now */
1130 return 1;
1131}
1132
1133static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
1134{
1135 cell_t *p = *cellp;
1136 unsigned long r = 0;
1137
1138 /* Ignore more than 2 cells */
1139 while (s > 2) {
1140 p++;
1141 s--;
1142 }
1143 while (s) {
1144 r <<= 32;
1145 r |= *(p++);
1146 s--;
1147 }
1148
1149 *cellp = p;
1150 return r;
1151}
1152
1153
1154static int __init early_init_dt_scan_memory(unsigned long node,
1155 const char *uname, int depth, void *data)
1156{
1157 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
1158 cell_t *reg, *endp;
1159 unsigned long l;
1160
1161 /* We are scanning "memory" nodes only */
1162 if (type == NULL || strcmp(type, "memory") != 0)
1163 return 0;
1164
1165 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
1166 if (reg == NULL)
1167 return 0;
1168
1169 endp = reg + (l / sizeof(cell_t));
1170
1171 DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
1172 uname, l, reg[0], reg[1], reg[2], reg[3]);
1173
1174 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
1175 unsigned long base, size;
1176
1177 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
1178 size = dt_mem_next_cell(dt_root_size_cells, &reg);
1179
1180 if (size == 0)
1181 continue;
1182 DBG(" - %lx , %lx\n", base, size);
1183 if (iommu_is_off) {
1184 if (base >= 0x80000000ul)
1185 continue;
1186 if ((base + size) > 0x80000000ul)
1187 size = 0x80000000ul - base;
1188 }
1189 lmb_add(base, size);
1190 }
1191 return 0;
1192}
1193
1194static void __init early_reserve_mem(void)
1195{
1196 u64 base, size;
1197 u64 *reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
1198 initial_boot_params->off_mem_rsvmap);
1199 while (1) {
1200 base = *(reserve_map++);
1201 size = *(reserve_map++);
1202 if (size == 0)
1203 break;
1204 DBG("reserving: %lx -> %lx\n", base, size);
1205 lmb_reserve(base, size);
1206 }
1207
1208#if 0
1209 DBG("memory reserved, lmbs :\n");
1210 lmb_dump_all();
1211#endif
1212}
1213
1214void __init early_init_devtree(void *params)
1215{
1216 DBG(" -> early_init_devtree()\n");
1217
1218 /* Setup flat device-tree pointer */
1219 initial_boot_params = params;
1220
1221 /* Retreive various informations from the /chosen node of the
1222 * device-tree, including the platform type, initrd location and
1223 * size, TCE reserve, and more ...
1224 */
1225 of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
1226
1227 /* Scan memory nodes and rebuild LMBs */
1228 lmb_init();
1229 of_scan_flat_dt(early_init_dt_scan_root, NULL);
1230 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1231 lmb_enforce_memory_limit(memory_limit);
1232 lmb_analyze();
1233 lmb_reserve(0, __pa(klimit));
1234
1235 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1236 early_reserve_mem();
1237
1238 DBG("Scanning CPUs ...\n");
1239
1240 /* Retreive hash table size from flattened tree plus other
1241 * CPU related informations (altivec support, boot CPU ID, ...)
1242 */
1243 of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
1244
1245 DBG(" <- early_init_devtree()\n");
1246}
1247
1248#undef printk
1249
1250int
1251prom_n_addr_cells(struct device_node* np)
1252{
1253 int* ip;
1254 do {
1255 if (np->parent)
1256 np = np->parent;
1257 ip = (int *) get_property(np, "#address-cells", NULL);
1258 if (ip != NULL)
1259 return *ip;
1260 } while (np->parent);
1261 /* No #address-cells property for the root node, default to 1 */
1262 return 1;
1263}
1264
1265int
1266prom_n_size_cells(struct device_node* np)
1267{
1268 int* ip;
1269 do {
1270 if (np->parent)
1271 np = np->parent;
1272 ip = (int *) get_property(np, "#size-cells", NULL);
1273 if (ip != NULL)
1274 return *ip;
1275 } while (np->parent);
1276 /* No #size-cells property for the root node, default to 1 */
1277 return 1;
1278}
1279
1280/**
1281 * Work out the sense (active-low level / active-high edge)
1282 * of each interrupt from the device tree.
1283 */
1284void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
1285{
1286 struct device_node *np;
1287 int i, j;
1288
1289 /* default to level-triggered */
1290 memset(senses, 1, max - off);
1291
1292 for (np = allnodes; np != 0; np = np->allnext) {
1293 for (j = 0; j < np->n_intrs; j++) {
1294 i = np->intrs[j].line;
1295 if (i >= off && i < max)
1296 senses[i-off] = np->intrs[j].sense ?
1297 IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE :
1298 IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
1299 }
1300 }
1301}
1302
1303/**
1304 * Construct and return a list of the device_nodes with a given name.
1305 */
1306struct device_node *
1307find_devices(const char *name)
1308{
1309 struct device_node *head, **prevp, *np;
1310
1311 prevp = &head;
1312 for (np = allnodes; np != 0; np = np->allnext) {
1313 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1314 *prevp = np;
1315 prevp = &np->next;
1316 }
1317 }
1318 *prevp = NULL;
1319 return head;
1320}
1321EXPORT_SYMBOL(find_devices);
1322
1323/**
1324 * Construct and return a list of the device_nodes with a given type.
1325 */
1326struct device_node *
1327find_type_devices(const char *type)
1328{
1329 struct device_node *head, **prevp, *np;
1330
1331 prevp = &head;
1332 for (np = allnodes; np != 0; np = np->allnext) {
1333 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1334 *prevp = np;
1335 prevp = &np->next;
1336 }
1337 }
1338 *prevp = NULL;
1339 return head;
1340}
1341EXPORT_SYMBOL(find_type_devices);
1342
1343/**
1344 * Returns all nodes linked together
1345 */
1346struct device_node *
1347find_all_nodes(void)
1348{
1349 struct device_node *head, **prevp, *np;
1350
1351 prevp = &head;
1352 for (np = allnodes; np != 0; np = np->allnext) {
1353 *prevp = np;
1354 prevp = &np->next;
1355 }
1356 *prevp = NULL;
1357 return head;
1358}
1359EXPORT_SYMBOL(find_all_nodes);
1360
1361/** Checks if the given "compat" string matches one of the strings in
1362 * the device's "compatible" property
1363 */
1364int
1365device_is_compatible(struct device_node *device, const char *compat)
1366{
1367 const char* cp;
1368 int cplen, l;
1369
1370 cp = (char *) get_property(device, "compatible", &cplen);
1371 if (cp == NULL)
1372 return 0;
1373 while (cplen > 0) {
1374 if (strncasecmp(cp, compat, strlen(compat)) == 0)
1375 return 1;
1376 l = strlen(cp) + 1;
1377 cp += l;
1378 cplen -= l;
1379 }
1380
1381 return 0;
1382}
1383EXPORT_SYMBOL(device_is_compatible);
1384
1385
1386/**
1387 * Indicates whether the root node has a given value in its
1388 * compatible property.
1389 */
1390int
1391machine_is_compatible(const char *compat)
1392{
1393 struct device_node *root;
1394 int rc = 0;
1395
1396 root = of_find_node_by_path("/");
1397 if (root) {
1398 rc = device_is_compatible(root, compat);
1399 of_node_put(root);
1400 }
1401 return rc;
1402}
1403EXPORT_SYMBOL(machine_is_compatible);
1404
1405/**
1406 * Construct and return a list of the device_nodes with a given type
1407 * and compatible property.
1408 */
1409struct device_node *
1410find_compatible_devices(const char *type, const char *compat)
1411{
1412 struct device_node *head, **prevp, *np;
1413
1414 prevp = &head;
1415 for (np = allnodes; np != 0; np = np->allnext) {
1416 if (type != NULL
1417 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1418 continue;
1419 if (device_is_compatible(np, compat)) {
1420 *prevp = np;
1421 prevp = &np->next;
1422 }
1423 }
1424 *prevp = NULL;
1425 return head;
1426}
1427EXPORT_SYMBOL(find_compatible_devices);
1428
1429/**
1430 * Find the device_node with a given full_name.
1431 */
1432struct device_node *
1433find_path_device(const char *path)
1434{
1435 struct device_node *np;
1436
1437 for (np = allnodes; np != 0; np = np->allnext)
1438 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1439 return np;
1440 return NULL;
1441}
1442EXPORT_SYMBOL(find_path_device);
1443
1444/*******
1445 *
1446 * New implementation of the OF "find" APIs, return a refcounted
1447 * object, call of_node_put() when done. The device tree and list
1448 * are protected by a rw_lock.
1449 *
1450 * Note that property management will need some locking as well,
1451 * this isn't dealt with yet.
1452 *
1453 *******/
1454
1455/**
1456 * of_find_node_by_name - Find a node by its "name" property
1457 * @from: The node to start searching from or NULL, the node
1458 * you pass will not be searched, only the next one
1459 * will; typically, you pass what the previous call
1460 * returned. of_node_put() will be called on it
1461 * @name: The name string to match against
1462 *
1463 * Returns a node pointer with refcount incremented, use
1464 * of_node_put() on it when done.
1465 */
1466struct device_node *of_find_node_by_name(struct device_node *from,
1467 const char *name)
1468{
1469 struct device_node *np;
1470
1471 read_lock(&devtree_lock);
1472 np = from ? from->allnext : allnodes;
1473 for (; np != 0; np = np->allnext)
1474 if (np->name != 0 && strcasecmp(np->name, name) == 0
1475 && of_node_get(np))
1476 break;
1477 if (from)
1478 of_node_put(from);
1479 read_unlock(&devtree_lock);
1480 return np;
1481}
1482EXPORT_SYMBOL(of_find_node_by_name);
1483
1484/**
1485 * of_find_node_by_type - Find a node by its "device_type" property
1486 * @from: The node to start searching from or NULL, the node
1487 * you pass will not be searched, only the next one
1488 * will; typically, you pass what the previous call
1489 * returned. of_node_put() will be called on it
1490 * @name: The type string to match against
1491 *
1492 * Returns a node pointer with refcount incremented, use
1493 * of_node_put() on it when done.
1494 */
1495struct device_node *of_find_node_by_type(struct device_node *from,
1496 const char *type)
1497{
1498 struct device_node *np;
1499
1500 read_lock(&devtree_lock);
1501 np = from ? from->allnext : allnodes;
1502 for (; np != 0; np = np->allnext)
1503 if (np->type != 0 && strcasecmp(np->type, type) == 0
1504 && of_node_get(np))
1505 break;
1506 if (from)
1507 of_node_put(from);
1508 read_unlock(&devtree_lock);
1509 return np;
1510}
1511EXPORT_SYMBOL(of_find_node_by_type);
1512
1513/**
1514 * of_find_compatible_node - Find a node based on type and one of the
1515 * tokens in its "compatible" property
1516 * @from: The node to start searching from or NULL, the node
1517 * you pass will not be searched, only the next one
1518 * will; typically, you pass what the previous call
1519 * returned. of_node_put() will be called on it
1520 * @type: The type string to match "device_type" or NULL to ignore
1521 * @compatible: The string to match to one of the tokens in the device
1522 * "compatible" list.
1523 *
1524 * Returns a node pointer with refcount incremented, use
1525 * of_node_put() on it when done.
1526 */
1527struct device_node *of_find_compatible_node(struct device_node *from,
1528 const char *type, const char *compatible)
1529{
1530 struct device_node *np;
1531
1532 read_lock(&devtree_lock);
1533 np = from ? from->allnext : allnodes;
1534 for (; np != 0; np = np->allnext) {
1535 if (type != NULL
1536 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1537 continue;
1538 if (device_is_compatible(np, compatible) && of_node_get(np))
1539 break;
1540 }
1541 if (from)
1542 of_node_put(from);
1543 read_unlock(&devtree_lock);
1544 return np;
1545}
1546EXPORT_SYMBOL(of_find_compatible_node);
1547
1548/**
1549 * of_find_node_by_path - Find a node matching a full OF path
1550 * @path: The full path to match
1551 *
1552 * Returns a node pointer with refcount incremented, use
1553 * of_node_put() on it when done.
1554 */
1555struct device_node *of_find_node_by_path(const char *path)
1556{
1557 struct device_node *np = allnodes;
1558
1559 read_lock(&devtree_lock);
1560 for (; np != 0; np = np->allnext) {
1561 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1562 && of_node_get(np))
1563 break;
1564 }
1565 read_unlock(&devtree_lock);
1566 return np;
1567}
1568EXPORT_SYMBOL(of_find_node_by_path);
1569
1570/**
1571 * of_find_node_by_phandle - Find a node given a phandle
1572 * @handle: phandle of the node to find
1573 *
1574 * Returns a node pointer with refcount incremented, use
1575 * of_node_put() on it when done.
1576 */
1577struct device_node *of_find_node_by_phandle(phandle handle)
1578{
1579 struct device_node *np;
1580
1581 read_lock(&devtree_lock);
1582 for (np = allnodes; np != 0; np = np->allnext)
1583 if (np->linux_phandle == handle)
1584 break;
1585 if (np)
1586 of_node_get(np);
1587 read_unlock(&devtree_lock);
1588 return np;
1589}
1590EXPORT_SYMBOL(of_find_node_by_phandle);
1591
1592/**
1593 * of_find_all_nodes - Get next node in global list
1594 * @prev: Previous node or NULL to start iteration
1595 * of_node_put() will be called on it
1596 *
1597 * Returns a node pointer with refcount incremented, use
1598 * of_node_put() on it when done.
1599 */
1600struct device_node *of_find_all_nodes(struct device_node *prev)
1601{
1602 struct device_node *np;
1603
1604 read_lock(&devtree_lock);
1605 np = prev ? prev->allnext : allnodes;
1606 for (; np != 0; np = np->allnext)
1607 if (of_node_get(np))
1608 break;
1609 if (prev)
1610 of_node_put(prev);
1611 read_unlock(&devtree_lock);
1612 return np;
1613}
1614EXPORT_SYMBOL(of_find_all_nodes);
1615
1616/**
1617 * of_get_parent - Get a node's parent if any
1618 * @node: Node to get parent
1619 *
1620 * Returns a node pointer with refcount incremented, use
1621 * of_node_put() on it when done.
1622 */
1623struct device_node *of_get_parent(const struct device_node *node)
1624{
1625 struct device_node *np;
1626
1627 if (!node)
1628 return NULL;
1629
1630 read_lock(&devtree_lock);
1631 np = of_node_get(node->parent);
1632 read_unlock(&devtree_lock);
1633 return np;
1634}
1635EXPORT_SYMBOL(of_get_parent);
1636
1637/**
1638 * of_get_next_child - Iterate a node childs
1639 * @node: parent node
1640 * @prev: previous child of the parent node, or NULL to get first
1641 *
1642 * Returns a node pointer with refcount incremented, use
1643 * of_node_put() on it when done.
1644 */
1645struct device_node *of_get_next_child(const struct device_node *node,
1646 struct device_node *prev)
1647{
1648 struct device_node *next;
1649
1650 read_lock(&devtree_lock);
1651 next = prev ? prev->sibling : node->child;
1652 for (; next != 0; next = next->sibling)
1653 if (of_node_get(next))
1654 break;
1655 if (prev)
1656 of_node_put(prev);
1657 read_unlock(&devtree_lock);
1658 return next;
1659}
1660EXPORT_SYMBOL(of_get_next_child);
1661
1662/**
1663 * of_node_get - Increment refcount of a node
1664 * @node: Node to inc refcount, NULL is supported to
1665 * simplify writing of callers
1666 *
1667 * Returns node.
1668 */
1669struct device_node *of_node_get(struct device_node *node)
1670{
1671 if (node)
1672 kref_get(&node->kref);
1673 return node;
1674}
1675EXPORT_SYMBOL(of_node_get);
1676
1677static inline struct device_node * kref_to_device_node(struct kref *kref)
1678{
1679 return container_of(kref, struct device_node, kref);
1680}
1681
1682/**
1683 * of_node_release - release a dynamically allocated node
1684 * @kref: kref element of the node to be released
1685 *
1686 * In of_node_put() this function is passed to kref_put()
1687 * as the destructor.
1688 */
1689static void of_node_release(struct kref *kref)
1690{
1691 struct device_node *node = kref_to_device_node(kref);
1692 struct property *prop = node->properties;
1693
1694 if (!OF_IS_DYNAMIC(node))
1695 return;
1696 while (prop) {
1697 struct property *next = prop->next;
1698 kfree(prop->name);
1699 kfree(prop->value);
1700 kfree(prop);
1701 prop = next;
1702 }
1703 kfree(node->intrs);
1704 kfree(node->addrs);
1705 kfree(node->full_name);
1706 kfree(node->data);
1707 kfree(node);
1708}
1709
1710/**
1711 * of_node_put - Decrement refcount of a node
1712 * @node: Node to dec refcount, NULL is supported to
1713 * simplify writing of callers
1714 *
1715 */
1716void of_node_put(struct device_node *node)
1717{
1718 if (node)
1719 kref_put(&node->kref, of_node_release);
1720}
1721EXPORT_SYMBOL(of_node_put);
1722
1723/*
1724 * Fix up the uninitialized fields in a new device node:
1725 * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
1726 *
1727 * A lot of boot-time code is duplicated here, because functions such
1728 * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
1729 * slab allocator.
1730 *
1731 * This should probably be split up into smaller chunks.
1732 */
1733
1734static int of_finish_dynamic_node(struct device_node *node,
1735 unsigned long *unused1, int unused2,
1736 int unused3, int unused4)
1737{
1738 struct device_node *parent = of_get_parent(node);
1739 int err = 0;
1740 phandle *ibm_phandle;
1741
1742 node->name = get_property(node, "name", NULL);
1743 node->type = get_property(node, "device_type", NULL);
1744
1745 if (!parent) {
1746 err = -ENODEV;
1747 goto out;
1748 }
1749
1750 /* We don't support that function on PowerMac, at least
1751 * not yet
1752 */
1753 if (_machine == PLATFORM_POWERMAC)
1754 return -ENODEV;
1755
1756 /* fix up new node's linux_phandle field */
1757 if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
1758 node->linux_phandle = *ibm_phandle;
1759
1760out:
1761 of_node_put(parent);
1762 return err;
1763}
1764
1765/*
1766 * Plug a device node into the tree and global list.
1767 */
1768void of_attach_node(struct device_node *np)
1769{
1770 write_lock(&devtree_lock);
1771 np->sibling = np->parent->child;
1772 np->allnext = allnodes;
1773 np->parent->child = np;
1774 allnodes = np;
1775 write_unlock(&devtree_lock);
1776}
1777
1778/*
1779 * "Unplug" a node from the device tree. The caller must hold
1780 * a reference to the node. The memory associated with the node
1781 * is not freed until its refcount goes to zero.
1782 */
1783void of_detach_node(const struct device_node *np)
1784{
1785 struct device_node *parent;
1786
1787 write_lock(&devtree_lock);
1788
1789 parent = np->parent;
1790
1791 if (allnodes == np)
1792 allnodes = np->allnext;
1793 else {
1794 struct device_node *prev;
1795 for (prev = allnodes;
1796 prev->allnext != np;
1797 prev = prev->allnext)
1798 ;
1799 prev->allnext = np->allnext;
1800 }
1801
1802 if (parent->child == np)
1803 parent->child = np->sibling;
1804 else {
1805 struct device_node *prevsib;
1806 for (prevsib = np->parent->child;
1807 prevsib->sibling != np;
1808 prevsib = prevsib->sibling)
1809 ;
1810 prevsib->sibling = np->sibling;
1811 }
1812
1813 write_unlock(&devtree_lock);
1814}
1815
1816static int prom_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
1817{
1818 int err;
1819
1820 switch (action) {
1821 case PSERIES_RECONFIG_ADD:
1822 err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
1823 if (err < 0) {
1824 printk(KERN_ERR "finish_node returned %d\n", err);
1825 err = NOTIFY_BAD;
1826 }
1827 break;
1828 default:
1829 err = NOTIFY_DONE;
1830 break;
1831 }
1832 return err;
1833}
1834
1835static struct notifier_block prom_reconfig_nb = {
1836 .notifier_call = prom_reconfig_notifier,
1837 .priority = 10, /* This one needs to run first */
1838};
1839
1840static int __init prom_reconfig_setup(void)
1841{
1842 return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
1843}
1844__initcall(prom_reconfig_setup);
1845
1846/*
1847 * Find a property with a given name for a given node
1848 * and return the value.
1849 */
1850unsigned char *
1851get_property(struct device_node *np, const char *name, int *lenp)
1852{
1853 struct property *pp;
1854
1855 for (pp = np->properties; pp != 0; pp = pp->next)
1856 if (strcmp(pp->name, name) == 0) {
1857 if (lenp != 0)
1858 *lenp = pp->length;
1859 return pp->value;
1860 }
1861 return NULL;
1862}
1863EXPORT_SYMBOL(get_property);
1864
1865/*
1866 * Add a property to a node.
1867 */
1868int
1869prom_add_property(struct device_node* np, struct property* prop)
1870{
1871 struct property **next;
1872
1873 prop->next = NULL;
1874 write_lock(&devtree_lock);
1875 next = &np->properties;
1876 while (*next) {
1877 if (strcmp(prop->name, (*next)->name) == 0) {
1878 /* duplicate ! don't insert it */
1879 write_unlock(&devtree_lock);
1880 return -1;
1881 }
1882 next = &(*next)->next;
1883 }
1884 *next = prop;
1885 write_unlock(&devtree_lock);
1886
1887 /* try to add to proc as well if it was initialized */
1888 if (np->pde)
1889 proc_device_tree_add_prop(np->pde, prop);
1890
1891 return 0;
1892}
1893
1894#if 0
1895void
1896print_properties(struct device_node *np)
1897{
1898 struct property *pp;
1899 char *cp;
1900 int i, n;
1901
1902 for (pp = np->properties; pp != 0; pp = pp->next) {
1903 printk(KERN_INFO "%s", pp->name);
1904 for (i = strlen(pp->name); i < 16; ++i)
1905 printk(" ");
1906 cp = (char *) pp->value;
1907 for (i = pp->length; i > 0; --i, ++cp)
1908 if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
1909 || (i == 1 && *cp != 0))
1910 break;
1911 if (i == 0 && pp->length > 1) {
1912 /* looks like a string */
1913 printk(" %s\n", (char *) pp->value);
1914 } else {
1915 /* dump it in hex */
1916 n = pp->length;
1917 if (n > 64)
1918 n = 64;
1919 if (pp->length % 4 == 0) {
1920 unsigned int *p = (unsigned int *) pp->value;
1921
1922 n /= 4;
1923 for (i = 0; i < n; ++i) {
1924 if (i != 0 && (i % 4) == 0)
1925 printk("\n ");
1926 printk(" %08x", *p++);
1927 }
1928 } else {
1929 unsigned char *bp = pp->value;
1930
1931 for (i = 0; i < n; ++i) {
1932 if (i != 0 && (i % 16) == 0)
1933 printk("\n ");
1934 printk(" %02x", *bp++);
1935 }
1936 }
1937 printk("\n");
1938 if (pp->length > 64)
1939 printk(" ... (length = %d)\n",
1940 pp->length);
1941 }
1942 }
1943}
1944#endif
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
deleted file mode 100644
index 6375f40b23db..000000000000
--- a/arch/ppc64/kernel/prom_init.c
+++ /dev/null
@@ -1,2051 +0,0 @@
1/*
2 *
3 *
4 * Procedures for interfacing to Open Firmware.
5 *
6 * Paul Mackerras August 1996.
7 * Copyright (C) 1996 Paul Mackerras.
8 *
9 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
10 * {engebret|bergner}@us.ibm.com
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#undef DEBUG_PROM
19
20#include <stdarg.h>
21#include <linux/config.h>
22#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/threads.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28#include <linux/pci.h>
29#include <linux/proc_fs.h>
30#include <linux/stringify.h>
31#include <linux/delay.h>
32#include <linux/initrd.h>
33#include <linux/bitops.h>
34#include <asm/prom.h>
35#include <asm/rtas.h>
36#include <asm/abs_addr.h>
37#include <asm/page.h>
38#include <asm/processor.h>
39#include <asm/irq.h>
40#include <asm/io.h>
41#include <asm/smp.h>
42#include <asm/system.h>
43#include <asm/mmu.h>
44#include <asm/pgtable.h>
45#include <asm/pci.h>
46#include <asm/iommu.h>
47#include <asm/btext.h>
48#include <asm/sections.h>
49#include <asm/machdep.h>
50
51#ifdef CONFIG_LOGO_LINUX_CLUT224
52#include <linux/linux_logo.h>
53extern const struct linux_logo logo_linux_clut224;
54#endif
55
56/*
57 * Properties whose value is longer than this get excluded from our
58 * copy of the device tree. This value does need to be big enough to
59 * ensure that we don't lose things like the interrupt-map property
60 * on a PCI-PCI bridge.
61 */
62#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
63
64/*
65 * Eventually bump that one up
66 */
67#define DEVTREE_CHUNK_SIZE 0x100000
68
69/*
70 * This is the size of the local memory reserve map that gets copied
71 * into the boot params passed to the kernel. That size is totally
72 * flexible as the kernel just reads the list until it encounters an
73 * entry with size 0, so it can be changed without breaking binary
74 * compatibility
75 */
76#define MEM_RESERVE_MAP_SIZE 8
77
78/*
79 * prom_init() is called very early on, before the kernel text
80 * and data have been mapped to KERNELBASE. At this point the code
81 * is running at whatever address it has been loaded at, so
82 * references to extern and static variables must be relocated
83 * explicitly. The procedure reloc_offset() returns the address
84 * we're currently running at minus the address we were linked at.
85 * (Note that strings count as static variables.)
86 *
87 * Because OF may have mapped I/O devices into the area starting at
88 * KERNELBASE, particularly on CHRP machines, we can't safely call
89 * OF once the kernel has been mapped to KERNELBASE. Therefore all
90 * OF calls should be done within prom_init(), and prom_init()
91 * and all routines called within it must be careful to relocate
92 * references as necessary.
93 *
94 * Note that the bss is cleared *after* prom_init runs, so we have
95 * to make sure that any static or extern variables it accesses
96 * are put in the data segment.
97 */
98
99
100#define PROM_BUG() do { \
101 prom_printf("kernel BUG at %s line 0x%x!\n", \
102 RELOC(__FILE__), __LINE__); \
103 __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
104} while (0)
105
106#ifdef DEBUG_PROM
107#define prom_debug(x...) prom_printf(x)
108#else
109#define prom_debug(x...)
110#endif
111
112
113typedef u32 prom_arg_t;
114
115struct prom_args {
116 u32 service;
117 u32 nargs;
118 u32 nret;
119 prom_arg_t args[10];
120 prom_arg_t *rets; /* Pointer to return values in args[16]. */
121};
122
123struct prom_t {
124 unsigned long entry;
125 ihandle root;
126 ihandle chosen;
127 int cpu;
128 ihandle stdout;
129 ihandle disp_node;
130 struct prom_args args;
131 unsigned long version;
132 unsigned long root_size_cells;
133 unsigned long root_addr_cells;
134};
135
136struct pci_reg_property {
137 struct pci_address addr;
138 u32 size_hi;
139 u32 size_lo;
140};
141
142struct mem_map_entry {
143 u64 base;
144 u64 size;
145};
146
147typedef u32 cell_t;
148
149extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
150
151extern void enter_prom(struct prom_args *args, unsigned long entry);
152extern void copy_and_flush(unsigned long dest, unsigned long src,
153 unsigned long size, unsigned long offset);
154
155extern unsigned long klimit;
156
157/* prom structure */
158static struct prom_t __initdata prom;
159
160#define PROM_SCRATCH_SIZE 256
161
162static char __initdata of_stdout_device[256];
163static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
164
165static unsigned long __initdata dt_header_start;
166static unsigned long __initdata dt_struct_start, dt_struct_end;
167static unsigned long __initdata dt_string_start, dt_string_end;
168
169static unsigned long __initdata prom_initrd_start, prom_initrd_end;
170
171static int __initdata iommu_force_on;
172static int __initdata ppc64_iommu_off;
173static int __initdata of_platform;
174
175static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
176
177static unsigned long __initdata prom_memory_limit;
178static unsigned long __initdata prom_tce_alloc_start;
179static unsigned long __initdata prom_tce_alloc_end;
180
181static unsigned long __initdata alloc_top;
182static unsigned long __initdata alloc_top_high;
183static unsigned long __initdata alloc_bottom;
184static unsigned long __initdata rmo_top;
185static unsigned long __initdata ram_top;
186
187static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
188static int __initdata mem_reserve_cnt;
189
190static cell_t __initdata regbuf[1024];
191
192
193#define MAX_CPU_THREADS 2
194
195/* TO GO */
196#ifdef CONFIG_HMT
197struct {
198 unsigned int pir;
199 unsigned int threadid;
200} hmt_thread_data[NR_CPUS];
201#endif /* CONFIG_HMT */
202
203/*
204 * This are used in calls to call_prom. The 4th and following
205 * arguments to call_prom should be 32-bit values. 64 bit values
206 * are truncated to 32 bits (and fortunately don't get interpreted
207 * as two arguments).
208 */
209#define ADDR(x) (u32) ((unsigned long)(x) - offset)
210
211/*
212 * Error results ... some OF calls will return "-1" on error, some
213 * will return 0, some will return either. To simplify, here are
214 * macros to use with any ihandle or phandle return value to check if
215 * it is valid
216 */
217
218#define PROM_ERROR (-1u)
219#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
220#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
221
222
223/* This is the one and *ONLY* place where we actually call open
224 * firmware from, since we need to make sure we're running in 32b
225 * mode when we do. We switch back to 64b mode upon return.
226 */
227
228static int __init call_prom(const char *service, int nargs, int nret, ...)
229{
230 int i;
231 unsigned long offset = reloc_offset();
232 struct prom_t *_prom = PTRRELOC(&prom);
233 va_list list;
234
235 _prom->args.service = ADDR(service);
236 _prom->args.nargs = nargs;
237 _prom->args.nret = nret;
238 _prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
239
240 va_start(list, nret);
241 for (i=0; i < nargs; i++)
242 _prom->args.args[i] = va_arg(list, prom_arg_t);
243 va_end(list);
244
245 for (i=0; i < nret ;i++)
246 _prom->args.rets[i] = 0;
247
248 enter_prom(&_prom->args, _prom->entry);
249
250 return (nret > 0) ? _prom->args.rets[0] : 0;
251}
252
253
254static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
255 unsigned long align)
256{
257 return (unsigned int)call_prom("claim", 3, 1,
258 (prom_arg_t)virt, (prom_arg_t)size,
259 (prom_arg_t)align);
260}
261
262static void __init prom_print(const char *msg)
263{
264 const char *p, *q;
265 unsigned long offset = reloc_offset();
266 struct prom_t *_prom = PTRRELOC(&prom);
267
268 if (_prom->stdout == 0)
269 return;
270
271 for (p = msg; *p != 0; p = q) {
272 for (q = p; *q != 0 && *q != '\n'; ++q)
273 ;
274 if (q > p)
275 call_prom("write", 3, 1, _prom->stdout, p, q - p);
276 if (*q == 0)
277 break;
278 ++q;
279 call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
280 }
281}
282
283
284static void __init prom_print_hex(unsigned long val)
285{
286 unsigned long offset = reloc_offset();
287 int i, nibbles = sizeof(val)*2;
288 char buf[sizeof(val)*2+1];
289 struct prom_t *_prom = PTRRELOC(&prom);
290
291 for (i = nibbles-1; i >= 0; i--) {
292 buf[i] = (val & 0xf) + '0';
293 if (buf[i] > '9')
294 buf[i] += ('a'-'0'-10);
295 val >>= 4;
296 }
297 buf[nibbles] = '\0';
298 call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
299}
300
301
302static void __init prom_printf(const char *format, ...)
303{
304 unsigned long offset = reloc_offset();
305 const char *p, *q, *s;
306 va_list args;
307 unsigned long v;
308 struct prom_t *_prom = PTRRELOC(&prom);
309
310 va_start(args, format);
311 for (p = PTRRELOC(format); *p != 0; p = q) {
312 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
313 ;
314 if (q > p)
315 call_prom("write", 3, 1, _prom->stdout, p, q - p);
316 if (*q == 0)
317 break;
318 if (*q == '\n') {
319 ++q;
320 call_prom("write", 3, 1, _prom->stdout,
321 ADDR("\r\n"), 2);
322 continue;
323 }
324 ++q;
325 if (*q == 0)
326 break;
327 switch (*q) {
328 case 's':
329 ++q;
330 s = va_arg(args, const char *);
331 prom_print(s);
332 break;
333 case 'x':
334 ++q;
335 v = va_arg(args, unsigned long);
336 prom_print_hex(v);
337 break;
338 }
339 }
340}
341
342
343static void __init __attribute__((noreturn)) prom_panic(const char *reason)
344{
345 unsigned long offset = reloc_offset();
346
347 prom_print(PTRRELOC(reason));
348 /* ToDo: should put up an SRC here */
349 call_prom("exit", 0, 0);
350
351 for (;;) /* should never get here */
352 ;
353}
354
355
356static int __init prom_next_node(phandle *nodep)
357{
358 phandle node;
359
360 if ((node = *nodep) != 0
361 && (*nodep = call_prom("child", 1, 1, node)) != 0)
362 return 1;
363 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
364 return 1;
365 for (;;) {
366 if ((node = call_prom("parent", 1, 1, node)) == 0)
367 return 0;
368 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
369 return 1;
370 }
371}
372
373static int __init prom_getprop(phandle node, const char *pname,
374 void *value, size_t valuelen)
375{
376 unsigned long offset = reloc_offset();
377
378 return call_prom("getprop", 4, 1, node, ADDR(pname),
379 (u32)(unsigned long) value, (u32) valuelen);
380}
381
382static int __init prom_getproplen(phandle node, const char *pname)
383{
384 unsigned long offset = reloc_offset();
385
386 return call_prom("getproplen", 2, 1, node, ADDR(pname));
387}
388
389static int __init prom_setprop(phandle node, const char *pname,
390 void *value, size_t valuelen)
391{
392 unsigned long offset = reloc_offset();
393
394 return call_prom("setprop", 4, 1, node, ADDR(pname),
395 (u32)(unsigned long) value, (u32) valuelen);
396}
397
398/* We can't use the standard versions because of RELOC headaches. */
399#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
400 || ('a' <= (c) && (c) <= 'f') \
401 || ('A' <= (c) && (c) <= 'F'))
402
403#define isdigit(c) ('0' <= (c) && (c) <= '9')
404#define islower(c) ('a' <= (c) && (c) <= 'z')
405#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
406
407unsigned long prom_strtoul(const char *cp, const char **endp)
408{
409 unsigned long result = 0, base = 10, value;
410
411 if (*cp == '0') {
412 base = 8;
413 cp++;
414 if (toupper(*cp) == 'X') {
415 cp++;
416 base = 16;
417 }
418 }
419
420 while (isxdigit(*cp) &&
421 (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
422 result = result * base + value;
423 cp++;
424 }
425
426 if (endp)
427 *endp = cp;
428
429 return result;
430}
431
432unsigned long prom_memparse(const char *ptr, const char **retptr)
433{
434 unsigned long ret = prom_strtoul(ptr, retptr);
435 int shift = 0;
436
437 /*
438 * We can't use a switch here because GCC *may* generate a
439 * jump table which won't work, because we're not running at
440 * the address we're linked at.
441 */
442 if ('G' == **retptr || 'g' == **retptr)
443 shift = 30;
444
445 if ('M' == **retptr || 'm' == **retptr)
446 shift = 20;
447
448 if ('K' == **retptr || 'k' == **retptr)
449 shift = 10;
450
451 if (shift) {
452 ret <<= shift;
453 (*retptr)++;
454 }
455
456 return ret;
457}
458
459/*
460 * Early parsing of the command line passed to the kernel, used for
461 * "mem=x" and the options that affect the iommu
462 */
463static void __init early_cmdline_parse(void)
464{
465 unsigned long offset = reloc_offset();
466 struct prom_t *_prom = PTRRELOC(&prom);
467 char *opt, *p;
468 int l = 0;
469
470 RELOC(prom_cmd_line[0]) = 0;
471 p = RELOC(prom_cmd_line);
472 if ((long)_prom->chosen > 0)
473 l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
474#ifdef CONFIG_CMDLINE
475 if (l == 0) /* dbl check */
476 strlcpy(RELOC(prom_cmd_line),
477 RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
478#endif /* CONFIG_CMDLINE */
479 prom_printf("command line: %s\n", RELOC(prom_cmd_line));
480
481 opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
482 if (opt) {
483 prom_printf("iommu opt is: %s\n", opt);
484 opt += 6;
485 while (*opt && *opt == ' ')
486 opt++;
487 if (!strncmp(opt, RELOC("off"), 3))
488 RELOC(ppc64_iommu_off) = 1;
489 else if (!strncmp(opt, RELOC("force"), 5))
490 RELOC(iommu_force_on) = 1;
491 }
492
493 opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
494 if (opt) {
495 opt += 4;
496 RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
497 /* Align to 16 MB == size of large page */
498 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
499 }
500}
501
502/*
503 * To tell the firmware what our capabilities are, we have to pass
504 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
505 * that contain structures that contain the actual values.
506 */
507static struct fake_elf {
508 Elf32_Ehdr elfhdr;
509 Elf32_Phdr phdr[2];
510 struct chrpnote {
511 u32 namesz;
512 u32 descsz;
513 u32 type;
514 char name[8]; /* "PowerPC" */
515 struct chrpdesc {
516 u32 real_mode;
517 u32 real_base;
518 u32 real_size;
519 u32 virt_base;
520 u32 virt_size;
521 u32 load_base;
522 } chrpdesc;
523 } chrpnote;
524 struct rpanote {
525 u32 namesz;
526 u32 descsz;
527 u32 type;
528 char name[24]; /* "IBM,RPA-Client-Config" */
529 struct rpadesc {
530 u32 lpar_affinity;
531 u32 min_rmo_size;
532 u32 min_rmo_percent;
533 u32 max_pft_size;
534 u32 splpar;
535 u32 min_load;
536 u32 new_mem_def;
537 u32 ignore_me;
538 } rpadesc;
539 } rpanote;
540} fake_elf = {
541 .elfhdr = {
542 .e_ident = { 0x7f, 'E', 'L', 'F',
543 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
544 .e_type = ET_EXEC, /* yeah right */
545 .e_machine = EM_PPC,
546 .e_version = EV_CURRENT,
547 .e_phoff = offsetof(struct fake_elf, phdr),
548 .e_phentsize = sizeof(Elf32_Phdr),
549 .e_phnum = 2
550 },
551 .phdr = {
552 [0] = {
553 .p_type = PT_NOTE,
554 .p_offset = offsetof(struct fake_elf, chrpnote),
555 .p_filesz = sizeof(struct chrpnote)
556 }, [1] = {
557 .p_type = PT_NOTE,
558 .p_offset = offsetof(struct fake_elf, rpanote),
559 .p_filesz = sizeof(struct rpanote)
560 }
561 },
562 .chrpnote = {
563 .namesz = sizeof("PowerPC"),
564 .descsz = sizeof(struct chrpdesc),
565 .type = 0x1275,
566 .name = "PowerPC",
567 .chrpdesc = {
568 .real_mode = ~0U, /* ~0 means "don't care" */
569 .real_base = ~0U,
570 .real_size = ~0U,
571 .virt_base = ~0U,
572 .virt_size = ~0U,
573 .load_base = ~0U
574 },
575 },
576 .rpanote = {
577 .namesz = sizeof("IBM,RPA-Client-Config"),
578 .descsz = sizeof(struct rpadesc),
579 .type = 0x12759999,
580 .name = "IBM,RPA-Client-Config",
581 .rpadesc = {
582 .lpar_affinity = 0,
583 .min_rmo_size = 64, /* in megabytes */
584 .min_rmo_percent = 0,
585 .max_pft_size = 48, /* 2^48 bytes max PFT size */
586 .splpar = 1,
587 .min_load = ~0U,
588 .new_mem_def = 0
589 }
590 }
591};
592
593static void __init prom_send_capabilities(void)
594{
595 unsigned long offset = reloc_offset();
596 ihandle elfloader;
597
598 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
599 if (elfloader == 0) {
600 prom_printf("couldn't open /packages/elf-loader\n");
601 return;
602 }
603 call_prom("call-method", 3, 1, ADDR("process-elf-header"),
604 elfloader, ADDR(&fake_elf));
605 call_prom("close", 1, 0, elfloader);
606}
607
608/*
609 * Memory allocation strategy... our layout is normally:
610 *
611 * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
612 * might end up beeing before the kernel though. We assume this won't override
613 * the final kernel at 0, we have no provision to handle that in this version,
614 * but it should hopefully never happen.
615 *
616 * alloc_top is set to the top of RMO, eventually shrink down if the TCEs overlap
617 * alloc_bottom is set to the top of kernel/initrd
618 *
619 * from there, allocations are done that way : rtas is allocated topmost, and
620 * the device-tree is allocated from the bottom. We try to grow the device-tree
621 * allocation as we progress. If we can't, then we fail, we don't currently have
622 * a facility to restart elsewhere, but that shouldn't be necessary neither
623 *
624 * Note that calls to reserve_mem have to be done explicitely, memory allocated
625 * with either alloc_up or alloc_down isn't automatically reserved.
626 */
627
628
629/*
630 * Allocates memory in the RMO upward from the kernel/initrd
631 *
632 * When align is 0, this is a special case, it means to allocate in place
633 * at the current location of alloc_bottom or fail (that is basically
634 * extending the previous allocation). Used for the device-tree flattening
635 */
636static unsigned long __init alloc_up(unsigned long size, unsigned long align)
637{
638 unsigned long offset = reloc_offset();
639 unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align);
640 unsigned long addr = 0;
641
642 prom_debug("alloc_up(%x, %x)\n", size, align);
643 if (RELOC(ram_top) == 0)
644 prom_panic("alloc_up() called with mem not initialized\n");
645
646 if (align)
647 base = _ALIGN_UP(RELOC(alloc_bottom), align);
648 else
649 base = RELOC(alloc_bottom);
650
651 for(; (base + size) <= RELOC(alloc_top);
652 base = _ALIGN_UP(base + 0x100000, align)) {
653 prom_debug(" trying: 0x%x\n\r", base);
654 addr = (unsigned long)prom_claim(base, size, 0);
655 if (addr != PROM_ERROR)
656 break;
657 addr = 0;
658 if (align == 0)
659 break;
660 }
661 if (addr == 0)
662 return 0;
663 RELOC(alloc_bottom) = addr;
664
665 prom_debug(" -> %x\n", addr);
666 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
667 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
668 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
669 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
670 prom_debug(" ram_top : %x\n", RELOC(ram_top));
671
672 return addr;
673}
674
675/*
676 * Allocates memory downard, either from top of RMO, or if highmem
677 * is set, from the top of RAM. Note that this one doesn't handle
678 * failures. In does claim memory if highmem is not set.
679 */
680static unsigned long __init alloc_down(unsigned long size, unsigned long align,
681 int highmem)
682{
683 unsigned long offset = reloc_offset();
684 unsigned long base, addr = 0;
685
686 prom_debug("alloc_down(%x, %x, %s)\n", size, align,
687 highmem ? RELOC("(high)") : RELOC("(low)"));
688 if (RELOC(ram_top) == 0)
689 prom_panic("alloc_down() called with mem not initialized\n");
690
691 if (highmem) {
692 /* Carve out storage for the TCE table. */
693 addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
694 if (addr <= RELOC(alloc_bottom))
695 return 0;
696 else {
697 /* Will we bump into the RMO ? If yes, check out that we
698 * didn't overlap existing allocations there, if we did,
699 * we are dead, we must be the first in town !
700 */
701 if (addr < RELOC(rmo_top)) {
702 /* Good, we are first */
703 if (RELOC(alloc_top) == RELOC(rmo_top))
704 RELOC(alloc_top) = RELOC(rmo_top) = addr;
705 else
706 return 0;
707 }
708 RELOC(alloc_top_high) = addr;
709 }
710 goto bail;
711 }
712
713 base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
714 for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) {
715 prom_debug(" trying: 0x%x\n\r", base);
716 addr = (unsigned long)prom_claim(base, size, 0);
717 if (addr != PROM_ERROR)
718 break;
719 addr = 0;
720 }
721 if (addr == 0)
722 return 0;
723 RELOC(alloc_top) = addr;
724
725 bail:
726 prom_debug(" -> %x\n", addr);
727 prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
728 prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
729 prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
730 prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
731 prom_debug(" ram_top : %x\n", RELOC(ram_top));
732
733 return addr;
734}
735
736/*
737 * Parse a "reg" cell
738 */
739static unsigned long __init prom_next_cell(int s, cell_t **cellp)
740{
741 cell_t *p = *cellp;
742 unsigned long r = 0;
743
744 /* Ignore more than 2 cells */
745 while (s > 2) {
746 p++;
747 s--;
748 }
749 while (s) {
750 r <<= 32;
751 r |= *(p++);
752 s--;
753 }
754
755 *cellp = p;
756 return r;
757}
758
759/*
760 * Very dumb function for adding to the memory reserve list, but
761 * we don't need anything smarter at this point
762 *
763 * XXX Eventually check for collisions. They should NEVER happen
764 * if problems seem to show up, it would be a good start to track
765 * them down.
766 */
767static void reserve_mem(unsigned long base, unsigned long size)
768{
769 unsigned long offset = reloc_offset();
770 unsigned long top = base + size;
771 unsigned long cnt = RELOC(mem_reserve_cnt);
772
773 if (size == 0)
774 return;
775
776 /* We need to always keep one empty entry so that we
777 * have our terminator with "size" set to 0 since we are
778 * dumb and just copy this entire array to the boot params
779 */
780 base = _ALIGN_DOWN(base, PAGE_SIZE);
781 top = _ALIGN_UP(top, PAGE_SIZE);
782 size = top - base;
783
784 if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
785 prom_panic("Memory reserve map exhausted !\n");
786 RELOC(mem_reserve_map)[cnt].base = base;
787 RELOC(mem_reserve_map)[cnt].size = size;
788 RELOC(mem_reserve_cnt) = cnt + 1;
789}
790
791/*
792 * Initialize memory allocation mecanism, parse "memory" nodes and
793 * obtain that way the top of memory and RMO to setup out local allocator
794 */
795static void __init prom_init_mem(void)
796{
797 phandle node;
798 char *path, type[64];
799 unsigned int plen;
800 cell_t *p, *endp;
801 unsigned long offset = reloc_offset();
802 struct prom_t *_prom = PTRRELOC(&prom);
803
804 /*
805 * We iterate the memory nodes to find
806 * 1) top of RMO (first node)
807 * 2) top of memory
808 */
809 prom_debug("root_addr_cells: %x\n", (long)_prom->root_addr_cells);
810 prom_debug("root_size_cells: %x\n", (long)_prom->root_size_cells);
811
812 prom_debug("scanning memory:\n");
813 path = RELOC(prom_scratch);
814
815 for (node = 0; prom_next_node(&node); ) {
816 type[0] = 0;
817 prom_getprop(node, "device_type", type, sizeof(type));
818
819 if (strcmp(type, RELOC("memory")))
820 continue;
821
822 plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
823 if (plen > sizeof(regbuf)) {
824 prom_printf("memory node too large for buffer !\n");
825 plen = sizeof(regbuf);
826 }
827 p = RELOC(regbuf);
828 endp = p + (plen / sizeof(cell_t));
829
830#ifdef DEBUG_PROM
831 memset(path, 0, PROM_SCRATCH_SIZE);
832 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
833 prom_debug(" node %s :\n", path);
834#endif /* DEBUG_PROM */
835
836 while ((endp - p) >= (_prom->root_addr_cells + _prom->root_size_cells)) {
837 unsigned long base, size;
838
839 base = prom_next_cell(_prom->root_addr_cells, &p);
840 size = prom_next_cell(_prom->root_size_cells, &p);
841
842 if (size == 0)
843 continue;
844 prom_debug(" %x %x\n", base, size);
845 if (base == 0)
846 RELOC(rmo_top) = size;
847 if ((base + size) > RELOC(ram_top))
848 RELOC(ram_top) = base + size;
849 }
850 }
851
852 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(klimit) - offset + 0x4000);
853
854 /* Check if we have an initrd after the kernel, if we do move our bottom
855 * point to after it
856 */
857 if (RELOC(prom_initrd_start)) {
858 if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
859 RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
860 }
861
862 /*
863 * If prom_memory_limit is set we reduce the upper limits *except* for
864 * alloc_top_high. This must be the real top of RAM so we can put
865 * TCE's up there.
866 */
867
868 RELOC(alloc_top_high) = RELOC(ram_top);
869
870 if (RELOC(prom_memory_limit)) {
871 if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
872 prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
873 RELOC(prom_memory_limit));
874 RELOC(prom_memory_limit) = 0;
875 } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
876 prom_printf("Ignoring mem=%x >= ram_top.\n",
877 RELOC(prom_memory_limit));
878 RELOC(prom_memory_limit) = 0;
879 } else {
880 RELOC(ram_top) = RELOC(prom_memory_limit);
881 RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
882 }
883 }
884
885 /*
886 * Setup our top alloc point, that is top of RMO or top of
887 * segment 0 when running non-LPAR.
888 */
889 if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
890 RELOC(alloc_top) = RELOC(rmo_top);
891 else
892 /* Some RS64 machines have buggy firmware where claims up at 1GB
893 * fails. Cap at 768MB as a workaround. Still plenty of room.
894 */
895 RELOC(alloc_top) = RELOC(rmo_top) = min(0x30000000ul, RELOC(ram_top));
896
897 prom_printf("memory layout at init:\n");
898 prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
899 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
900 prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
901 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
902 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
903 prom_printf(" ram_top : %x\n", RELOC(ram_top));
904}
905
906
907/*
908 * Allocate room for and instanciate RTAS
909 */
910static void __init prom_instantiate_rtas(void)
911{
912 unsigned long offset = reloc_offset();
913 struct prom_t *_prom = PTRRELOC(&prom);
914 phandle rtas_node;
915 ihandle rtas_inst;
916 u32 base, entry = 0;
917 u32 size = 0;
918
919 prom_debug("prom_instantiate_rtas: start...\n");
920
921 rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
922 prom_debug("rtas_node: %x\n", rtas_node);
923 if (!PHANDLE_VALID(rtas_node))
924 return;
925
926 prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
927 if (size == 0)
928 return;
929
930 base = alloc_down(size, PAGE_SIZE, 0);
931 if (base == 0) {
932 prom_printf("RTAS allocation failed !\n");
933 return;
934 }
935
936 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
937 if (!IHANDLE_VALID(rtas_inst)) {
938 prom_printf("opening rtas package failed");
939 return;
940 }
941
942 prom_printf("instantiating rtas at 0x%x ...", base);
943
944 if (call_prom("call-method", 3, 2,
945 ADDR("instantiate-rtas"),
946 rtas_inst, base) != PROM_ERROR) {
947 entry = (long)_prom->args.rets[1];
948 }
949 if (entry == 0) {
950 prom_printf(" failed\n");
951 return;
952 }
953 prom_printf(" done\n");
954
955 reserve_mem(base, size);
956
957 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
958 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
959
960 prom_debug("rtas base = 0x%x\n", base);
961 prom_debug("rtas entry = 0x%x\n", entry);
962 prom_debug("rtas size = 0x%x\n", (long)size);
963
964 prom_debug("prom_instantiate_rtas: end...\n");
965}
966
967
968/*
969 * Allocate room for and initialize TCE tables
970 */
971static void __init prom_initialize_tce_table(void)
972{
973 phandle node;
974 ihandle phb_node;
975 unsigned long offset = reloc_offset();
976 char compatible[64], type[64], model[64];
977 char *path = RELOC(prom_scratch);
978 u64 base, align;
979 u32 minalign, minsize;
980 u64 tce_entry, *tce_entryp;
981 u64 local_alloc_top, local_alloc_bottom;
982 u64 i;
983
984 if (RELOC(ppc64_iommu_off))
985 return;
986
987 prom_debug("starting prom_initialize_tce_table\n");
988
989 /* Cache current top of allocs so we reserve a single block */
990 local_alloc_top = RELOC(alloc_top_high);
991 local_alloc_bottom = local_alloc_top;
992
993 /* Search all nodes looking for PHBs. */
994 for (node = 0; prom_next_node(&node); ) {
995 compatible[0] = 0;
996 type[0] = 0;
997 model[0] = 0;
998 prom_getprop(node, "compatible",
999 compatible, sizeof(compatible));
1000 prom_getprop(node, "device_type", type, sizeof(type));
1001 prom_getprop(node, "model", model, sizeof(model));
1002
1003 if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
1004 continue;
1005
1006 /* Keep the old logic in tack to avoid regression. */
1007 if (compatible[0] != 0) {
1008 if ((strstr(compatible, RELOC("python")) == NULL) &&
1009 (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
1010 (strstr(compatible, RELOC("Winnipeg")) == NULL))
1011 continue;
1012 } else if (model[0] != 0) {
1013 if ((strstr(model, RELOC("ython")) == NULL) &&
1014 (strstr(model, RELOC("peedwagon")) == NULL) &&
1015 (strstr(model, RELOC("innipeg")) == NULL))
1016 continue;
1017 }
1018
1019 if (prom_getprop(node, "tce-table-minalign", &minalign,
1020 sizeof(minalign)) == PROM_ERROR)
1021 minalign = 0;
1022 if (prom_getprop(node, "tce-table-minsize", &minsize,
1023 sizeof(minsize)) == PROM_ERROR)
1024 minsize = 4UL << 20;
1025
1026 /*
1027 * Even though we read what OF wants, we just set the table
1028 * size to 4 MB. This is enough to map 2GB of PCI DMA space.
1029 * By doing this, we avoid the pitfalls of trying to DMA to
1030 * MMIO space and the DMA alias hole.
1031 *
1032 * On POWER4, firmware sets the TCE region by assuming
1033 * each TCE table is 8MB. Using this memory for anything
1034 * else will impact performance, so we always allocate 8MB.
1035 * Anton
1036 */
1037 if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
1038 minsize = 8UL << 20;
1039 else
1040 minsize = 4UL << 20;
1041
1042 /* Align to the greater of the align or size */
1043 align = max(minalign, minsize);
1044 base = alloc_down(minsize, align, 1);
1045 if (base == 0)
1046 prom_panic("ERROR, cannot find space for TCE table.\n");
1047 if (base < local_alloc_bottom)
1048 local_alloc_bottom = base;
1049
1050 /* Save away the TCE table attributes for later use. */
1051 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
1052 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
1053
1054 /* It seems OF doesn't null-terminate the path :-( */
1055 memset(path, 0, sizeof(path));
1056 /* Call OF to setup the TCE hardware */
1057 if (call_prom("package-to-path", 3, 1, node,
1058 path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
1059 prom_printf("package-to-path failed\n");
1060 }
1061
1062 prom_debug("TCE table: %s\n", path);
1063 prom_debug("\tnode = 0x%x\n", node);
1064 prom_debug("\tbase = 0x%x\n", base);
1065 prom_debug("\tsize = 0x%x\n", minsize);
1066
1067 /* Initialize the table to have a one-to-one mapping
1068 * over the allocated size.
1069 */
1070 tce_entryp = (unsigned long *)base;
1071 for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
1072 tce_entry = (i << PAGE_SHIFT);
1073 tce_entry |= 0x3;
1074 *tce_entryp = tce_entry;
1075 }
1076
1077 prom_printf("opening PHB %s", path);
1078 phb_node = call_prom("open", 1, 1, path);
1079 if (phb_node == 0)
1080 prom_printf("... failed\n");
1081 else
1082 prom_printf("... done\n");
1083
1084 call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
1085 phb_node, -1, minsize,
1086 (u32) base, (u32) (base >> 32));
1087 call_prom("close", 1, 0, phb_node);
1088 }
1089
1090 reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
1091
1092 if (RELOC(prom_memory_limit)) {
1093 /*
1094 * We align the start to a 16MB boundary so we can map the TCE area
1095 * using large pages if possible. The end should be the top of RAM
1096 * so no need to align it.
1097 */
1098 RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 0x1000000);
1099 RELOC(prom_tce_alloc_end) = local_alloc_top;
1100 }
1101
1102 /* Flag the first invalid entry */
1103 prom_debug("ending prom_initialize_tce_table\n");
1104}
1105
1106/*
1107 * With CHRP SMP we need to use the OF to start the other
1108 * processors so we can't wait until smp_boot_cpus (the OF is
1109 * trashed by then) so we have to put the processors into
1110 * a holding pattern controlled by the kernel (not OF) before
1111 * we destroy the OF.
1112 *
1113 * This uses a chunk of low memory, puts some holding pattern
1114 * code there and sends the other processors off to there until
1115 * smp_boot_cpus tells them to do something. The holding pattern
1116 * checks that address until its cpu # is there, when it is that
1117 * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
1118 * of setting those values.
1119 *
1120 * We also use physical address 0x4 here to tell when a cpu
1121 * is in its holding pattern code.
1122 *
1123 * Fixup comment... DRENG / PPPBBB - Peter
1124 *
1125 * -- Cort
1126 */
1127static void __init prom_hold_cpus(void)
1128{
1129 unsigned long i;
1130 unsigned int reg;
1131 phandle node;
1132 unsigned long offset = reloc_offset();
1133 char type[64];
1134 int cpuid = 0;
1135 unsigned int interrupt_server[MAX_CPU_THREADS];
1136 unsigned int cpu_threads, hw_cpu_num;
1137 int propsize;
1138 extern void __secondary_hold(void);
1139 extern unsigned long __secondary_hold_spinloop;
1140 extern unsigned long __secondary_hold_acknowledge;
1141 unsigned long *spinloop
1142 = (void *)virt_to_abs(&__secondary_hold_spinloop);
1143 unsigned long *acknowledge
1144 = (void *)virt_to_abs(&__secondary_hold_acknowledge);
1145 unsigned long secondary_hold
1146 = virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
1147 struct prom_t *_prom = PTRRELOC(&prom);
1148
1149 prom_debug("prom_hold_cpus: start...\n");
1150 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
1151 prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
1152 prom_debug(" 1) acknowledge = 0x%x\n",
1153 (unsigned long)acknowledge);
1154 prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
1155 prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
1156
1157 /* Set the common spinloop variable, so all of the secondary cpus
1158 * will block when they are awakened from their OF spinloop.
1159 * This must occur for both SMP and non SMP kernels, since OF will
1160 * be trashed when we move the kernel.
1161 */
1162 *spinloop = 0;
1163
1164#ifdef CONFIG_HMT
1165 for (i=0; i < NR_CPUS; i++) {
1166 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1167 }
1168#endif
1169 /* look for cpus */
1170 for (node = 0; prom_next_node(&node); ) {
1171 type[0] = 0;
1172 prom_getprop(node, "device_type", type, sizeof(type));
1173 if (strcmp(type, RELOC("cpu")) != 0)
1174 continue;
1175
1176 /* Skip non-configured cpus. */
1177 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1178 if (strcmp(type, RELOC("okay")) != 0)
1179 continue;
1180
1181 reg = -1;
1182 prom_getprop(node, "reg", &reg, sizeof(reg));
1183
1184 prom_debug("\ncpuid = 0x%x\n", cpuid);
1185 prom_debug("cpu hw idx = 0x%x\n", reg);
1186
1187 /* Init the acknowledge var which will be reset by
1188 * the secondary cpu when it awakens from its OF
1189 * spinloop.
1190 */
1191 *acknowledge = (unsigned long)-1;
1192
1193 propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
1194 &interrupt_server,
1195 sizeof(interrupt_server));
1196 if (propsize < 0) {
1197 /* no property. old hardware has no SMT */
1198 cpu_threads = 1;
1199 interrupt_server[0] = reg; /* fake it with phys id */
1200 } else {
1201 /* We have a threaded processor */
1202 cpu_threads = propsize / sizeof(u32);
1203 if (cpu_threads > MAX_CPU_THREADS) {
1204 prom_printf("SMT: too many threads!\n"
1205 "SMT: found %x, max is %x\n",
1206 cpu_threads, MAX_CPU_THREADS);
1207 cpu_threads = 1; /* ToDo: panic? */
1208 }
1209 }
1210
1211 hw_cpu_num = interrupt_server[0];
1212 if (hw_cpu_num != _prom->cpu) {
1213 /* Primary Thread of non-boot cpu */
1214 prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
1215 call_prom("start-cpu", 3, 0, node,
1216 secondary_hold, reg);
1217
1218 for ( i = 0 ; (i < 100000000) &&
1219 (*acknowledge == ((unsigned long)-1)); i++ )
1220 mb();
1221
1222 if (*acknowledge == reg) {
1223 prom_printf("done\n");
1224 /* We have to get every CPU out of OF,
1225 * even if we never start it. */
1226 if (cpuid >= NR_CPUS)
1227 goto next;
1228 } else {
1229 prom_printf("failed: %x\n", *acknowledge);
1230 }
1231 }
1232#ifdef CONFIG_SMP
1233 else
1234 prom_printf("%x : boot cpu %x\n", cpuid, reg);
1235#endif
1236next:
1237#ifdef CONFIG_SMP
1238 /* Init paca for secondary threads. They start later. */
1239 for (i=1; i < cpu_threads; i++) {
1240 cpuid++;
1241 if (cpuid >= NR_CPUS)
1242 continue;
1243 }
1244#endif /* CONFIG_SMP */
1245 cpuid++;
1246 }
1247#ifdef CONFIG_HMT
1248 /* Only enable HMT on processors that provide support. */
1249 if (__is_processor(PV_PULSAR) ||
1250 __is_processor(PV_ICESTAR) ||
1251 __is_processor(PV_SSTAR)) {
1252 prom_printf(" starting secondary threads\n");
1253
1254 for (i = 0; i < NR_CPUS; i += 2) {
1255 if (!cpu_online(i))
1256 continue;
1257
1258 if (i == 0) {
1259 unsigned long pir = mfspr(SPRN_PIR);
1260 if (__is_processor(PV_PULSAR)) {
1261 RELOC(hmt_thread_data)[i].pir =
1262 pir & 0x1f;
1263 } else {
1264 RELOC(hmt_thread_data)[i].pir =
1265 pir & 0x3ff;
1266 }
1267 }
1268 }
1269 } else {
1270 prom_printf("Processor is not HMT capable\n");
1271 }
1272#endif
1273
1274 if (cpuid > NR_CPUS)
1275 prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
1276 ") exceeded: ignoring extras\n");
1277
1278 prom_debug("prom_hold_cpus: end...\n");
1279}
1280
1281
1282static void __init prom_init_client_services(unsigned long pp)
1283{
1284 unsigned long offset = reloc_offset();
1285 struct prom_t *_prom = PTRRELOC(&prom);
1286
1287 /* Get a handle to the prom entry point before anything else */
1288 _prom->entry = pp;
1289
1290 /* Init default value for phys size */
1291 _prom->root_size_cells = 1;
1292 _prom->root_addr_cells = 2;
1293
1294 /* get a handle for the stdout device */
1295 _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
1296 if (!PHANDLE_VALID(_prom->chosen))
1297 prom_panic("cannot find chosen"); /* msg won't be printed :( */
1298
1299 /* get device tree root */
1300 _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
1301 if (!PHANDLE_VALID(_prom->root))
1302 prom_panic("cannot find device tree root"); /* msg won't be printed :( */
1303}
1304
1305static void __init prom_init_stdout(void)
1306{
1307 unsigned long offset = reloc_offset();
1308 struct prom_t *_prom = PTRRELOC(&prom);
1309 char *path = RELOC(of_stdout_device);
1310 char type[16];
1311 u32 val;
1312
1313 if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
1314 prom_panic("cannot find stdout");
1315
1316 _prom->stdout = val;
1317
1318 /* Get the full OF pathname of the stdout device */
1319 memset(path, 0, 256);
1320 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1321 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1322 prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
1323 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1324 prom_setprop(_prom->chosen, "linux,stdout-path",
1325 RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
1326
1327 /* If it's a display, note it */
1328 memset(type, 0, sizeof(type));
1329 prom_getprop(val, "device_type", type, sizeof(type));
1330 if (strcmp(type, RELOC("display")) == 0) {
1331 _prom->disp_node = val;
1332 prom_setprop(val, "linux,boot-display", NULL, 0);
1333 }
1334}
1335
1336static void __init prom_close_stdin(void)
1337{
1338 unsigned long offset = reloc_offset();
1339 struct prom_t *_prom = PTRRELOC(&prom);
1340 ihandle val;
1341
1342 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1343 call_prom("close", 1, 0, val);
1344}
1345
1346static int __init prom_find_machine_type(void)
1347{
1348 unsigned long offset = reloc_offset();
1349 struct prom_t *_prom = PTRRELOC(&prom);
1350 char compat[256];
1351 int len, i = 0;
1352 phandle rtas;
1353
1354 len = prom_getprop(_prom->root, "compatible",
1355 compat, sizeof(compat)-1);
1356 if (len > 0) {
1357 compat[len] = 0;
1358 while (i < len) {
1359 char *p = &compat[i];
1360 int sl = strlen(p);
1361 if (sl == 0)
1362 break;
1363 if (strstr(p, RELOC("Power Macintosh")) ||
1364 strstr(p, RELOC("MacRISC4")))
1365 return PLATFORM_POWERMAC;
1366 if (strstr(p, RELOC("Momentum,Maple")))
1367 return PLATFORM_MAPLE;
1368 i += sl + 1;
1369 }
1370 }
1371 /* Default to pSeries. We need to know if we are running LPAR */
1372 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1373 if (PHANDLE_VALID(rtas)) {
1374 int x = prom_getproplen(rtas, "ibm,hypertas-functions");
1375 if (x != PROM_ERROR) {
1376 prom_printf("Hypertas detected, assuming LPAR !\n");
1377 return PLATFORM_PSERIES_LPAR;
1378 }
1379 }
1380 return PLATFORM_PSERIES;
1381}
1382
1383static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
1384{
1385 unsigned long offset = reloc_offset();
1386
1387 return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
1388}
1389
1390/*
1391 * If we have a display that we don't know how to drive,
1392 * we will want to try to execute OF's open method for it
1393 * later. However, OF will probably fall over if we do that
1394 * we've taken over the MMU.
1395 * So we check whether we will need to open the display,
1396 * and if so, open it now.
1397 */
1398static void __init prom_check_displays(void)
1399{
1400 unsigned long offset = reloc_offset();
1401 struct prom_t *_prom = PTRRELOC(&prom);
1402 char type[16], *path;
1403 phandle node;
1404 ihandle ih;
1405 int i;
1406
1407 static unsigned char default_colors[] = {
1408 0x00, 0x00, 0x00,
1409 0x00, 0x00, 0xaa,
1410 0x00, 0xaa, 0x00,
1411 0x00, 0xaa, 0xaa,
1412 0xaa, 0x00, 0x00,
1413 0xaa, 0x00, 0xaa,
1414 0xaa, 0xaa, 0x00,
1415 0xaa, 0xaa, 0xaa,
1416 0x55, 0x55, 0x55,
1417 0x55, 0x55, 0xff,
1418 0x55, 0xff, 0x55,
1419 0x55, 0xff, 0xff,
1420 0xff, 0x55, 0x55,
1421 0xff, 0x55, 0xff,
1422 0xff, 0xff, 0x55,
1423 0xff, 0xff, 0xff
1424 };
1425 const unsigned char *clut;
1426
1427 prom_printf("Looking for displays\n");
1428 for (node = 0; prom_next_node(&node); ) {
1429 memset(type, 0, sizeof(type));
1430 prom_getprop(node, "device_type", type, sizeof(type));
1431 if (strcmp(type, RELOC("display")) != 0)
1432 continue;
1433
1434 /* It seems OF doesn't null-terminate the path :-( */
1435 path = RELOC(prom_scratch);
1436 memset(path, 0, PROM_SCRATCH_SIZE);
1437
1438 /*
1439 * leave some room at the end of the path for appending extra
1440 * arguments
1441 */
1442 if (call_prom("package-to-path", 3, 1, node, path,
1443 PROM_SCRATCH_SIZE-10) == PROM_ERROR)
1444 continue;
1445 prom_printf("found display : %s, opening ... ", path);
1446
1447 ih = call_prom("open", 1, 1, path);
1448 if (ih == 0) {
1449 prom_printf("failed\n");
1450 continue;
1451 }
1452
1453 /* Success */
1454 prom_printf("done\n");
1455 prom_setprop(node, "linux,opened", NULL, 0);
1456
1457 /*
1458 * stdout wasn't a display node, pick the first we can find
1459 * for btext
1460 */
1461 if (_prom->disp_node == 0)
1462 _prom->disp_node = node;
1463
1464 /* Setup a useable color table when the appropriate
1465 * method is available. Should update this to set-colors */
1466 clut = RELOC(default_colors);
1467 for (i = 0; i < 32; i++, clut += 3)
1468 if (prom_set_color(ih, i, clut[0], clut[1],
1469 clut[2]) != 0)
1470 break;
1471
1472#ifdef CONFIG_LOGO_LINUX_CLUT224
1473 clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
1474 for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
1475 if (prom_set_color(ih, i + 32, clut[0], clut[1],
1476 clut[2]) != 0)
1477 break;
1478#endif /* CONFIG_LOGO_LINUX_CLUT224 */
1479 }
1480}
1481
1482
1483/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
1484static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
1485 unsigned long needed, unsigned long align)
1486{
1487 unsigned long offset = reloc_offset();
1488 void *ret;
1489
1490 *mem_start = _ALIGN(*mem_start, align);
1491 while ((*mem_start + needed) > *mem_end) {
1492 unsigned long room, chunk;
1493
1494 prom_debug("Chunk exhausted, claiming more at %x...\n",
1495 RELOC(alloc_bottom));
1496 room = RELOC(alloc_top) - RELOC(alloc_bottom);
1497 if (room > DEVTREE_CHUNK_SIZE)
1498 room = DEVTREE_CHUNK_SIZE;
1499 if (room < PAGE_SIZE)
1500 prom_panic("No memory for flatten_device_tree (no room)");
1501 chunk = alloc_up(room, 0);
1502 if (chunk == 0)
1503 prom_panic("No memory for flatten_device_tree (claim failed)");
1504 *mem_end = RELOC(alloc_top);
1505 }
1506
1507 ret = (void *)*mem_start;
1508 *mem_start += needed;
1509
1510 return ret;
1511}
1512
1513#define dt_push_token(token, mem_start, mem_end) \
1514 do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
1515
1516static unsigned long __init dt_find_string(char *str)
1517{
1518 unsigned long offset = reloc_offset();
1519 char *s, *os;
1520
1521 s = os = (char *)RELOC(dt_string_start);
1522 s += 4;
1523 while (s < (char *)RELOC(dt_string_end)) {
1524 if (strcmp(s, str) == 0)
1525 return s - os;
1526 s += strlen(s) + 1;
1527 }
1528 return 0;
1529}
1530
1531/*
1532 * The Open Firmware 1275 specification states properties must be 31 bytes or
1533 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1534 */
1535#define MAX_PROPERTY_NAME 64
1536
1537static void __init scan_dt_build_strings(phandle node,
1538 unsigned long *mem_start,
1539 unsigned long *mem_end)
1540{
1541 unsigned long offset = reloc_offset();
1542 char *prev_name, *namep, *sstart;
1543 unsigned long soff;
1544 phandle child;
1545
1546 sstart = (char *)RELOC(dt_string_start);
1547
1548 /* get and store all property names */
1549 prev_name = RELOC("");
1550 for (;;) {
1551 /* 64 is max len of name including nul. */
1552 namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
1553 if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
1554 /* No more nodes: unwind alloc */
1555 *mem_start = (unsigned long)namep;
1556 break;
1557 }
1558
1559 /* skip "name" */
1560 if (strcmp(namep, RELOC("name")) == 0) {
1561 *mem_start = (unsigned long)namep;
1562 prev_name = RELOC("name");
1563 continue;
1564 }
1565 /* get/create string entry */
1566 soff = dt_find_string(namep);
1567 if (soff != 0) {
1568 *mem_start = (unsigned long)namep;
1569 namep = sstart + soff;
1570 } else {
1571 /* Trim off some if we can */
1572 *mem_start = (unsigned long)namep + strlen(namep) + 1;
1573 RELOC(dt_string_end) = *mem_start;
1574 }
1575 prev_name = namep;
1576 }
1577
1578 /* do all our children */
1579 child = call_prom("child", 1, 1, node);
1580 while (child != 0) {
1581 scan_dt_build_strings(child, mem_start, mem_end);
1582 child = call_prom("peer", 1, 1, child);
1583 }
1584}
1585
1586static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1587 unsigned long *mem_end)
1588{
1589 phandle child;
1590 char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
1591 unsigned long soff;
1592 unsigned char *valp;
1593 unsigned long offset = reloc_offset();
1594 static char pname[MAX_PROPERTY_NAME];
1595 int l;
1596
1597 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1598
1599 /* get the node's full name */
1600 namep = (char *)*mem_start;
1601 l = call_prom("package-to-path", 3, 1, node,
1602 namep, *mem_end - *mem_start);
1603 if (l >= 0) {
1604 /* Didn't fit? Get more room. */
1605 if ((l+1) > (*mem_end - *mem_start)) {
1606 namep = make_room(mem_start, mem_end, l+1, 1);
1607 call_prom("package-to-path", 3, 1, node, namep, l);
1608 }
1609 namep[l] = '\0';
1610
1611 /* Fixup an Apple bug where they have bogus \0 chars in the
1612 * middle of the path in some properties
1613 */
1614 for (p = namep, ep = namep + l; p < ep; p++)
1615 if (*p == '\0') {
1616 memmove(p, p+1, ep - p);
1617 ep--; l--; p--;
1618 }
1619
1620 /* now try to extract the unit name in that mess */
1621 for (p = namep, lp = NULL; *p; p++)
1622 if (*p == '/')
1623 lp = p + 1;
1624 if (lp != NULL)
1625 memmove(namep, lp, strlen(lp) + 1);
1626 *mem_start = _ALIGN(((unsigned long) namep) +
1627 strlen(namep) + 1, 4);
1628 }
1629
1630 /* get it again for debugging */
1631 path = RELOC(prom_scratch);
1632 memset(path, 0, PROM_SCRATCH_SIZE);
1633 call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
1634
1635 /* get and store all properties */
1636 prev_name = RELOC("");
1637 sstart = (char *)RELOC(dt_string_start);
1638 for (;;) {
1639 if (call_prom("nextprop", 3, 1, node, prev_name,
1640 RELOC(pname)) != 1)
1641 break;
1642
1643 /* skip "name" */
1644 if (strcmp(RELOC(pname), RELOC("name")) == 0) {
1645 prev_name = RELOC("name");
1646 continue;
1647 }
1648
1649 /* find string offset */
1650 soff = dt_find_string(RELOC(pname));
1651 if (soff == 0) {
1652 prom_printf("WARNING: Can't find string index for"
1653 " <%s>, node %s\n", RELOC(pname), path);
1654 break;
1655 }
1656 prev_name = sstart + soff;
1657
1658 /* get length */
1659 l = call_prom("getproplen", 2, 1, node, RELOC(pname));
1660
1661 /* sanity checks */
1662 if (l == PROM_ERROR)
1663 continue;
1664 if (l > MAX_PROPERTY_LENGTH) {
1665 prom_printf("WARNING: ignoring large property ");
1666 /* It seems OF doesn't null-terminate the path :-( */
1667 prom_printf("[%s] ", path);
1668 prom_printf("%s length 0x%x\n", RELOC(pname), l);
1669 continue;
1670 }
1671
1672 /* push property head */
1673 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1674 dt_push_token(l, mem_start, mem_end);
1675 dt_push_token(soff, mem_start, mem_end);
1676
1677 /* push property content */
1678 valp = make_room(mem_start, mem_end, l, 4);
1679 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
1680 *mem_start = _ALIGN(*mem_start, 4);
1681 }
1682
1683 /* Add a "linux,phandle" property. */
1684 soff = dt_find_string(RELOC("linux,phandle"));
1685 if (soff == 0)
1686 prom_printf("WARNING: Can't find string index for"
1687 " <linux-phandle> node %s\n", path);
1688 else {
1689 dt_push_token(OF_DT_PROP, mem_start, mem_end);
1690 dt_push_token(4, mem_start, mem_end);
1691 dt_push_token(soff, mem_start, mem_end);
1692 valp = make_room(mem_start, mem_end, 4, 4);
1693 *(u32 *)valp = node;
1694 }
1695
1696 /* do all our children */
1697 child = call_prom("child", 1, 1, node);
1698 while (child != 0) {
1699 scan_dt_build_struct(child, mem_start, mem_end);
1700 child = call_prom("peer", 1, 1, child);
1701 }
1702
1703 dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
1704}
1705
1706static void __init flatten_device_tree(void)
1707{
1708 phandle root;
1709 unsigned long offset = reloc_offset();
1710 unsigned long mem_start, mem_end, room;
1711 struct boot_param_header *hdr;
1712 struct prom_t *_prom = PTRRELOC(&prom);
1713 char *namep;
1714 u64 *rsvmap;
1715
1716 /*
1717 * Check how much room we have between alloc top & bottom (+/- a
1718 * few pages), crop to 4Mb, as this is our "chuck" size
1719 */
1720 room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
1721 if (room > DEVTREE_CHUNK_SIZE)
1722 room = DEVTREE_CHUNK_SIZE;
1723 prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
1724
1725 /* Now try to claim that */
1726 mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
1727 if (mem_start == 0)
1728 prom_panic("Can't allocate initial device-tree chunk\n");
1729 mem_end = RELOC(alloc_top);
1730
1731 /* Get root of tree */
1732 root = call_prom("peer", 1, 1, (phandle)0);
1733 if (root == (phandle)0)
1734 prom_panic ("couldn't get device tree root\n");
1735
1736 /* Build header and make room for mem rsv map */
1737 mem_start = _ALIGN(mem_start, 4);
1738 hdr = make_room(&mem_start, &mem_end,
1739 sizeof(struct boot_param_header), 4);
1740 RELOC(dt_header_start) = (unsigned long)hdr;
1741 rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
1742
1743 /* Start of strings */
1744 mem_start = PAGE_ALIGN(mem_start);
1745 RELOC(dt_string_start) = mem_start;
1746 mem_start += 4; /* hole */
1747
1748 /* Add "linux,phandle" in there, we'll need it */
1749 namep = make_room(&mem_start, &mem_end, 16, 1);
1750 strcpy(namep, RELOC("linux,phandle"));
1751 mem_start = (unsigned long)namep + strlen(namep) + 1;
1752
1753 /* Build string array */
1754 prom_printf("Building dt strings...\n");
1755 scan_dt_build_strings(root, &mem_start, &mem_end);
1756 RELOC(dt_string_end) = mem_start;
1757
1758 /* Build structure */
1759 mem_start = PAGE_ALIGN(mem_start);
1760 RELOC(dt_struct_start) = mem_start;
1761 prom_printf("Building dt structure...\n");
1762 scan_dt_build_struct(root, &mem_start, &mem_end);
1763 dt_push_token(OF_DT_END, &mem_start, &mem_end);
1764 RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
1765
1766 /* Finish header */
1767 hdr->boot_cpuid_phys = _prom->cpu;
1768 hdr->magic = OF_DT_HEADER;
1769 hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
1770 hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
1771 hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
1772 hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
1773 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
1774 hdr->version = OF_DT_VERSION;
1775 /* Version 16 is not backward compatible */
1776 hdr->last_comp_version = 0x10;
1777
1778 /* Reserve the whole thing and copy the reserve map in, we
1779 * also bump mem_reserve_cnt to cause further reservations to
1780 * fail since it's too late.
1781 */
1782 reserve_mem(RELOC(dt_header_start), hdr->totalsize);
1783 memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
1784
1785#ifdef DEBUG_PROM
1786 {
1787 int i;
1788 prom_printf("reserved memory map:\n");
1789 for (i = 0; i < RELOC(mem_reserve_cnt); i++)
1790 prom_printf(" %x - %x\n", RELOC(mem_reserve_map)[i].base,
1791 RELOC(mem_reserve_map)[i].size);
1792 }
1793#endif
1794 RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
1795
1796 prom_printf("Device tree strings 0x%x -> 0x%x\n",
1797 RELOC(dt_string_start), RELOC(dt_string_end));
1798 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1799 RELOC(dt_struct_start), RELOC(dt_struct_end));
1800
1801}
1802
1803
1804static void __init fixup_device_tree(void)
1805{
1806 unsigned long offset = reloc_offset();
1807 phandle u3, i2c, mpic;
1808 u32 u3_rev;
1809 u32 interrupts[2];
1810 u32 parent;
1811
1812 /* Some G5s have a missing interrupt definition, fix it up here */
1813 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1814 if (!PHANDLE_VALID(u3))
1815 return;
1816 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1817 if (!PHANDLE_VALID(i2c))
1818 return;
1819 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1820 if (!PHANDLE_VALID(mpic))
1821 return;
1822
1823 /* check if proper rev of u3 */
1824 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
1825 == PROM_ERROR)
1826 return;
1827 if (u3_rev < 0x35 || u3_rev > 0x39)
1828 return;
1829 /* does it need fixup ? */
1830 if (prom_getproplen(i2c, "interrupts") > 0)
1831 return;
1832
1833 prom_printf("fixing up bogus interrupts for u3 i2c...\n");
1834
1835 /* interrupt on this revision of u3 is number 0 and level */
1836 interrupts[0] = 0;
1837 interrupts[1] = 1;
1838 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1839 parent = (u32)mpic;
1840 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1841}
1842
1843
1844static void __init prom_find_boot_cpu(void)
1845{
1846 unsigned long offset = reloc_offset();
1847 struct prom_t *_prom = PTRRELOC(&prom);
1848 u32 getprop_rval;
1849 ihandle prom_cpu;
1850 phandle cpu_pkg;
1851
1852 if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
1853 prom_panic("cannot find boot cpu");
1854
1855 cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
1856
1857 prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
1858 _prom->cpu = getprop_rval;
1859
1860 prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
1861}
1862
1863static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1864{
1865#ifdef CONFIG_BLK_DEV_INITRD
1866 unsigned long offset = reloc_offset();
1867 struct prom_t *_prom = PTRRELOC(&prom);
1868
1869 if ( r3 && r4 && r4 != 0xdeadbeef) {
1870 u64 val;
1871
1872 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
1873 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1874
1875 val = (u64)RELOC(prom_initrd_start);
1876 prom_setprop(_prom->chosen, "linux,initrd-start", &val, sizeof(val));
1877 val = (u64)RELOC(prom_initrd_end);
1878 prom_setprop(_prom->chosen, "linux,initrd-end", &val, sizeof(val));
1879
1880 reserve_mem(RELOC(prom_initrd_start),
1881 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
1882
1883 prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
1884 prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
1885 }
1886#endif /* CONFIG_BLK_DEV_INITRD */
1887}
1888
1889/*
1890 * We enter here early on, when the Open Firmware prom is still
1891 * handling exceptions and the MMU hash table for us.
1892 */
1893
1894unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
1895 unsigned long r6, unsigned long r7)
1896{
1897 unsigned long offset = reloc_offset();
1898 struct prom_t *_prom = PTRRELOC(&prom);
1899 unsigned long phys = KERNELBASE - offset;
1900 u32 getprop_rval;
1901
1902 /*
1903 * First zero the BSS
1904 */
1905 memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
1906
1907 /*
1908 * Init interface to Open Firmware, get some node references,
1909 * like /chosen
1910 */
1911 prom_init_client_services(pp);
1912
1913 /*
1914 * Init prom stdout device
1915 */
1916 prom_init_stdout();
1917 prom_debug("klimit=0x%x\n", RELOC(klimit));
1918 prom_debug("offset=0x%x\n", offset);
1919
1920 /*
1921 * Check for an initrd
1922 */
1923 prom_check_initrd(r3, r4);
1924
1925 /*
1926 * Get default machine type. At this point, we do not differenciate
1927 * between pSeries SMP and pSeries LPAR
1928 */
1929 RELOC(of_platform) = prom_find_machine_type();
1930 getprop_rval = RELOC(of_platform);
1931 prom_setprop(_prom->chosen, "linux,platform",
1932 &getprop_rval, sizeof(getprop_rval));
1933
1934 /*
1935 * On pSeries, inform the firmware about our capabilities
1936 */
1937 if (RELOC(of_platform) == PLATFORM_PSERIES ||
1938 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
1939 prom_send_capabilities();
1940
1941 /*
1942 * On pSeries and Cell, copy the CPU hold code
1943 */
1944 if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_CELL))
1945 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1946
1947 /*
1948 * Get memory cells format
1949 */
1950 getprop_rval = 1;
1951 prom_getprop(_prom->root, "#size-cells",
1952 &getprop_rval, sizeof(getprop_rval));
1953 _prom->root_size_cells = getprop_rval;
1954 getprop_rval = 2;
1955 prom_getprop(_prom->root, "#address-cells",
1956 &getprop_rval, sizeof(getprop_rval));
1957 _prom->root_addr_cells = getprop_rval;
1958
1959 /*
1960 * Do early parsing of command line
1961 */
1962 early_cmdline_parse();
1963
1964 /*
1965 * Initialize memory management within prom_init
1966 */
1967 prom_init_mem();
1968
1969 /*
1970 * Determine which cpu is actually running right _now_
1971 */
1972 prom_find_boot_cpu();
1973
1974 /*
1975 * Initialize display devices
1976 */
1977 prom_check_displays();
1978
1979 /*
1980 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
1981 * that uses the allocator, we need to make sure we get the top of memory
1982 * available for us here...
1983 */
1984 if (RELOC(of_platform) == PLATFORM_PSERIES)
1985 prom_initialize_tce_table();
1986
1987 /*
1988 * On non-powermacs, try to instantiate RTAS and puts all CPUs
1989 * in spin-loops. PowerMacs don't have a working RTAS and use
1990 * a different way to spin CPUs
1991 */
1992 if (RELOC(of_platform) != PLATFORM_POWERMAC) {
1993 prom_instantiate_rtas();
1994 prom_hold_cpus();
1995 }
1996
1997 /*
1998 * Fill in some infos for use by the kernel later on
1999 */
2000 if (RELOC(ppc64_iommu_off))
2001 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
2002
2003 if (RELOC(iommu_force_on))
2004 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
2005
2006 if (RELOC(prom_memory_limit))
2007 prom_setprop(_prom->chosen, "linux,memory-limit",
2008 PTRRELOC(&prom_memory_limit), sizeof(RELOC(prom_memory_limit)));
2009
2010 if (RELOC(prom_tce_alloc_start)) {
2011 prom_setprop(_prom->chosen, "linux,tce-alloc-start",
2012 PTRRELOC(&prom_tce_alloc_start), sizeof(RELOC(prom_tce_alloc_start)));
2013 prom_setprop(_prom->chosen, "linux,tce-alloc-end",
2014 PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
2015 }
2016
2017 /*
2018 * Fixup any known bugs in the device-tree
2019 */
2020 fixup_device_tree();
2021
2022 /*
2023 * Now finally create the flattened device-tree
2024 */
2025 prom_printf("copying OF device tree ...\n");
2026 flatten_device_tree();
2027
2028 /* in case stdin is USB and still active on IBM machines... */
2029 prom_close_stdin();
2030
2031 /*
2032 * Call OF "quiesce" method to shut down pending DMA's from
2033 * devices etc...
2034 */
2035 prom_printf("Calling quiesce ...\n");
2036 call_prom("quiesce", 0, 0);
2037
2038 /*
2039 * And finally, call the kernel passing it the flattened device
2040 * tree and NULL as r5, thus triggering the new entry point which
2041 * is common to us and kexec
2042 */
2043 prom_printf("returning from prom_init\n");
2044 prom_debug("->dt_header_start=0x%x\n", RELOC(dt_header_start));
2045 prom_debug("->phys=0x%x\n", phys);
2046
2047 __start(RELOC(dt_header_start), phys, 0);
2048
2049 return 0;
2050}
2051
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
deleted file mode 100644
index 79e7ed2858dd..000000000000
--- a/arch/ppc64/kernel/rtc.c
+++ /dev/null
@@ -1,358 +0,0 @@
1/*
2 * Real Time Clock interface for PPC64.
3 *
4 * Based on rtc.c by Paul Gortmaker
5 *
6 * This driver allows use of the real time clock
7 * from user space. It exports the /dev/rtc
8 * interface supporting various ioctl() and also the
9 * /proc/driver/rtc pseudo-file for status information.
10 *
11 * Interface does not support RTC interrupts nor an alarm.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
17 *
18 * 1.0 Mike Corrigan: IBM iSeries rtc support
19 * 1.1 Dave Engebretsen: IBM pSeries rtc support
20 */
21
22#define RTC_VERSION "1.1"
23
24#include <linux/config.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/types.h>
28#include <linux/miscdevice.h>
29#include <linux/ioport.h>
30#include <linux/fcntl.h>
31#include <linux/mc146818rtc.h>
32#include <linux/init.h>
33#include <linux/poll.h>
34#include <linux/proc_fs.h>
35#include <linux/spinlock.h>
36#include <linux/bcd.h>
37#include <linux/interrupt.h>
38#include <linux/delay.h>
39
40#include <asm/io.h>
41#include <asm/uaccess.h>
42#include <asm/system.h>
43#include <asm/time.h>
44#include <asm/rtas.h>
45
46#include <asm/machdep.h>
47
48/*
49 * We sponge a minor off of the misc major. No need slurping
50 * up another valuable major dev number for this. If you add
51 * an ioctl, make sure you don't conflict with SPARC's RTC
52 * ioctls.
53 */
54
55static ssize_t rtc_read(struct file *file, char __user *buf,
56 size_t count, loff_t *ppos);
57
58static int rtc_ioctl(struct inode *inode, struct file *file,
59 unsigned int cmd, unsigned long arg);
60
61static int rtc_read_proc(char *page, char **start, off_t off,
62 int count, int *eof, void *data);
63
64/*
65 * If this driver ever becomes modularised, it will be really nice
66 * to make the epoch retain its value across module reload...
67 */
68
69static unsigned long epoch = 1900; /* year corresponding to 0x00 */
70
71static const unsigned char days_in_mo[] =
72{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
73
74/*
75 * Now all the various file operations that we export.
76 */
77
78static ssize_t rtc_read(struct file *file, char __user *buf,
79 size_t count, loff_t *ppos)
80{
81 return -EIO;
82}
83
84static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
85 unsigned long arg)
86{
87 struct rtc_time wtime;
88
89 switch (cmd) {
90 case RTC_RD_TIME: /* Read the time/date from RTC */
91 {
92 memset(&wtime, 0, sizeof(struct rtc_time));
93 ppc_md.get_rtc_time(&wtime);
94 break;
95 }
96 case RTC_SET_TIME: /* Set the RTC */
97 {
98 struct rtc_time rtc_tm;
99 unsigned char mon, day, hrs, min, sec, leap_yr;
100 unsigned int yrs;
101
102 if (!capable(CAP_SYS_TIME))
103 return -EACCES;
104
105 if (copy_from_user(&rtc_tm, (struct rtc_time __user *)arg,
106 sizeof(struct rtc_time)))
107 return -EFAULT;
108
109 yrs = rtc_tm.tm_year;
110 mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
111 day = rtc_tm.tm_mday;
112 hrs = rtc_tm.tm_hour;
113 min = rtc_tm.tm_min;
114 sec = rtc_tm.tm_sec;
115
116 if (yrs < 70)
117 return -EINVAL;
118
119 leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
120
121 if ((mon > 12) || (day == 0))
122 return -EINVAL;
123
124 if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
125 return -EINVAL;
126
127 if ((hrs >= 24) || (min >= 60) || (sec >= 60))
128 return -EINVAL;
129
130 if ( yrs > 169 )
131 return -EINVAL;
132
133 ppc_md.set_rtc_time(&rtc_tm);
134
135 return 0;
136 }
137 case RTC_EPOCH_READ: /* Read the epoch. */
138 {
139 return put_user (epoch, (unsigned long __user *)arg);
140 }
141 case RTC_EPOCH_SET: /* Set the epoch. */
142 {
143 /*
144 * There were no RTC clocks before 1900.
145 */
146 if (arg < 1900)
147 return -EINVAL;
148
149 if (!capable(CAP_SYS_TIME))
150 return -EACCES;
151
152 epoch = arg;
153 return 0;
154 }
155 default:
156 return -EINVAL;
157 }
158 return copy_to_user((void __user *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
159}
160
161static int rtc_open(struct inode *inode, struct file *file)
162{
163 nonseekable_open(inode, file);
164 return 0;
165}
166
167static int rtc_release(struct inode *inode, struct file *file)
168{
169 return 0;
170}
171
172/*
173 * The various file operations we support.
174 */
175static struct file_operations rtc_fops = {
176 .owner = THIS_MODULE,
177 .llseek = no_llseek,
178 .read = rtc_read,
179 .ioctl = rtc_ioctl,
180 .open = rtc_open,
181 .release = rtc_release,
182};
183
184static struct miscdevice rtc_dev = {
185 .minor = RTC_MINOR,
186 .name = "rtc",
187 .fops = &rtc_fops
188};
189
190static int __init rtc_init(void)
191{
192 int retval;
193
194 retval = misc_register(&rtc_dev);
195 if(retval < 0)
196 return retval;
197
198#ifdef CONFIG_PROC_FS
199 if (create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)
200 == NULL) {
201 misc_deregister(&rtc_dev);
202 return -ENOMEM;
203 }
204#endif
205
206 printk(KERN_INFO "i/pSeries Real Time Clock Driver v" RTC_VERSION "\n");
207
208 return 0;
209}
210
211static void __exit rtc_exit (void)
212{
213 remove_proc_entry ("driver/rtc", NULL);
214 misc_deregister(&rtc_dev);
215}
216
217module_init(rtc_init);
218module_exit(rtc_exit);
219
220/*
221 * Info exported via "/proc/driver/rtc".
222 */
223
224static int rtc_proc_output (char *buf)
225{
226
227 char *p;
228 struct rtc_time tm;
229
230 p = buf;
231
232 ppc_md.get_rtc_time(&tm);
233
234 /*
235 * There is no way to tell if the luser has the RTC set for local
236 * time or for Universal Standard Time (GMT). Probably local though.
237 */
238 p += sprintf(p,
239 "rtc_time\t: %02d:%02d:%02d\n"
240 "rtc_date\t: %04d-%02d-%02d\n"
241 "rtc_epoch\t: %04lu\n",
242 tm.tm_hour, tm.tm_min, tm.tm_sec,
243 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
244
245 p += sprintf(p,
246 "DST_enable\t: no\n"
247 "BCD\t\t: yes\n"
248 "24hr\t\t: yes\n" );
249
250 return p - buf;
251}
252
253static int rtc_read_proc(char *page, char **start, off_t off,
254 int count, int *eof, void *data)
255{
256 int len = rtc_proc_output (page);
257 if (len <= off+count) *eof = 1;
258 *start = page + off;
259 len -= off;
260 if (len>count) len = count;
261 if (len<0) len = 0;
262 return len;
263}
264
265#ifdef CONFIG_PPC_RTAS
266#define MAX_RTC_WAIT 5000 /* 5 sec */
267#define RTAS_CLOCK_BUSY (-2)
268unsigned long rtas_get_boot_time(void)
269{
270 int ret[8];
271 int error, wait_time;
272 unsigned long max_wait_tb;
273
274 max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
275 do {
276 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
277 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
278 wait_time = rtas_extended_busy_delay_time(error);
279 /* This is boot time so we spin. */
280 udelay(wait_time*1000);
281 error = RTAS_CLOCK_BUSY;
282 }
283 } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
284
285 if (error != 0 && printk_ratelimit()) {
286 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
287 error);
288 return 0;
289 }
290
291 return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
292}
293
294/* NOTE: get_rtc_time will get an error if executed in interrupt context
295 * and if a delay is needed to read the clock. In this case we just
296 * silently return without updating rtc_tm.
297 */
298void rtas_get_rtc_time(struct rtc_time *rtc_tm)
299{
300 int ret[8];
301 int error, wait_time;
302 unsigned long max_wait_tb;
303
304 max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
305 do {
306 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
307 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
308 if (in_interrupt() && printk_ratelimit()) {
309 printk(KERN_WARNING "error: reading clock would delay interrupt\n");
310 return; /* delay not allowed */
311 }
312 wait_time = rtas_extended_busy_delay_time(error);
313 msleep_interruptible(wait_time);
314 error = RTAS_CLOCK_BUSY;
315 }
316 } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
317
318 if (error != 0 && printk_ratelimit()) {
319 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
320 error);
321 return;
322 }
323
324 rtc_tm->tm_sec = ret[5];
325 rtc_tm->tm_min = ret[4];
326 rtc_tm->tm_hour = ret[3];
327 rtc_tm->tm_mday = ret[2];
328 rtc_tm->tm_mon = ret[1] - 1;
329 rtc_tm->tm_year = ret[0] - 1900;
330}
331
332int rtas_set_rtc_time(struct rtc_time *tm)
333{
334 int error, wait_time;
335 unsigned long max_wait_tb;
336
337 max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
338 do {
339 error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
340 tm->tm_year + 1900, tm->tm_mon + 1,
341 tm->tm_mday, tm->tm_hour, tm->tm_min,
342 tm->tm_sec, 0);
343 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
344 if (in_interrupt())
345 return 1; /* probably decrementer */
346 wait_time = rtas_extended_busy_delay_time(error);
347 msleep_interruptible(wait_time);
348 error = RTAS_CLOCK_BUSY;
349 }
350 } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
351
352 if (error != 0 && printk_ratelimit())
353 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
354 error);
355
356 return 0;
357}
358#endif
diff --git a/arch/ppc64/kernel/semaphore.c b/arch/ppc64/kernel/semaphore.c
deleted file mode 100644
index a1c1db573e9c..000000000000
--- a/arch/ppc64/kernel/semaphore.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 *
3 *
4 * PowerPC-specific semaphore code.
5 *
6 * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
14 * to eliminate the SMP races in the old version between the updates
15 * of `count' and `waking'. Now we use negative `count' values to
16 * indicate that some process(es) are waiting for the semaphore.
17 */
18
19#include <linux/sched.h>
20#include <linux/init.h>
21#include <linux/module.h>
22
23#include <asm/atomic.h>
24#include <asm/semaphore.h>
25#include <asm/errno.h>
26
27/*
28 * Atomically update sem->count.
29 * This does the equivalent of the following:
30 *
31 * old_count = sem->count;
32 * tmp = MAX(old_count, 0) + incr;
33 * sem->count = tmp;
34 * return old_count;
35 */
36static inline int __sem_update_count(struct semaphore *sem, int incr)
37{
38 int old_count, tmp;
39
40 __asm__ __volatile__("\n"
41"1: lwarx %0,0,%3\n"
42" srawi %1,%0,31\n"
43" andc %1,%0,%1\n"
44" add %1,%1,%4\n"
45" stwcx. %1,0,%3\n"
46" bne 1b"
47 : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
48 : "r" (&sem->count), "r" (incr), "m" (sem->count)
49 : "cc");
50
51 return old_count;
52}
53
54void __up(struct semaphore *sem)
55{
56 /*
57 * Note that we incremented count in up() before we came here,
58 * but that was ineffective since the result was <= 0, and
59 * any negative value of count is equivalent to 0.
60 * This ends up setting count to 1, unless count is now > 0
61 * (i.e. because some other cpu has called up() in the meantime),
62 * in which case we just increment count.
63 */
64 __sem_update_count(sem, 1);
65 wake_up(&sem->wait);
66}
67EXPORT_SYMBOL(__up);
68
69/*
70 * Note that when we come in to __down or __down_interruptible,
71 * we have already decremented count, but that decrement was
72 * ineffective since the result was < 0, and any negative value
73 * of count is equivalent to 0.
74 * Thus it is only when we decrement count from some value > 0
75 * that we have actually got the semaphore.
76 */
77void __sched __down(struct semaphore *sem)
78{
79 struct task_struct *tsk = current;
80 DECLARE_WAITQUEUE(wait, tsk);
81
82 __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
83 add_wait_queue_exclusive(&sem->wait, &wait);
84
85 /*
86 * Try to get the semaphore. If the count is > 0, then we've
87 * got the semaphore; we decrement count and exit the loop.
88 * If the count is 0 or negative, we set it to -1, indicating
89 * that we are asleep, and then sleep.
90 */
91 while (__sem_update_count(sem, -1) <= 0) {
92 schedule();
93 set_task_state(tsk, TASK_UNINTERRUPTIBLE);
94 }
95 remove_wait_queue(&sem->wait, &wait);
96 __set_task_state(tsk, TASK_RUNNING);
97
98 /*
99 * If there are any more sleepers, wake one of them up so
100 * that it can either get the semaphore, or set count to -1
101 * indicating that there are still processes sleeping.
102 */
103 wake_up(&sem->wait);
104}
105EXPORT_SYMBOL(__down);
106
107int __sched __down_interruptible(struct semaphore * sem)
108{
109 int retval = 0;
110 struct task_struct *tsk = current;
111 DECLARE_WAITQUEUE(wait, tsk);
112
113 __set_task_state(tsk, TASK_INTERRUPTIBLE);
114 add_wait_queue_exclusive(&sem->wait, &wait);
115
116 while (__sem_update_count(sem, -1) <= 0) {
117 if (signal_pending(current)) {
118 /*
119 * A signal is pending - give up trying.
120 * Set sem->count to 0 if it is negative,
121 * since we are no longer sleeping.
122 */
123 __sem_update_count(sem, 0);
124 retval = -EINTR;
125 break;
126 }
127 schedule();
128 set_task_state(tsk, TASK_INTERRUPTIBLE);
129 }
130 remove_wait_queue(&sem->wait, &wait);
131 __set_task_state(tsk, TASK_RUNNING);
132
133 wake_up(&sem->wait);
134 return retval;
135}
136EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
deleted file mode 100644
index 1bbacac44988..000000000000
--- a/arch/ppc64/kernel/vdso.c
+++ /dev/null
@@ -1,625 +0,0 @@
1/*
2 * linux/arch/ppc64/kernel/vdso.c
3 *
4 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/errno.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/stddef.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/user.h>
25#include <linux/elf.h>
26#include <linux/security.h>
27#include <linux/bootmem.h>
28
29#include <asm/pgtable.h>
30#include <asm/system.h>
31#include <asm/processor.h>
32#include <asm/mmu.h>
33#include <asm/mmu_context.h>
34#include <asm/machdep.h>
35#include <asm/cputable.h>
36#include <asm/sections.h>
37#include <asm/systemcfg.h>
38#include <asm/vdso.h>
39
40#undef DEBUG
41
42#ifdef DEBUG
43#define DBG(fmt...) printk(fmt)
44#else
45#define DBG(fmt...)
46#endif
47
48
49/*
50 * The vDSOs themselves are here
51 */
52extern char vdso64_start, vdso64_end;
53extern char vdso32_start, vdso32_end;
54
55static void *vdso64_kbase = &vdso64_start;
56static void *vdso32_kbase = &vdso32_start;
57
58unsigned int vdso64_pages;
59unsigned int vdso32_pages;
60
61/* Signal trampolines user addresses */
62
63unsigned long vdso64_rt_sigtramp;
64unsigned long vdso32_sigtramp;
65unsigned long vdso32_rt_sigtramp;
66
67/* Format of the patch table */
68struct vdso_patch_def
69{
70 u32 pvr_mask, pvr_value;
71 const char *gen_name;
72 const char *fix_name;
73};
74
75/* Table of functions to patch based on the CPU type/revision
76 *
77 * TODO: Improve by adding whole lists for each entry
78 */
79static struct vdso_patch_def vdso_patches[] = {
80 {
81 0xffff0000, 0x003a0000, /* POWER5 */
82 "__kernel_sync_dicache", "__kernel_sync_dicache_p5"
83 },
84 {
85 0xffff0000, 0x003b0000, /* POWER5 */
86 "__kernel_sync_dicache", "__kernel_sync_dicache_p5"
87 },
88};
89
90/*
91 * Some infos carried around for each of them during parsing at
92 * boot time.
93 */
94struct lib32_elfinfo
95{
96 Elf32_Ehdr *hdr; /* ptr to ELF */
97 Elf32_Sym *dynsym; /* ptr to .dynsym section */
98 unsigned long dynsymsize; /* size of .dynsym section */
99 char *dynstr; /* ptr to .dynstr section */
100 unsigned long text; /* offset of .text section in .so */
101};
102
103struct lib64_elfinfo
104{
105 Elf64_Ehdr *hdr;
106 Elf64_Sym *dynsym;
107 unsigned long dynsymsize;
108 char *dynstr;
109 unsigned long text;
110};
111
112
113#ifdef __DEBUG
114static void dump_one_vdso_page(struct page *pg, struct page *upg)
115{
116 printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
117 page_count(pg),
118 pg->flags);
119 if (upg/* && pg != upg*/) {
120 printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) << PAGE_SHIFT),
121 page_count(upg),
122 upg->flags);
123 }
124 printk("\n");
125}
126
127static void dump_vdso_pages(struct vm_area_struct * vma)
128{
129 int i;
130
131 if (!vma || test_thread_flag(TIF_32BIT)) {
132 printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase);
133 for (i=0; i<vdso32_pages; i++) {
134 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
135 struct page *upg = (vma && vma->vm_mm) ?
136 follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0)
137 : NULL;
138 dump_one_vdso_page(pg, upg);
139 }
140 }
141 if (!vma || !test_thread_flag(TIF_32BIT)) {
142 printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase);
143 for (i=0; i<vdso64_pages; i++) {
144 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
145 struct page *upg = (vma && vma->vm_mm) ?
146 follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0)
147 : NULL;
148 dump_one_vdso_page(pg, upg);
149 }
150 }
151}
152#endif /* DEBUG */
153
154/*
155 * Keep a dummy vma_close for now, it will prevent VMA merging.
156 */
157static void vdso_vma_close(struct vm_area_struct * vma)
158{
159}
160
161/*
162 * Our nopage() function, maps in the actual vDSO kernel pages, they will
163 * be mapped read-only by do_no_page(), and eventually COW'ed, either
164 * right away for an initial write access, or by do_wp_page().
165 */
166static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
167 unsigned long address, int *type)
168{
169 unsigned long offset = address - vma->vm_start;
170 struct page *pg;
171 void *vbase = test_thread_flag(TIF_32BIT) ? vdso32_kbase : vdso64_kbase;
172
173 DBG("vdso_vma_nopage(current: %s, address: %016lx, off: %lx)\n",
174 current->comm, address, offset);
175
176 if (address < vma->vm_start || address > vma->vm_end)
177 return NOPAGE_SIGBUS;
178
179 /*
180 * Last page is systemcfg.
181 */
182 if ((vma->vm_end - address) <= PAGE_SIZE)
183 pg = virt_to_page(_systemcfg);
184 else
185 pg = virt_to_page(vbase + offset);
186
187 get_page(pg);
188 DBG(" ->page count: %d\n", page_count(pg));
189
190 return pg;
191}
192
193static struct vm_operations_struct vdso_vmops = {
194 .close = vdso_vma_close,
195 .nopage = vdso_vma_nopage,
196};
197
198/*
199 * This is called from binfmt_elf, we create the special vma for the
200 * vDSO and insert it into the mm struct tree
201 */
202int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
203{
204 struct mm_struct *mm = current->mm;
205 struct vm_area_struct *vma;
206 unsigned long vdso_pages;
207 unsigned long vdso_base;
208
209 if (test_thread_flag(TIF_32BIT)) {
210 vdso_pages = vdso32_pages;
211 vdso_base = VDSO32_MBASE;
212 } else {
213 vdso_pages = vdso64_pages;
214 vdso_base = VDSO64_MBASE;
215 }
216
217 current->thread.vdso_base = 0;
218
219 /* vDSO has a problem and was disabled, just don't "enable" it for the
220 * process
221 */
222 if (vdso_pages == 0)
223 return 0;
224
225 vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
226 if (vma == NULL)
227 return -ENOMEM;
228
229 memset(vma, 0, sizeof(*vma));
230
231 /*
232 * pick a base address for the vDSO in process space. We try to put it
233 * at vdso_base which is the "natural" base for it, but we might fail
234 * and end up putting it elsewhere.
235 */
236 vdso_base = get_unmapped_area(NULL, vdso_base,
237 vdso_pages << PAGE_SHIFT, 0, 0);
238 if (vdso_base & ~PAGE_MASK) {
239 kmem_cache_free(vm_area_cachep, vma);
240 return (int)vdso_base;
241 }
242
243 current->thread.vdso_base = vdso_base;
244
245 vma->vm_mm = mm;
246 vma->vm_start = current->thread.vdso_base;
247
248 /*
249 * the VMA size is one page more than the vDSO since systemcfg
250 * is mapped in the last one
251 */
252 vma->vm_end = vma->vm_start + ((vdso_pages + 1) << PAGE_SHIFT);
253
254 /*
255 * our vma flags don't have VM_WRITE so by default, the process isn't allowed
256 * to write those pages.
257 * gdb can break that with ptrace interface, and thus trigger COW on those
258 * pages but it's then your responsibility to never do that on the "data" page
259 * of the vDSO or you'll stop getting kernel updates and your nice userland
260 * gettimeofday will be totally dead. It's fine to use that for setting
261 * breakpoints in the vDSO code pages though
262 */
263 vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | VM_RESERVED;
264 vma->vm_flags |= mm->def_flags;
265 vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
266 vma->vm_ops = &vdso_vmops;
267
268 down_write(&mm->mmap_sem);
269 if (insert_vm_struct(mm, vma)) {
270 up_write(&mm->mmap_sem);
271 kmem_cache_free(vm_area_cachep, vma);
272 return -ENOMEM;
273 }
274 mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
275 up_write(&mm->mmap_sem);
276
277 return 0;
278}
279
280static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
281 unsigned long *size)
282{
283 Elf32_Shdr *sechdrs;
284 unsigned int i;
285 char *secnames;
286
287 /* Grab section headers and strings so we can tell who is who */
288 sechdrs = (void *)ehdr + ehdr->e_shoff;
289 secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
290
291 /* Find the section they want */
292 for (i = 1; i < ehdr->e_shnum; i++) {
293 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
294 if (size)
295 *size = sechdrs[i].sh_size;
296 return (void *)ehdr + sechdrs[i].sh_offset;
297 }
298 }
299 *size = 0;
300 return NULL;
301}
302
303static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname,
304 unsigned long *size)
305{
306 Elf64_Shdr *sechdrs;
307 unsigned int i;
308 char *secnames;
309
310 /* Grab section headers and strings so we can tell who is who */
311 sechdrs = (void *)ehdr + ehdr->e_shoff;
312 secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
313
314 /* Find the section they want */
315 for (i = 1; i < ehdr->e_shnum; i++) {
316 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
317 if (size)
318 *size = sechdrs[i].sh_size;
319 return (void *)ehdr + sechdrs[i].sh_offset;
320 }
321 }
322 if (size)
323 *size = 0;
324 return NULL;
325}
326
327static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib, const char *symname)
328{
329 unsigned int i;
330 char name[32], *c;
331
332 for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
333 if (lib->dynsym[i].st_name == 0)
334 continue;
335 strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32);
336 c = strchr(name, '@');
337 if (c)
338 *c = 0;
339 if (strcmp(symname, name) == 0)
340 return &lib->dynsym[i];
341 }
342 return NULL;
343}
344
345static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib, const char *symname)
346{
347 unsigned int i;
348 char name[32], *c;
349
350 for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) {
351 if (lib->dynsym[i].st_name == 0)
352 continue;
353 strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32);
354 c = strchr(name, '@');
355 if (c)
356 *c = 0;
357 if (strcmp(symname, name) == 0)
358 return &lib->dynsym[i];
359 }
360 return NULL;
361}
362
363/* Note that we assume the section is .text and the symbol is relative to
364 * the library base
365 */
366static unsigned long __init find_function32(struct lib32_elfinfo *lib, const char *symname)
367{
368 Elf32_Sym *sym = find_symbol32(lib, symname);
369
370 if (sym == NULL) {
371 printk(KERN_WARNING "vDSO32: function %s not found !\n", symname);
372 return 0;
373 }
374 return sym->st_value - VDSO32_LBASE;
375}
376
377/* Note that we assume the section is .text and the symbol is relative to
378 * the library base
379 */
380static unsigned long __init find_function64(struct lib64_elfinfo *lib, const char *symname)
381{
382 Elf64_Sym *sym = find_symbol64(lib, symname);
383
384 if (sym == NULL) {
385 printk(KERN_WARNING "vDSO64: function %s not found !\n", symname);
386 return 0;
387 }
388#ifdef VDS64_HAS_DESCRIPTORS
389 return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) - VDSO64_LBASE;
390#else
391 return sym->st_value - VDSO64_LBASE;
392#endif
393}
394
395
396static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
397 struct lib64_elfinfo *v64)
398{
399 void *sect;
400
401 /*
402 * Locate symbol tables & text section
403 */
404
405 v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);
406 v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);
407 if (v32->dynsym == NULL || v32->dynstr == NULL) {
408 printk(KERN_ERR "vDSO32: a required symbol section was not found\n");
409 return -1;
410 }
411 sect = find_section32(v32->hdr, ".text", NULL);
412 if (sect == NULL) {
413 printk(KERN_ERR "vDSO32: the .text section was not found\n");
414 return -1;
415 }
416 v32->text = sect - vdso32_kbase;
417
418 v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);
419 v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL);
420 if (v64->dynsym == NULL || v64->dynstr == NULL) {
421 printk(KERN_ERR "vDSO64: a required symbol section was not found\n");
422 return -1;
423 }
424 sect = find_section64(v64->hdr, ".text", NULL);
425 if (sect == NULL) {
426 printk(KERN_ERR "vDSO64: the .text section was not found\n");
427 return -1;
428 }
429 v64->text = sect - vdso64_kbase;
430
431 return 0;
432}
433
434static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
435 struct lib64_elfinfo *v64)
436{
437 /*
438 * Find signal trampolines
439 */
440
441 vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64");
442 vdso32_sigtramp = find_function32(v32, "__kernel_sigtramp32");
443 vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
444}
445
446static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
447 struct lib64_elfinfo *v64)
448{
449 Elf32_Sym *sym32;
450 Elf64_Sym *sym64;
451
452 sym32 = find_symbol32(v32, "__kernel_datapage_offset");
453 if (sym32 == NULL) {
454 printk(KERN_ERR "vDSO32: Can't find symbol __kernel_datapage_offset !\n");
455 return -1;
456 }
457 *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
458 (vdso32_pages << PAGE_SHIFT) - (sym32->st_value - VDSO32_LBASE);
459
460 sym64 = find_symbol64(v64, "__kernel_datapage_offset");
461 if (sym64 == NULL) {
462 printk(KERN_ERR "vDSO64: Can't find symbol __kernel_datapage_offset !\n");
463 return -1;
464 }
465 *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
466 (vdso64_pages << PAGE_SHIFT) - (sym64->st_value - VDSO64_LBASE);
467
468 return 0;
469}
470
471static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
472 struct lib64_elfinfo *v64,
473 const char *orig, const char *fix)
474{
475 Elf32_Sym *sym32_gen, *sym32_fix;
476
477 sym32_gen = find_symbol32(v32, orig);
478 if (sym32_gen == NULL) {
479 printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig);
480 return -1;
481 }
482 sym32_fix = find_symbol32(v32, fix);
483 if (sym32_fix == NULL) {
484 printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix);
485 return -1;
486 }
487 sym32_gen->st_value = sym32_fix->st_value;
488 sym32_gen->st_size = sym32_fix->st_size;
489 sym32_gen->st_info = sym32_fix->st_info;
490 sym32_gen->st_other = sym32_fix->st_other;
491 sym32_gen->st_shndx = sym32_fix->st_shndx;
492
493 return 0;
494}
495
496static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
497 struct lib64_elfinfo *v64,
498 const char *orig, const char *fix)
499{
500 Elf64_Sym *sym64_gen, *sym64_fix;
501
502 sym64_gen = find_symbol64(v64, orig);
503 if (sym64_gen == NULL) {
504 printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig);
505 return -1;
506 }
507 sym64_fix = find_symbol64(v64, fix);
508 if (sym64_fix == NULL) {
509 printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix);
510 return -1;
511 }
512 sym64_gen->st_value = sym64_fix->st_value;
513 sym64_gen->st_size = sym64_fix->st_size;
514 sym64_gen->st_info = sym64_fix->st_info;
515 sym64_gen->st_other = sym64_fix->st_other;
516 sym64_gen->st_shndx = sym64_fix->st_shndx;
517
518 return 0;
519}
520
521static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
522 struct lib64_elfinfo *v64)
523{
524 u32 pvr;
525 int i;
526
527 pvr = mfspr(SPRN_PVR);
528 for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) {
529 struct vdso_patch_def *patch = &vdso_patches[i];
530 int match = (pvr & patch->pvr_mask) == patch->pvr_value;
531
532 DBG("patch %d (mask: %x, pvr: %x) : %s\n",
533 i, patch->pvr_mask, patch->pvr_value, match ? "match" : "skip");
534
535 if (!match)
536 continue;
537
538 DBG("replacing %s with %s...\n", patch->gen_name, patch->fix_name);
539
540 /*
541 * Patch the 32 bits and 64 bits symbols. Note that we do not patch
542 * the "." symbol on 64 bits. It would be easy to do, but doesn't
543 * seem to be necessary, patching the OPD symbol is enough.
544 */
545 vdso_do_func_patch32(v32, v64, patch->gen_name, patch->fix_name);
546 vdso_do_func_patch64(v32, v64, patch->gen_name, patch->fix_name);
547 }
548
549 return 0;
550}
551
552
553static __init int vdso_setup(void)
554{
555 struct lib32_elfinfo v32;
556 struct lib64_elfinfo v64;
557
558 v32.hdr = vdso32_kbase;
559 v64.hdr = vdso64_kbase;
560
561 if (vdso_do_find_sections(&v32, &v64))
562 return -1;
563
564 if (vdso_fixup_datapage(&v32, &v64))
565 return -1;
566
567 if (vdso_fixup_alt_funcs(&v32, &v64))
568 return -1;
569
570 vdso_setup_trampolines(&v32, &v64);
571
572 return 0;
573}
574
575void __init vdso_init(void)
576{
577 int i;
578
579 vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
580 vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
581
582 DBG("vdso64_kbase: %p, 0x%x pages, vdso32_kbase: %p, 0x%x pages\n",
583 vdso64_kbase, vdso64_pages, vdso32_kbase, vdso32_pages);
584
585 /*
586 * Initialize the vDSO images in memory, that is do necessary
587 * fixups of vDSO symbols, locate trampolines, etc...
588 */
589 if (vdso_setup()) {
590 printk(KERN_ERR "vDSO setup failure, not enabled !\n");
591 /* XXX should free pages here ? */
592 vdso64_pages = vdso32_pages = 0;
593 return;
594 }
595
596 /* Make sure pages are in the correct state */
597 for (i = 0; i < vdso64_pages; i++) {
598 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
599 ClearPageReserved(pg);
600 get_page(pg);
601 }
602 for (i = 0; i < vdso32_pages; i++) {
603 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
604 ClearPageReserved(pg);
605 get_page(pg);
606 }
607
608 get_page(virt_to_page(_systemcfg));
609}
610
611int in_gate_area_no_task(unsigned long addr)
612{
613 return 0;
614}
615
616int in_gate_area(struct task_struct *task, unsigned long addr)
617{
618 return 0;
619}
620
621struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
622{
623 return NULL;
624}
625
diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
deleted file mode 100644
index 022f220e772f..000000000000
--- a/arch/ppc64/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,151 +0,0 @@
1#include <asm/page.h>
2#include <asm-generic/vmlinux.lds.h>
3
4OUTPUT_ARCH(powerpc:common64)
5jiffies = jiffies_64;
6SECTIONS
7{
8 /* Sections to be discarded. */
9 /DISCARD/ : {
10 *(.exitcall.exit)
11 }
12
13
14 /* Read-only sections, merged into text segment: */
15 .text : {
16 *(.text .text.*)
17 SCHED_TEXT
18 LOCK_TEXT
19 KPROBES_TEXT
20 *(.fixup)
21 . = ALIGN(PAGE_SIZE);
22 _etext = .;
23 }
24
25 __ex_table : {
26 __start___ex_table = .;
27 *(__ex_table)
28 __stop___ex_table = .;
29 }
30
31 __bug_table : {
32 __start___bug_table = .;
33 *(__bug_table)
34 __stop___bug_table = .;
35 }
36
37 __ftr_fixup : {
38 __start___ftr_fixup = .;
39 *(__ftr_fixup)
40 __stop___ftr_fixup = .;
41 }
42
43 RODATA
44
45
46 /* will be freed after init */
47 . = ALIGN(PAGE_SIZE);
48 __init_begin = .;
49
50 .init.text : {
51 _sinittext = .;
52 *(.init.text)
53 _einittext = .;
54 }
55
56 .init.data : {
57 *(.init.data)
58 }
59
60 . = ALIGN(16);
61 .init.setup : {
62 __setup_start = .;
63 *(.init.setup)
64 __setup_end = .;
65 }
66
67 .initcall.init : {
68 __initcall_start = .;
69 *(.initcall1.init)
70 *(.initcall2.init)
71 *(.initcall3.init)
72 *(.initcall4.init)
73 *(.initcall5.init)
74 *(.initcall6.init)
75 *(.initcall7.init)
76 __initcall_end = .;
77 }
78
79 .con_initcall.init : {
80 __con_initcall_start = .;
81 *(.con_initcall.init)
82 __con_initcall_end = .;
83 }
84
85 SECURITY_INIT
86
87 . = ALIGN(PAGE_SIZE);
88 .init.ramfs : {
89 __initramfs_start = .;
90 *(.init.ramfs)
91 __initramfs_end = .;
92 }
93
94 .data.percpu : {
95 __per_cpu_start = .;
96 *(.data.percpu)
97 __per_cpu_end = .;
98 }
99
100 . = ALIGN(PAGE_SIZE);
101 . = ALIGN(16384);
102 __init_end = .;
103 /* freed after init ends here */
104
105
106 /* Read/write sections */
107 . = ALIGN(PAGE_SIZE);
108 . = ALIGN(16384);
109 _sdata = .;
110 /* The initial task and kernel stack */
111 .data.init_task : {
112 *(.data.init_task)
113 }
114
115 . = ALIGN(PAGE_SIZE);
116 .data.page_aligned : {
117 *(.data.page_aligned)
118 }
119
120 .data.cacheline_aligned : {
121 *(.data.cacheline_aligned)
122 }
123
124 .data : {
125 *(.data .data.rel* .toc1)
126 *(.branch_lt)
127 }
128
129 .opd : {
130 *(.opd)
131 }
132
133 .got : {
134 __toc_start = .;
135 *(.got)
136 *(.toc)
137 . = ALIGN(PAGE_SIZE);
138 _edata = .;
139 }
140
141
142 . = ALIGN(PAGE_SIZE);
143 .bss : {
144 __bss_start = .;
145 *(.bss)
146 __bss_stop = .;
147 }
148
149 . = ALIGN(PAGE_SIZE);
150 _end = . ;
151}
diff --git a/arch/ppc64/xmon/privinst.h b/arch/ppc64/xmon/privinst.h
deleted file mode 100644
index 02eb40dac0b3..000000000000
--- a/arch/ppc64/xmon/privinst.h
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#define GETREG(reg) \
11 static inline unsigned long get_ ## reg (void) \
12 { unsigned long ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
13
14#define SETREG(reg) \
15 static inline void set_ ## reg (unsigned long val) \
16 { asm volatile ("mt" #reg " %0" : : "r" (val)); }
17
18GETREG(msr)
19SETREG(msrd)
20GETREG(cr)
21
22#define GSETSPR(n, name) \
23 static inline long get_ ## name (void) \
24 { long ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
25 static inline void set_ ## name (long val) \
26 { asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
27
28GSETSPR(0, mq)
29GSETSPR(1, xer)
30GSETSPR(4, rtcu)
31GSETSPR(5, rtcl)
32GSETSPR(8, lr)
33GSETSPR(9, ctr)
34GSETSPR(18, dsisr)
35GSETSPR(19, dar)
36GSETSPR(22, dec)
37GSETSPR(25, sdr1)
38GSETSPR(26, srr0)
39GSETSPR(27, srr1)
40GSETSPR(272, sprg0)
41GSETSPR(273, sprg1)
42GSETSPR(274, sprg2)
43GSETSPR(275, sprg3)
44GSETSPR(282, ear)
45GSETSPR(287, pvr)
46GSETSPR(1008, hid0)
47GSETSPR(1009, hid1)
48GSETSPR(1010, iabr)
49GSETSPR(1023, pir)
50
51static inline void store_inst(void *p)
52{
53 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
54}
55
56static inline void cflush(void *p)
57{
58 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
59}
60
61static inline void cinval(void *p)
62{
63 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
64}
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 2e64e8c3e8e5..cb3cf0f22822 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -37,17 +37,43 @@ int __atomic_add_return(int i, atomic_t *v)
37 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 37 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
38 return ret; 38 return ret;
39} 39}
40EXPORT_SYMBOL(__atomic_add_return);
40 41
41void atomic_set(atomic_t *v, int i) 42int atomic_cmpxchg(atomic_t *v, int old, int new)
42{ 43{
44 int ret;
43 unsigned long flags; 45 unsigned long flags;
46
44 spin_lock_irqsave(ATOMIC_HASH(v), flags); 47 spin_lock_irqsave(ATOMIC_HASH(v), flags);
48 ret = v->counter;
49 if (likely(ret == old))
50 v->counter = new;
45 51
46 v->counter = i; 52 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
53 return ret;
54}
55
56int atomic_add_unless(atomic_t *v, int a, int u)
57{
58 int ret;
59 unsigned long flags;
47 60
61 spin_lock_irqsave(ATOMIC_HASH(v), flags);
62 ret = v->counter;
63 if (ret != u)
64 v->counter += a;
48 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 65 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
66 return ret != u;
49} 67}
50 68
51EXPORT_SYMBOL(__atomic_add_return); 69static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
52EXPORT_SYMBOL(atomic_set); 70/* Atomic operations are already serializing */
71void atomic_set(atomic_t *v, int i)
72{
73 unsigned long flags;
53 74
75 spin_lock_irqsave(ATOMIC_HASH(v), flags);
76 v->counter = i;
77 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
78}
79EXPORT_SYMBOL(atomic_set);
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
index 94b05e8c906c..2e168d16547f 100644
--- a/arch/sparc/lib/bitext.c
+++ b/arch/sparc/lib/bitext.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
13#include <linux/string.h>
13#include <linux/bitops.h> 14#include <linux/bitops.h>
14 15
15#include <asm/bitext.h> 16#include <asm/bitext.h>
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 3b5f47c46907..563301fe5df8 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -7,7 +7,6 @@ config UML
7 bool 7 bool
8 default y 8 default y
9 9
10# XXX: does UM have a mmu/swap?
11config MMU 10config MMU
12 bool 11 bool
13 default y 12 default y
@@ -36,12 +35,6 @@ config IRQ_RELEASE_METHOD
36 bool 35 bool
37 default y 36 default y
38 37
39menu "Host processor type and features"
40
41source "arch/i386/Kconfig.cpu"
42
43endmenu
44
45menu "UML-specific options" 38menu "UML-specific options"
46 39
47config MODE_TT 40config MODE_TT
@@ -209,7 +202,8 @@ config MAGIC_SYSRQ
209config SMP 202config SMP
210 bool "Symmetric multi-processing support (EXPERIMENTAL)" 203 bool "Symmetric multi-processing support (EXPERIMENTAL)"
211 default n 204 default n
212 depends on (MODE_TT && EXPERIMENTAL && !SMP_BROKEN) || (BROKEN && SMP_BROKEN) 205 #SMP_BROKEN is for x86_64.
206 depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
213 help 207 help
214 This option enables UML SMP support. 208 This option enables UML SMP support.
215 It is NOT related to having a real SMP box. Not directly, at least. 209 It is NOT related to having a real SMP box. Not directly, at least.
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index 5d92cacd56c6..c71b39a677aa 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -1,3 +1,9 @@
1menu "Host processor type and features"
2
3source "arch/i386/Kconfig.cpu"
4
5endmenu
6
1config UML_X86 7config UML_X86
2 bool 8 bool
3 default y 9 default y
@@ -42,7 +48,3 @@ config ARCH_HAS_SC_SIGNALS
42config ARCH_REUSE_HOST_VSYSCALL_AREA 48config ARCH_REUSE_HOST_VSYSCALL_AREA
43 bool 49 bool
44 default y 50 default y
45
46config X86_CMPXCHG
47 bool
48 default y
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 1f7dcb064aee..7a0e04e34bf9 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -35,4 +35,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
35 35
36CFLAGS += $(cflags-y) 36CFLAGS += $(cflags-y)
37USER_CFLAGS += $(cflags-y) 37USER_CFLAGS += $(cflags-y)
38
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 16e7dc89f61d..5b58fad45290 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -89,8 +89,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
89 return(-EIO); 89 return(-EIO);
90} 90}
91 91
92static int not_configged_console_write(int fd, const char *buf, int len, 92static int not_configged_console_write(int fd, const char *buf, int len)
93 void *data)
94{ 93{
95 my_puts("Using a channel type which is configured out of " 94 my_puts("Using a channel type which is configured out of "
96 "UML\n"); 95 "UML\n");
@@ -299,7 +298,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
299 chan = list_entry(ele, struct chan, list); 298 chan = list_entry(ele, struct chan, list);
300 if(!chan->output || (chan->ops->console_write == NULL)) 299 if(!chan->output || (chan->ops->console_write == NULL))
301 continue; 300 continue;
302 n = chan->ops->console_write(chan->fd, buf, len, chan->data); 301 n = chan->ops->console_write(chan->fd, buf, len);
303 if(chan->primary) ret = n; 302 if(chan->primary) ret = n;
304 } 303 }
305 return(ret); 304 return(ret);
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 1c55d5802489..5d50d4a44abf 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -20,7 +20,7 @@
20#include "choose-mode.h" 20#include "choose-mode.h"
21#include "mode.h" 21#include "mode.h"
22 22
23int generic_console_write(int fd, const char *buf, int n, void *unused) 23int generic_console_write(int fd, const char *buf, int n)
24{ 24{
25 struct termios save, new; 25 struct termios save, new;
26 int err; 26 int err;
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index c1b03f7c1daa..1bb085b2824d 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -98,7 +98,7 @@ static int connect_to_switch(struct daemon_data *pri)
98 printk("daemon_open : control setup request failed, err = %d\n", 98 printk("daemon_open : control setup request failed, err = %d\n",
99 -n); 99 -n);
100 err = -ENOTCONN; 100 err = -ENOTCONN;
101 goto out; 101 goto out_free;
102 } 102 }
103 103
104 n = os_read_file(pri->control, sun, sizeof(*sun)); 104 n = os_read_file(pri->control, sun, sizeof(*sun));
@@ -106,12 +106,14 @@ static int connect_to_switch(struct daemon_data *pri)
106 printk("daemon_open : read of data socket failed, err = %d\n", 106 printk("daemon_open : read of data socket failed, err = %d\n",
107 -n); 107 -n);
108 err = -ENOTCONN; 108 err = -ENOTCONN;
109 goto out_close; 109 goto out_free;
110 } 110 }
111 111
112 pri->data_addr = sun; 112 pri->data_addr = sun;
113 return(fd); 113 return(fd);
114 114
115 out_free:
116 kfree(sun);
115 out_close: 117 out_close:
116 os_close_file(fd); 118 os_close_file(fd);
117 out: 119 out:
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index f0b888f66e05..3296e86a03a5 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -76,13 +76,6 @@ static void fd_close(int fd, void *d)
76 } 76 }
77} 77}
78 78
79static int fd_console_write(int fd, const char *buf, int n, void *d)
80{
81 struct fd_chan *data = d;
82
83 return(generic_console_write(fd, buf, n, &data->tt));
84}
85
86struct chan_ops fd_ops = { 79struct chan_ops fd_ops = {
87 .type = "fd", 80 .type = "fd",
88 .init = fd_init, 81 .init = fd_init,
@@ -90,7 +83,7 @@ struct chan_ops fd_ops = {
90 .close = fd_close, 83 .close = fd_close,
91 .read = generic_read, 84 .read = generic_read,
92 .write = generic_write, 85 .write = generic_write,
93 .console_write = fd_console_write, 86 .console_write = generic_console_write,
94 .window_size = generic_window_size, 87 .window_size = generic_window_size,
95 .free = generic_free, 88 .free = generic_free,
96 .winch = 1, 89 .winch = 1,
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 5db136e2651c..afe85bfa66e0 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -54,7 +54,7 @@ static int mcast_open(void *data)
54 struct mcast_data *pri = data; 54 struct mcast_data *pri = data;
55 struct sockaddr_in *sin = pri->mcast_addr; 55 struct sockaddr_in *sin = pri->mcast_addr;
56 struct ip_mreq mreq; 56 struct ip_mreq mreq;
57 int fd, yes = 1, err = 0; 57 int fd, yes = 1, err = -EINVAL;
58 58
59 59
60 if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) 60 if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
@@ -63,40 +63,40 @@ static int mcast_open(void *data)
63 fd = socket(AF_INET, SOCK_DGRAM, 0); 63 fd = socket(AF_INET, SOCK_DGRAM, 0);
64 64
65 if (fd < 0){ 65 if (fd < 0){
66 err = -errno;
66 printk("mcast_open : data socket failed, errno = %d\n", 67 printk("mcast_open : data socket failed, errno = %d\n",
67 errno); 68 errno);
68 err = -errno;
69 goto out; 69 goto out;
70 } 70 }
71 71
72 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { 72 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
73 err = -errno;
73 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", 74 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
74 errno); 75 errno);
75 err = -errno;
76 goto out_close; 76 goto out_close;
77 } 77 }
78 78
79 /* set ttl according to config */ 79 /* set ttl according to config */
80 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl, 80 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
81 sizeof(pri->ttl)) < 0) { 81 sizeof(pri->ttl)) < 0) {
82 err = -errno;
82 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", 83 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
83 errno); 84 errno);
84 err = -errno;
85 goto out_close; 85 goto out_close;
86 } 86 }
87 87
88 /* set LOOP, so data does get fed back to local sockets */ 88 /* set LOOP, so data does get fed back to local sockets */
89 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { 89 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
90 err = -errno;
90 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", 91 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
91 errno); 92 errno);
92 err = -errno;
93 goto out_close; 93 goto out_close;
94 } 94 }
95 95
96 /* bind socket to mcast address */ 96 /* bind socket to mcast address */
97 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { 97 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
98 printk("mcast_open : data bind failed, errno = %d\n", errno);
99 err = -errno; 98 err = -errno;
99 printk("mcast_open : data bind failed, errno = %d\n", errno);
100 goto out_close; 100 goto out_close;
101 } 101 }
102 102
@@ -105,22 +105,22 @@ static int mcast_open(void *data)
105 mreq.imr_interface.s_addr = 0; 105 mreq.imr_interface.s_addr = 0;
106 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 106 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
107 &mreq, sizeof(mreq)) < 0) { 107 &mreq, sizeof(mreq)) < 0) {
108 err = -errno;
108 printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n", 109 printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
109 errno); 110 errno);
110 printk("There appears not to be a multicast-capable network " 111 printk("There appears not to be a multicast-capable network "
111 "interface on the host.\n"); 112 "interface on the host.\n");
112 printk("eth0 should be configured in order to use the " 113 printk("eth0 should be configured in order to use the "
113 "multicast transport.\n"); 114 "multicast transport.\n");
114 err = -errno; 115 goto out_close;
115 goto out_close;
116 } 116 }
117 117
118 return fd; 118 return fd;
119 119
120 out_close: 120 out_close:
121 os_close_file(fd); 121 os_close_file(fd);
122 out: 122 out:
123 return err; 123 return err;
124} 124}
125 125
126static void mcast_close(int fd, void *data) 126static void mcast_close(int fd, void *data)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index ed4a1a6c5d83..c43e8bb32502 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -100,13 +100,6 @@ static void port_close(int fd, void *d)
100 os_close_file(fd); 100 os_close_file(fd);
101} 101}
102 102
103static int port_console_write(int fd, const char *buf, int n, void *d)
104{
105 struct port_chan *data = d;
106
107 return(generic_console_write(fd, buf, n, &data->tt));
108}
109
110struct chan_ops port_ops = { 103struct chan_ops port_ops = {
111 .type = "port", 104 .type = "port",
112 .init = port_init, 105 .init = port_init,
@@ -114,7 +107,7 @@ struct chan_ops port_ops = {
114 .close = port_close, 107 .close = port_close,
115 .read = generic_read, 108 .read = generic_read,
116 .write = generic_write, 109 .write = generic_write,
117 .console_write = port_console_write, 110 .console_write = generic_console_write,
118 .window_size = generic_window_size, 111 .window_size = generic_window_size,
119 .free = port_free, 112 .free = port_free,
120 .winch = 1, 113 .winch = 1,
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 0306a1b215b7..1c555c38de4d 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -118,13 +118,6 @@ static int pty_open(int input, int output, int primary, void *d,
118 return(fd); 118 return(fd);
119} 119}
120 120
121static int pty_console_write(int fd, const char *buf, int n, void *d)
122{
123 struct pty_chan *data = d;
124
125 return(generic_console_write(fd, buf, n, &data->tt));
126}
127
128struct chan_ops pty_ops = { 121struct chan_ops pty_ops = {
129 .type = "pty", 122 .type = "pty",
130 .init = pty_chan_init, 123 .init = pty_chan_init,
@@ -132,7 +125,7 @@ struct chan_ops pty_ops = {
132 .close = generic_close, 125 .close = generic_close,
133 .read = generic_read, 126 .read = generic_read,
134 .write = generic_write, 127 .write = generic_write,
135 .console_write = pty_console_write, 128 .console_write = generic_console_write,
136 .window_size = generic_window_size, 129 .window_size = generic_window_size,
137 .free = generic_free, 130 .free = generic_free,
138 .winch = 0, 131 .winch = 0,
@@ -145,7 +138,7 @@ struct chan_ops pts_ops = {
145 .close = generic_close, 138 .close = generic_close,
146 .read = generic_read, 139 .read = generic_read,
147 .write = generic_write, 140 .write = generic_write,
148 .console_write = pty_console_write, 141 .console_write = generic_console_write,
149 .window_size = generic_window_size, 142 .window_size = generic_window_size,
150 .free = generic_free, 143 .free = generic_free,
151 .winch = 0, 144 .winch = 0,
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index 6fbb670ee274..94c9265a4f2c 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -60,13 +60,6 @@ static int tty_open(int input, int output, int primary, void *d,
60 return(fd); 60 return(fd);
61} 61}
62 62
63static int tty_console_write(int fd, const char *buf, int n, void *d)
64{
65 struct tty_chan *data = d;
66
67 return(generic_console_write(fd, buf, n, &data->tt));
68}
69
70struct chan_ops tty_ops = { 63struct chan_ops tty_ops = {
71 .type = "tty", 64 .type = "tty",
72 .init = tty_chan_init, 65 .init = tty_chan_init,
@@ -74,7 +67,7 @@ struct chan_ops tty_ops = {
74 .close = generic_close, 67 .close = generic_close,
75 .read = generic_read, 68 .read = generic_read,
76 .write = generic_write, 69 .write = generic_write,
77 .console_write = tty_console_write, 70 .console_write = generic_console_write,
78 .window_size = generic_window_size, 71 .window_size = generic_window_size,
79 .free = generic_free, 72 .free = generic_free,
80 .winch = 0, 73 .winch = 0,
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index b530f1a6540d..aaa636661043 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -194,13 +194,6 @@ static void xterm_free(void *d)
194 free(d); 194 free(d);
195} 195}
196 196
197static int xterm_console_write(int fd, const char *buf, int n, void *d)
198{
199 struct xterm_chan *data = d;
200
201 return(generic_console_write(fd, buf, n, &data->tt));
202}
203
204struct chan_ops xterm_ops = { 197struct chan_ops xterm_ops = {
205 .type = "xterm", 198 .type = "xterm",
206 .init = xterm_init, 199 .init = xterm_init,
@@ -208,7 +201,7 @@ struct chan_ops xterm_ops = {
208 .close = xterm_close, 201 .close = xterm_close,
209 .read = generic_read, 202 .read = generic_read,
210 .write = generic_write, 203 .write = generic_write,
211 .console_write = xterm_console_write, 204 .console_write = generic_console_write,
212 .window_size = generic_window_size, 205 .window_size = generic_window_size,
213 .free = xterm_free, 206 .free = xterm_free,
214 .winch = 1, 207 .winch = 1,
diff --git a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h
index f77d9aa4c164..659bb3cac32f 100644
--- a/arch/um/include/chan_user.h
+++ b/arch/um/include/chan_user.h
@@ -25,7 +25,7 @@ struct chan_ops {
25 void (*close)(int, void *); 25 void (*close)(int, void *);
26 int (*read)(int, char *, void *); 26 int (*read)(int, char *, void *);
27 int (*write)(int, const char *, int, void *); 27 int (*write)(int, const char *, int, void *);
28 int (*console_write)(int, const char *, int, void *); 28 int (*console_write)(int, const char *, int);
29 int (*window_size)(int, void *, unsigned short *, unsigned short *); 29 int (*window_size)(int, void *, unsigned short *, unsigned short *);
30 void (*free)(void *); 30 void (*free)(void *);
31 int winch; 31 int winch;
@@ -37,7 +37,7 @@ extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
37extern void generic_close(int fd, void *unused); 37extern void generic_close(int fd, void *unused);
38extern int generic_read(int fd, char *c_out, void *unused); 38extern int generic_read(int fd, char *c_out, void *unused);
39extern int generic_write(int fd, const char *buf, int n, void *unused); 39extern int generic_write(int fd, const char *buf, int n, void *unused);
40extern int generic_console_write(int fd, const char *buf, int n, void *state); 40extern int generic_console_write(int fd, const char *buf, int n);
41extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, 41extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
42 unsigned short *cols_out); 42 unsigned short *cols_out);
43extern void generic_free(void *data); 43extern void generic_free(void *data);
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index 84c0868cd561..f8760a3f43b0 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -17,8 +17,25 @@
17#include "uaccess-skas.h" 17#include "uaccess-skas.h"
18#endif 18#endif
19 19
20#define __under_task_size(addr, size) \
21 (((unsigned long) (addr) < TASK_SIZE) && \
22 (((unsigned long) (addr) + (size)) < TASK_SIZE))
23
24#define __access_ok_vsyscall(type, addr, size) \
25 ((type == VERIFY_READ) && \
26 ((unsigned long) (addr) >= FIXADDR_USER_START) && \
27 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
28 ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
29
30#define __addr_range_nowrap(addr, size) \
31 ((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
32
20#define access_ok(type, addr, size) \ 33#define access_ok(type, addr, size) \
21 CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size) 34 (__addr_range_nowrap(addr, size) && \
35 (__under_task_size(addr, size) || \
36 __access_ok_vsyscall(type, addr, size) || \
37 segment_eq(get_fs(), KERNEL_DS) || \
38 CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
22 39
23static inline int copy_from_user(void *to, const void __user *from, int n) 40static inline int copy_from_user(void *to, const void __user *from, int n)
24{ 41{
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 7da0c2def0ef..f611f83ad4ff 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -9,14 +9,8 @@
9#include "asm/errno.h" 9#include "asm/errno.h"
10#include "asm/fixmap.h" 10#include "asm/fixmap.h"
11 11
12#define access_ok_skas(type, addr, size) \ 12/* No SKAS-specific checking. */
13 ((segment_eq(get_fs(), KERNEL_DS)) || \ 13#define access_ok_skas(type, addr, size) 0
14 (((unsigned long) (addr) < TASK_SIZE) && \
15 ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
16 ((type == VERIFY_READ ) && \
17 ((unsigned long) (addr) >= FIXADDR_USER_START) && \
18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
20 14
21extern int copy_from_user_skas(void *to, const void __user *from, int n); 15extern int copy_from_user_skas(void *to, const void __user *from, int n);
22extern int copy_to_user_skas(void __user *to, const void *from, int n); 16extern int copy_to_user_skas(void __user *to, const void *from, int n);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 75195281081e..a5a47528dec7 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -143,7 +143,7 @@ int copy_from_user_skas(void *to, const void __user *from, int n)
143 return(0); 143 return(0);
144 } 144 }
145 145
146 return(access_ok_skas(VERIFY_READ, from, n) ? 146 return(access_ok(VERIFY_READ, from, n) ?
147 buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): 147 buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
148 n); 148 n);
149} 149}
@@ -164,7 +164,7 @@ int copy_to_user_skas(void __user *to, const void *from, int n)
164 return(0); 164 return(0);
165 } 165 }
166 166
167 return(access_ok_skas(VERIFY_WRITE, to, n) ? 167 return(access_ok(VERIFY_WRITE, to, n) ?
168 buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : 168 buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
169 n); 169 n);
170} 170}
@@ -193,7 +193,7 @@ int strncpy_from_user_skas(char *dst, const char __user *src, int count)
193 return(strnlen(dst, count)); 193 return(strnlen(dst, count));
194 } 194 }
195 195
196 if(!access_ok_skas(VERIFY_READ, src, 1)) 196 if(!access_ok(VERIFY_READ, src, 1))
197 return(-EFAULT); 197 return(-EFAULT);
198 198
199 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 199 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
@@ -221,7 +221,7 @@ int clear_user_skas(void __user *mem, int len)
221 return(0); 221 return(0);
222 } 222 }
223 223
224 return(access_ok_skas(VERIFY_WRITE, mem, len) ? 224 return(access_ok(VERIFY_WRITE, mem, len) ?
225 buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len); 225 buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
226} 226}
227 227
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 95c8f8733baf..0d4c10a73607 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -95,7 +95,16 @@ survive:
95 pte = pte_offset_kernel(pmd, address); 95 pte = pte_offset_kernel(pmd, address);
96 } while(!pte_present(*pte)); 96 } while(!pte_present(*pte));
97 err = 0; 97 err = 0;
98 /* The below warning was added in place of
99 * pte_mkyoung(); if (is_write) pte_mkdirty();
100 * If it's triggered, we'd see normally a hang here (a clean pte is
101 * marked read-only to emulate the dirty bit).
102 * However, the generic code can mark a PTE writable but clean on a
103 * concurrent read fault, triggering this harmlessly. So comment it out.
104 */
105#if 0
98 WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte))); 106 WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
107#endif
99 flush_tlb_page(vma, address); 108 flush_tlb_page(vma, address);
100out: 109out:
101 up_read(&mm->mmap_sem); 110 up_read(&mm->mmap_sem);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index dc2ebfa8c54f..b9bfe9c481c4 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -19,19 +19,13 @@
19extern unsigned long end_vm; 19extern unsigned long end_vm;
20extern unsigned long uml_physmem; 20extern unsigned long uml_physmem;
21 21
22#define under_task_size(addr, size) \
23 (((unsigned long) (addr) < TASK_SIZE) && \
24 (((unsigned long) (addr) + (size)) < TASK_SIZE))
25
26#define is_stack(addr, size) \ 22#define is_stack(addr, size) \
27 (((unsigned long) (addr) < STACK_TOP) && \ 23 (((unsigned long) (addr) < STACK_TOP) && \
28 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \ 24 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
29 (((unsigned long) (addr) + (size)) <= STACK_TOP)) 25 (((unsigned long) (addr) + (size)) <= STACK_TOP))
30 26
31#define access_ok_tt(type, addr, size) \ 27#define access_ok_tt(type, addr, size) \
32 ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \ 28 (is_stack(addr, size))
33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
34 (under_task_size(addr, size) || is_stack(addr, size))))
35 29
36extern unsigned long get_fault_addr(void); 30extern unsigned long get_fault_addr(void);
37 31
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
index a72aa632972f..1cb60726567e 100644
--- a/arch/um/kernel/tt/uaccess.c
+++ b/arch/um/kernel/tt/uaccess.c
@@ -8,7 +8,7 @@
8 8
9int copy_from_user_tt(void *to, const void __user *from, int n) 9int copy_from_user_tt(void *to, const void __user *from, int n)
10{ 10{
11 if(!access_ok_tt(VERIFY_READ, from, n)) 11 if(!access_ok(VERIFY_READ, from, n))
12 return(n); 12 return(n);
13 13
14 return(__do_copy_from_user(to, from, n, &current->thread.fault_addr, 14 return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
@@ -17,7 +17,7 @@ int copy_from_user_tt(void *to, const void __user *from, int n)
17 17
18int copy_to_user_tt(void __user *to, const void *from, int n) 18int copy_to_user_tt(void __user *to, const void *from, int n)
19{ 19{
20 if(!access_ok_tt(VERIFY_WRITE, to, n)) 20 if(!access_ok(VERIFY_WRITE, to, n))
21 return(n); 21 return(n);
22 22
23 return(__do_copy_to_user(to, from, n, &current->thread.fault_addr, 23 return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
@@ -28,7 +28,7 @@ int strncpy_from_user_tt(char *dst, const char __user *src, int count)
28{ 28{
29 int n; 29 int n;
30 30
31 if(!access_ok_tt(VERIFY_READ, src, 1)) 31 if(!access_ok(VERIFY_READ, src, 1))
32 return(-EFAULT); 32 return(-EFAULT);
33 33
34 n = __do_strncpy_from_user(dst, src, count, 34 n = __do_strncpy_from_user(dst, src, count,
@@ -47,7 +47,7 @@ int __clear_user_tt(void __user *mem, int len)
47 47
48int clear_user_tt(void __user *mem, int len) 48int clear_user_tt(void __user *mem, int len)
49{ 49{
50 if(!access_ok_tt(VERIFY_WRITE, mem, len)) 50 if(!access_ok(VERIFY_WRITE, mem, len))
51 return(len); 51 return(len);
52 52
53 return(__do_clear_user(mem, len, &current->thread.fault_addr, 53 return(__do_clear_user(mem, len, &current->thread.fault_addr,
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 89c053b6c2c4..310865903234 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -23,6 +23,14 @@ config GENERIC_CALIBRATE_DELAY
23 bool 23 bool
24 default y 24 default y
25 25
26config GENERIC_HARDIRQS
27 bool
28 default y
29
30config GENERIC_IRQ_PROBE
31 bool
32 default y
33
26# Turn off some random 386 crap that can affect device config 34# Turn off some random 386 crap that can affect device config
27config ISA 35config ISA
28 bool 36 bool
diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
index 9e85969ba976..7a151c26f82e 100644
--- a/arch/v850/kernel/irq.c
+++ b/arch/v850/kernel/irq.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * arch/v850/kernel/irq.c -- High-level interrupt handling 2 * arch/v850/kernel/irq.c -- High-level interrupt handling
3 * 3 *
4 * Copyright (C) 2001,02,03,04 NEC Electronics Corporation 4 * Copyright (C) 2001,02,03,04,05 NEC Electronics Corporation
5 * Copyright (C) 2001,02,03,04 Miles Bader <miles@gnu.org> 5 * Copyright (C) 2001,02,03,04,05 Miles Bader <miles@gnu.org>
6 * Copyright (C) 1994-2000 Ralf Baechle 6 * Copyright (C) 1994-2000 Ralf Baechle
7 * Copyright (C) 1992 Linus Torvalds 7 * Copyright (C) 1992 Linus Torvalds
8 * 8 *
@@ -27,55 +27,15 @@
27#include <asm/system.h> 27#include <asm/system.h>
28 28
29/* 29/*
30 * Controller mappings for all interrupt sources: 30 * 'what should we do if we get a hw irq event on an illegal vector'.
31 * each architecture has to answer this themselves, it doesn't deserve
32 * a generic callback i think.
31 */ 33 */
32irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { 34void ack_bad_irq(unsigned int irq)
33 [0 ... NR_IRQS-1] = {
34 .handler = &no_irq_type,
35 .lock = SPIN_LOCK_UNLOCKED
36 }
37};
38
39/*
40 * Special irq handlers.
41 */
42
43irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
44{
45 return IRQ_NONE;
46}
47
48/*
49 * Generic no controller code
50 */
51
52static void enable_none(unsigned int irq) { }
53static unsigned int startup_none(unsigned int irq) { return 0; }
54static void disable_none(unsigned int irq) { }
55static void ack_none(unsigned int irq)
56{ 35{
57 /*
58 * 'what should we do if we get a hw irq event on an illegal vector'.
59 * each architecture has to answer this themselves, it doesn't deserve
60 * a generic callback i think.
61 */
62 printk("received IRQ %d with unknown interrupt type\n", irq); 36 printk("received IRQ %d with unknown interrupt type\n", irq);
63} 37}
64 38
65/* startup is the same as "enable", shutdown is same as "disable" */
66#define shutdown_none disable_none
67#define end_none enable_none
68
69struct hw_interrupt_type no_irq_type = {
70 .typename = "none",
71 .startup = startup_none,
72 .shutdown = shutdown_none,
73 .enable = enable_none,
74 .disable = disable_none,
75 .ack = ack_none,
76 .end = end_none
77};
78
79volatile unsigned long irq_err_count, spurious_count; 39volatile unsigned long irq_err_count, spurious_count;
80 40
81/* 41/*
@@ -84,643 +44,68 @@ volatile unsigned long irq_err_count, spurious_count;
84 44
85int show_interrupts(struct seq_file *p, void *v) 45int show_interrupts(struct seq_file *p, void *v)
86{ 46{
87 int i = *(loff_t *) v; 47 int irq = *(loff_t *) v;
88 struct irqaction * action;
89 unsigned long flags;
90 48
91 if (i == 0) { 49 if (irq == 0) {
50 int cpu;
92 seq_puts(p, " "); 51 seq_puts(p, " ");
93 for (i=0; i < 1 /*smp_num_cpus*/; i++) 52 for (cpu=0; cpu < 1 /*smp_num_cpus*/; cpu++)
94 seq_printf(p, "CPU%d ", i); 53 seq_printf(p, "CPU%d ", cpu);
95 seq_putc(p, '\n'); 54 seq_putc(p, '\n');
96 } 55 }
97 56
98 if (i < NR_IRQS) { 57 if (irq < NR_IRQS) {
99 int j, count, num; 58 unsigned long flags;
100 const char *type_name = irq_desc[i].handler->typename; 59 struct irqaction *action;
101 spin_lock_irqsave(&irq_desc[j].lock, flags);
102 action = irq_desc[i].action;
103 if (!action)
104 goto skip;
105 60
106 count = 0; 61 spin_lock_irqsave(&irq_desc[irq].lock, flags);
107 num = -1;
108 for (j = 0; j < NR_IRQS; j++)
109 if (irq_desc[j].handler->typename == type_name) {
110 if (i == j)
111 num = count;
112 count++;
113 }
114 62
115 seq_printf(p, "%3d: ",i); 63 action = irq_desc[irq].action;
116 seq_printf(p, "%10u ", kstat_irqs(i)); 64 if (action) {
117 if (count > 1) { 65 int j;
118 int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1); 66 int count = 0;
119 seq_printf(p, " %*s%d", 14 - prec, type_name, num); 67 int num = -1;
120 } else 68 const char *type_name = irq_desc[irq].handler->typename;
121 seq_printf(p, " %14s", type_name); 69
70 for (j = 0; j < NR_IRQS; j++)
71 if (irq_desc[j].handler->typename == type_name){
72 if (irq == j)
73 num = count;
74 count++;
75 }
76
77 seq_printf(p, "%3d: ",irq);
78 seq_printf(p, "%10u ", kstat_irqs(irq));
79 if (count > 1) {
80 int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
81 seq_printf(p, " %*s%d", 14 - prec,
82 type_name, num);
83 } else
84 seq_printf(p, " %14s", type_name);
122 85
123 seq_printf(p, " %s", action->name); 86 seq_printf(p, " %s", action->name);
124 for (action=action->next; action; action = action->next) 87 for (action=action->next; action; action = action->next)
125 seq_printf(p, ", %s", action->name); 88 seq_printf(p, ", %s", action->name);
126 seq_putc(p, '\n'); 89 seq_putc(p, '\n');
127skip: 90 }
128 spin_unlock_irqrestore(&irq_desc[j].lock, flags);
129 } else if (i == NR_IRQS)
130 seq_printf(p, "ERR: %10lu\n", irq_err_count);
131 return 0;
132}
133
134/*
135 * This should really return information about whether
136 * we should do bottom half handling etc. Right now we
137 * end up _always_ checking the bottom half, which is a
138 * waste of time and is not what some drivers would
139 * prefer.
140 */
141int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
142{
143 int status = 1; /* Force the "do bottom halves" bit */
144 int ret;
145
146 if (!(action->flags & SA_INTERRUPT))
147 local_irq_enable();
148
149 do {
150 ret = action->handler(irq, action->dev_id, regs);
151 if (ret == IRQ_HANDLED)
152 status |= action->flags;
153 action = action->next;
154 } while (action);
155 if (status & SA_SAMPLE_RANDOM)
156 add_interrupt_randomness(irq);
157 local_irq_disable();
158
159 return status;
160}
161
162/*
163 * Generic enable/disable code: this just calls
164 * down into the PIC-specific version for the actual
165 * hardware disable after having gotten the irq
166 * controller lock.
167 */
168
169/**
170 * disable_irq_nosync - disable an irq without waiting
171 * @irq: Interrupt to disable
172 *
173 * Disable the selected interrupt line. Disables of an interrupt
174 * stack. Unlike disable_irq(), this function does not ensure existing
175 * instances of the IRQ handler have completed before returning.
176 *
177 * This function may be called from IRQ context.
178 */
179
180void inline disable_irq_nosync(unsigned int irq)
181{
182 irq_desc_t *desc = irq_desc + irq;
183 unsigned long flags;
184
185 spin_lock_irqsave(&desc->lock, flags);
186 if (!desc->depth++) {
187 desc->status |= IRQ_DISABLED;
188 desc->handler->disable(irq);
189 }
190 spin_unlock_irqrestore(&desc->lock, flags);
191}
192
193/**
194 * disable_irq - disable an irq and wait for completion
195 * @irq: Interrupt to disable
196 *
197 * Disable the selected interrupt line. Disables of an interrupt
198 * stack. That is for two disables you need two enables. This
199 * function waits for any pending IRQ handlers for this interrupt
200 * to complete before returning. If you use this function while
201 * holding a resource the IRQ handler may need you will deadlock.
202 *
203 * This function may be called - with care - from IRQ context.
204 */
205
206void disable_irq(unsigned int irq)
207{
208 disable_irq_nosync(irq);
209 synchronize_irq(irq);
210}
211 91
212/** 92 spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
213 * enable_irq - enable interrupt handling on an irq 93 } else if (irq == NR_IRQS)
214 * @irq: Interrupt to enable 94 seq_printf(p, "ERR: %10lu\n", irq_err_count);
215 *
216 * Re-enables the processing of interrupts on this IRQ line
217 * providing no disable_irq calls are now in effect.
218 *
219 * This function may be called from IRQ context.
220 */
221
222void enable_irq(unsigned int irq)
223{
224 irq_desc_t *desc = irq_desc + irq;
225 unsigned long flags;
226 95
227 spin_lock_irqsave(&desc->lock, flags); 96 return 0;
228 switch (desc->depth) {
229 case 1: {
230 unsigned int status = desc->status & ~IRQ_DISABLED;
231 desc->status = status;
232 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
233 desc->status = status | IRQ_REPLAY;
234 hw_resend_irq(desc->handler,irq);
235 }
236 desc->handler->enable(irq);
237 /* fall-through */
238 }
239 default:
240 desc->depth--;
241 break;
242 case 0:
243 printk("enable_irq(%u) unbalanced from %p\n", irq,
244 __builtin_return_address(0));
245 }
246 spin_unlock_irqrestore(&desc->lock, flags);
247} 97}
248 98
249/* Handle interrupt IRQ. REGS are the registers at the time of ther 99/* Handle interrupt IRQ. REGS are the registers at the time of ther
250 interrupt. */ 100 interrupt. */
251unsigned int handle_irq (int irq, struct pt_regs *regs) 101unsigned int handle_irq (int irq, struct pt_regs *regs)
252{ 102{
253 /*
254 * We ack quickly, we don't want the irq controller
255 * thinking we're snobs just because some other CPU has
256 * disabled global interrupts (we have already done the
257 * INT_ACK cycles, it's too late to try to pretend to the
258 * controller that we aren't taking the interrupt).
259 *
260 * 0 return value means that this irq is already being
261 * handled by some other CPU. (or is disabled)
262 */
263 int cpu = smp_processor_id();
264 irq_desc_t *desc = irq_desc + irq;
265 struct irqaction * action;
266 unsigned int status;
267
268 irq_enter(); 103 irq_enter();
269 kstat_cpu(cpu).irqs[irq]++; 104 __do_IRQ(irq, regs);
270 spin_lock(&desc->lock);
271 desc->handler->ack(irq);
272 /*
273 REPLAY is when Linux resends an IRQ that was dropped earlier
274 WAITING is used by probe to mark irqs that are being tested
275 */
276 status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
277 status |= IRQ_PENDING; /* we _want_ to handle it */
278
279 /*
280 * If the IRQ is disabled for whatever reason, we cannot
281 * use the action we have.
282 */
283 action = NULL;
284 if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
285 action = desc->action;
286 status &= ~IRQ_PENDING; /* we commit to handling */
287 status |= IRQ_INPROGRESS; /* we are handling it */
288 }
289 desc->status = status;
290
291 /*
292 * If there is no IRQ handler or it was disabled, exit early.
293 Since we set PENDING, if another processor is handling
294 a different instance of this same irq, the other processor
295 will take care of it.
296 */
297 if (unlikely(!action))
298 goto out;
299
300 /*
301 * Edge triggered interrupts need to remember
302 * pending events.
303 * This applies to any hw interrupts that allow a second
304 * instance of the same irq to arrive while we are in handle_irq
305 * or in the handler. But the code here only handles the _second_
306 * instance of the irq, not the third or fourth. So it is mostly
307 * useful for irq hardware that does not mask cleanly in an
308 * SMP environment.
309 */
310 for (;;) {
311 spin_unlock(&desc->lock);
312 handle_IRQ_event(irq, regs, action);
313 spin_lock(&desc->lock);
314
315 if (likely(!(desc->status & IRQ_PENDING)))
316 break;
317 desc->status &= ~IRQ_PENDING;
318 }
319 desc->status &= ~IRQ_INPROGRESS;
320
321out:
322 /*
323 * The ->end() handler has to deal with interrupts which got
324 * disabled while the handler was running.
325 */
326 desc->handler->end(irq);
327 spin_unlock(&desc->lock);
328
329 irq_exit(); 105 irq_exit();
330
331 return 1; 106 return 1;
332} 107}
333 108
334/**
335 * request_irq - allocate an interrupt line
336 * @irq: Interrupt line to allocate
337 * @handler: Function to be called when the IRQ occurs
338 * @irqflags: Interrupt type flags
339 * @devname: An ascii name for the claiming device
340 * @dev_id: A cookie passed back to the handler function
341 *
342 * This call allocates interrupt resources and enables the
343 * interrupt line and IRQ handling. From the point this
344 * call is made your handler function may be invoked. Since
345 * your handler function must clear any interrupt the board
346 * raises, you must take care both to initialise your hardware
347 * and to set up the interrupt handler in the right order.
348 *
349 * Dev_id must be globally unique. Normally the address of the
350 * device data structure is used as the cookie. Since the handler
351 * receives this value it makes sense to use it.
352 *
353 * If your interrupt is shared you must pass a non NULL dev_id
354 * as this is required when freeing the interrupt.
355 *
356 * Flags:
357 *
358 * SA_SHIRQ Interrupt is shared
359 *
360 * SA_INTERRUPT Disable local interrupts while processing
361 *
362 * SA_SAMPLE_RANDOM The interrupt can be used for entropy
363 *
364 */
365
366int request_irq(unsigned int irq,
367 irqreturn_t (*handler)(int, void *, struct pt_regs *),
368 unsigned long irqflags,
369 const char * devname,
370 void *dev_id)
371{
372 int retval;
373 struct irqaction * action;
374
375#if 1
376 /*
377 * Sanity-check: shared interrupts should REALLY pass in
378 * a real dev-ID, otherwise we'll have trouble later trying
379 * to figure out which interrupt is which (messes up the
380 * interrupt freeing logic etc).
381 */
382 if (irqflags & SA_SHIRQ) {
383 if (!dev_id)
384 printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
385 }
386#endif
387
388 if (irq >= NR_IRQS)
389 return -EINVAL;
390 if (!handler)
391 return -EINVAL;
392
393 action = (struct irqaction *)
394 kmalloc(sizeof(struct irqaction), GFP_KERNEL);
395 if (!action)
396 return -ENOMEM;
397
398 action->handler = handler;
399 action->flags = irqflags;
400 cpus_clear(action->mask);
401 action->name = devname;
402 action->next = NULL;
403 action->dev_id = dev_id;
404
405 retval = setup_irq(irq, action);
406 if (retval)
407 kfree(action);
408 return retval;
409}
410
411EXPORT_SYMBOL(request_irq);
412
413/**
414 * free_irq - free an interrupt
415 * @irq: Interrupt line to free
416 * @dev_id: Device identity to free
417 *
418 * Remove an interrupt handler. The handler is removed and if the
419 * interrupt line is no longer in use by any driver it is disabled.
420 * On a shared IRQ the caller must ensure the interrupt is disabled
421 * on the card it drives before calling this function. The function
422 * does not return until any executing interrupts for this IRQ
423 * have completed.
424 *
425 * This function may be called from interrupt context.
426 *
427 * Bugs: Attempting to free an irq in a handler for the same irq hangs
428 * the machine.
429 */
430
431void free_irq(unsigned int irq, void *dev_id)
432{
433 irq_desc_t *desc;
434 struct irqaction **p;
435 unsigned long flags;
436
437 if (irq >= NR_IRQS)
438 return;
439
440 desc = irq_desc + irq;
441 spin_lock_irqsave(&desc->lock,flags);
442 p = &desc->action;
443 for (;;) {
444 struct irqaction * action = *p;
445 if (action) {
446 struct irqaction **pp = p;
447 p = &action->next;
448 if (action->dev_id != dev_id)
449 continue;
450
451 /* Found it - now remove it from the list of entries */
452 *pp = action->next;
453 if (!desc->action) {
454 desc->status |= IRQ_DISABLED;
455 desc->handler->shutdown(irq);
456 }
457 spin_unlock_irqrestore(&desc->lock,flags);
458
459 synchronize_irq(irq);
460 kfree(action);
461 return;
462 }
463 printk("Trying to free free IRQ%d\n",irq);
464 spin_unlock_irqrestore(&desc->lock,flags);
465 return;
466 }
467}
468
469EXPORT_SYMBOL(free_irq);
470
471/*
472 * IRQ autodetection code..
473 *
474 * This depends on the fact that any interrupt that
475 * comes in on to an unassigned handler will get stuck
476 * with "IRQ_WAITING" cleared and the interrupt
477 * disabled.
478 */
479
480static DECLARE_MUTEX(probe_sem);
481
482/**
483 * probe_irq_on - begin an interrupt autodetect
484 *
485 * Commence probing for an interrupt. The interrupts are scanned
486 * and a mask of potential interrupt lines is returned.
487 *
488 */
489
490unsigned long probe_irq_on(void)
491{
492 unsigned int i;
493 irq_desc_t *desc;
494 unsigned long val;
495 unsigned long delay;
496
497 down(&probe_sem);
498 /*
499 * something may have generated an irq long ago and we want to
500 * flush such a longstanding irq before considering it as spurious.
501 */
502 for (i = NR_IRQS-1; i > 0; i--) {
503 desc = irq_desc + i;
504
505 spin_lock_irq(&desc->lock);
506 if (!irq_desc[i].action)
507 irq_desc[i].handler->startup(i);
508 spin_unlock_irq(&desc->lock);
509 }
510
511 /* Wait for longstanding interrupts to trigger. */
512 for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
513 /* about 20ms delay */ barrier();
514
515 /*
516 * enable any unassigned irqs
517 * (we must startup again here because if a longstanding irq
518 * happened in the previous stage, it may have masked itself)
519 */
520 for (i = NR_IRQS-1; i > 0; i--) {
521 desc = irq_desc + i;
522
523 spin_lock_irq(&desc->lock);
524 if (!desc->action) {
525 desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
526 if (desc->handler->startup(i))
527 desc->status |= IRQ_PENDING;
528 }
529 spin_unlock_irq(&desc->lock);
530 }
531
532 /*
533 * Wait for spurious interrupts to trigger
534 */
535 for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
536 /* about 100ms delay */ barrier();
537
538 /*
539 * Now filter out any obviously spurious interrupts
540 */
541 val = 0;
542 for (i = 0; i < NR_IRQS; i++) {
543 irq_desc_t *desc = irq_desc + i;
544 unsigned int status;
545
546 spin_lock_irq(&desc->lock);
547 status = desc->status;
548
549 if (status & IRQ_AUTODETECT) {
550 /* It triggered already - consider it spurious. */
551 if (!(status & IRQ_WAITING)) {
552 desc->status = status & ~IRQ_AUTODETECT;
553 desc->handler->shutdown(i);
554 } else
555 if (i < 32)
556 val |= 1 << i;
557 }
558 spin_unlock_irq(&desc->lock);
559 }
560
561 return val;
562}
563
564EXPORT_SYMBOL(probe_irq_on);
565
566/*
567 * Return a mask of triggered interrupts (this
568 * can handle only legacy ISA interrupts).
569 */
570
571/**
572 * probe_irq_mask - scan a bitmap of interrupt lines
573 * @val: mask of interrupts to consider
574 *
575 * Scan the ISA bus interrupt lines and return a bitmap of
576 * active interrupts. The interrupt probe logic state is then
577 * returned to its previous value.
578 *
579 * Note: we need to scan all the irq's even though we will
580 * only return ISA irq numbers - just so that we reset them
581 * all to a known state.
582 */
583unsigned int probe_irq_mask(unsigned long val)
584{
585 int i;
586 unsigned int mask;
587
588 mask = 0;
589 for (i = 0; i < NR_IRQS; i++) {
590 irq_desc_t *desc = irq_desc + i;
591 unsigned int status;
592
593 spin_lock_irq(&desc->lock);
594 status = desc->status;
595
596 if (status & IRQ_AUTODETECT) {
597 if (i < 16 && !(status & IRQ_WAITING))
598 mask |= 1 << i;
599
600 desc->status = status & ~IRQ_AUTODETECT;
601 desc->handler->shutdown(i);
602 }
603 spin_unlock_irq(&desc->lock);
604 }
605 up(&probe_sem);
606
607 return mask & val;
608}
609
610/*
611 * Return the one interrupt that triggered (this can
612 * handle any interrupt source).
613 */
614
615/**
616 * probe_irq_off - end an interrupt autodetect
617 * @val: mask of potential interrupts (unused)
618 *
619 * Scans the unused interrupt lines and returns the line which
620 * appears to have triggered the interrupt. If no interrupt was
621 * found then zero is returned. If more than one interrupt is
622 * found then minus the first candidate is returned to indicate
623 * their is doubt.
624 *
625 * The interrupt probe logic state is returned to its previous
626 * value.
627 *
628 * BUGS: When used in a module (which arguably shouldnt happen)
629 * nothing prevents two IRQ probe callers from overlapping. The
630 * results of this are non-optimal.
631 */
632
633int probe_irq_off(unsigned long val)
634{
635 int i, irq_found, nr_irqs;
636
637 nr_irqs = 0;
638 irq_found = 0;
639 for (i = 0; i < NR_IRQS; i++) {
640 irq_desc_t *desc = irq_desc + i;
641 unsigned int status;
642
643 spin_lock_irq(&desc->lock);
644 status = desc->status;
645
646 if (status & IRQ_AUTODETECT) {
647 if (!(status & IRQ_WAITING)) {
648 if (!nr_irqs)
649 irq_found = i;
650 nr_irqs++;
651 }
652 desc->status = status & ~IRQ_AUTODETECT;
653 desc->handler->shutdown(i);
654 }
655 spin_unlock_irq(&desc->lock);
656 }
657 up(&probe_sem);
658
659 if (nr_irqs > 1)
660 irq_found = -irq_found;
661 return irq_found;
662}
663
664EXPORT_SYMBOL(probe_irq_off);
665
666/* this was setup_x86_irq but it seems pretty generic */
667int setup_irq(unsigned int irq, struct irqaction * new)
668{
669 int shared = 0;
670 unsigned long flags;
671 struct irqaction *old, **p;
672 irq_desc_t *desc = irq_desc + irq;
673
674 /*
675 * Some drivers like serial.c use request_irq() heavily,
676 * so we have to be careful not to interfere with a
677 * running system.
678 */
679 if (new->flags & SA_SAMPLE_RANDOM) {
680 /*
681 * This function might sleep, we want to call it first,
682 * outside of the atomic block.
683 * Yes, this might clear the entropy pool if the wrong
684 * driver is attempted to be loaded, without actually
685 * installing a new handler, but is this really a problem,
686 * only the sysadmin is able to do this.
687 */
688 rand_initialize_irq(irq);
689 }
690
691 /*
692 * The following block of code has to be executed atomically
693 */
694 spin_lock_irqsave(&desc->lock,flags);
695 p = &desc->action;
696 if ((old = *p) != NULL) {
697 /* Can't share interrupts unless both agree to */
698 if (!(old->flags & new->flags & SA_SHIRQ)) {
699 spin_unlock_irqrestore(&desc->lock,flags);
700 return -EBUSY;
701 }
702
703 /* add new interrupt at end of irq queue */
704 do {
705 p = &old->next;
706 old = *p;
707 } while (old);
708 shared = 1;
709 }
710
711 *p = new;
712
713 if (!shared) {
714 desc->depth = 0;
715 desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
716 desc->handler->startup(irq);
717 }
718 spin_unlock_irqrestore(&desc->lock,flags);
719
720 /* register_irq_proc(irq); */
721 return 0;
722}
723
724/* Initialize irq handling for IRQs. 109/* Initialize irq handling for IRQs.
725 BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL 110 BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
726 to IRQ_TYPE. An IRQ_TYPE of 0 means to use a generic interrupt type. */ 111 to IRQ_TYPE. An IRQ_TYPE of 0 means to use a generic interrupt type. */
@@ -736,9 +121,3 @@ init_irq_handlers (int base_irq, int num, int interval,
736 base_irq += interval; 121 base_irq += interval;
737 } 122 }
738} 123}
739
740#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
741void init_irq_proc(void)
742{
743}
744#endif /* CONFIG_PROC_FS && CONFIG_SYSCTL */
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 4cce2f6f170c..6ece645e4dbe 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -226,22 +226,42 @@ config SCHED_SMT
226 226
227source "kernel/Kconfig.preempt" 227source "kernel/Kconfig.preempt"
228 228
229config K8_NUMA 229config NUMA
230 bool "K8 NUMA support" 230 bool "Non Uniform Memory Access (NUMA) Support"
231 select NUMA
232 depends on SMP 231 depends on SMP
233 help 232 help
234 Enable NUMA (Non Unified Memory Architecture) support for 233 Enable NUMA (Non Uniform Memory Access) support. The kernel
235 AMD Opteron Multiprocessor systems. The kernel will try to allocate 234 will try to allocate memory used by a CPU on the local memory
236 memory used by a CPU on the local memory controller of the CPU 235 controller of the CPU and add some more NUMA awareness to the kernel.
237 and add some more NUMA awareness to the kernel. 236 This code is recommended on all multiprocessor Opteron systems.
238 This code is recommended on all multiprocessor Opteron systems 237 If the system is EM64T, you should say N unless your system is EM64T
239 and normally doesn't hurt on others. 238 NUMA.
239
240config K8_NUMA
241 bool "Old style AMD Opteron NUMA detection"
242 depends on NUMA
243 default y
244 help
245 Enable K8 NUMA node topology detection. You should say Y here if
246 you have a multi processor AMD K8 system. This uses an old
247 method to read the NUMA configurtion directly from the builtin
248 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
249 instead, which also takes priority if both are compiled in.
250
251# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig.
252
253config X86_64_ACPI_NUMA
254 bool "ACPI NUMA detection"
255 depends on NUMA
256 select ACPI
257 select ACPI_NUMA
258 default y
259 help
260 Enable ACPI SRAT based node topology detection.
240 261
241config NUMA_EMU 262config NUMA_EMU
242 bool "NUMA emulation support" 263 bool "NUMA emulation"
243 select NUMA 264 depends on NUMA
244 depends on SMP
245 help 265 help
246 Enable NUMA emulation. A flat machine will be split 266 Enable NUMA emulation. A flat machine will be split
247 into virtual nodes when booted with "numa=fake=N", where N is the 267 into virtual nodes when booted with "numa=fake=N", where N is the
@@ -252,9 +272,6 @@ config ARCH_DISCONTIGMEM_ENABLE
252 depends on NUMA 272 depends on NUMA
253 default y 273 default y
254 274
255config NUMA
256 bool
257 default n
258 275
259config ARCH_DISCONTIGMEM_ENABLE 276config ARCH_DISCONTIGMEM_ENABLE
260 def_bool y 277 def_bool y
@@ -374,6 +391,14 @@ config X86_MCE_INTEL
374 Additional support for intel specific MCE features such as 391 Additional support for intel specific MCE features such as
375 the thermal monitor. 392 the thermal monitor.
376 393
394config X86_MCE_AMD
395 bool "AMD MCE features"
396 depends on X86_MCE && X86_LOCAL_APIC
397 default y
398 help
399 Additional support for AMD specific MCE features such as
400 the DRAM Error Threshold.
401
377config PHYSICAL_START 402config PHYSICAL_START
378 hex "Physical address where the kernel is loaded" if EMBEDDED 403 hex "Physical address where the kernel is loaded" if EMBEDDED
379 default "0x100000" 404 default "0x100000"
@@ -502,7 +527,7 @@ config IA32_EMULATION
502 left. 527 left.
503 528
504config IA32_AOUT 529config IA32_AOUT
505 bool "IA32 a.out support" 530 tristate "IA32 a.out support"
506 depends on IA32_EMULATION 531 depends on IA32_EMULATION
507 help 532 help
508 Support old a.out binaries in the 32bit emulation. 533 Support old a.out binaries in the 32bit emulation.
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index d584ecc27ea1..e2c6e64a85ec 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -2,15 +2,6 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5# !SMP for now because the context switch early causes GPF in segment reloading
6# and the GS base checking does the wrong thing then, causing a hang.
7config CHECKING
8 bool "Additional run-time checks"
9 depends on DEBUG_KERNEL && !SMP
10 help
11 Enables some internal consistency checks for kernel debugging.
12 You should normally say N.
13
14config INIT_DEBUG 5config INIT_DEBUG
15 bool "Debug __init statements" 6 bool "Debug __init statements"
16 depends on DEBUG_KERNEL 7 depends on DEBUG_KERNEL
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index f8db7e500fbf..5d56542fb68f 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13-git11 3# Linux kernel version: 2.6.14-git7
4# Mon Sep 12 16:16:16 2005 4# Sat Nov 5 15:55:50 2005
5# 5#
6CONFIG_X86_64=y 6CONFIG_X86_64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -35,7 +35,7 @@ CONFIG_POSIX_MQUEUE=y
35# CONFIG_BSD_PROCESS_ACCT is not set 35# CONFIG_BSD_PROCESS_ACCT is not set
36CONFIG_SYSCTL=y 36CONFIG_SYSCTL=y
37# CONFIG_AUDIT is not set 37# CONFIG_AUDIT is not set
38# CONFIG_HOTPLUG is not set 38CONFIG_HOTPLUG=y
39CONFIG_KOBJECT_UEVENT=y 39CONFIG_KOBJECT_UEVENT=y
40CONFIG_IKCONFIG=y 40CONFIG_IKCONFIG=y
41CONFIG_IKCONFIG_PROC=y 41CONFIG_IKCONFIG_PROC=y
@@ -93,10 +93,11 @@ CONFIG_PREEMPT_NONE=y
93# CONFIG_PREEMPT_VOLUNTARY is not set 93# CONFIG_PREEMPT_VOLUNTARY is not set
94# CONFIG_PREEMPT is not set 94# CONFIG_PREEMPT is not set
95CONFIG_PREEMPT_BKL=y 95CONFIG_PREEMPT_BKL=y
96CONFIG_NUMA=y
96CONFIG_K8_NUMA=y 97CONFIG_K8_NUMA=y
98CONFIG_X86_64_ACPI_NUMA=y
97# CONFIG_NUMA_EMU is not set 99# CONFIG_NUMA_EMU is not set
98CONFIG_ARCH_DISCONTIGMEM_ENABLE=y 100CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
99CONFIG_NUMA=y
100CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y 101CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
101CONFIG_ARCH_SPARSEMEM_ENABLE=y 102CONFIG_ARCH_SPARSEMEM_ENABLE=y
102CONFIG_SELECT_MEMORY_MODEL=y 103CONFIG_SELECT_MEMORY_MODEL=y
@@ -107,9 +108,10 @@ CONFIG_DISCONTIGMEM=y
107CONFIG_FLAT_NODE_MEM_MAP=y 108CONFIG_FLAT_NODE_MEM_MAP=y
108CONFIG_NEED_MULTIPLE_NODES=y 109CONFIG_NEED_MULTIPLE_NODES=y
109# CONFIG_SPARSEMEM_STATIC is not set 110# CONFIG_SPARSEMEM_STATIC is not set
111CONFIG_SPLIT_PTLOCK_CPUS=4
110CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y 112CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
111CONFIG_HAVE_DEC_LOCK=y
112CONFIG_NR_CPUS=32 113CONFIG_NR_CPUS=32
114CONFIG_HOTPLUG_CPU=y
113CONFIG_HPET_TIMER=y 115CONFIG_HPET_TIMER=y
114CONFIG_X86_PM_TIMER=y 116CONFIG_X86_PM_TIMER=y
115CONFIG_HPET_EMULATE_RTC=y 117CONFIG_HPET_EMULATE_RTC=y
@@ -117,6 +119,7 @@ CONFIG_GART_IOMMU=y
117CONFIG_SWIOTLB=y 119CONFIG_SWIOTLB=y
118CONFIG_X86_MCE=y 120CONFIG_X86_MCE=y
119CONFIG_X86_MCE_INTEL=y 121CONFIG_X86_MCE_INTEL=y
122CONFIG_X86_MCE_AMD=y
120CONFIG_PHYSICAL_START=0x100000 123CONFIG_PHYSICAL_START=0x100000
121# CONFIG_KEXEC is not set 124# CONFIG_KEXEC is not set
122CONFIG_SECCOMP=y 125CONFIG_SECCOMP=y
@@ -136,11 +139,15 @@ CONFIG_PM=y
136# CONFIG_PM_DEBUG is not set 139# CONFIG_PM_DEBUG is not set
137CONFIG_SOFTWARE_SUSPEND=y 140CONFIG_SOFTWARE_SUSPEND=y
138CONFIG_PM_STD_PARTITION="" 141CONFIG_PM_STD_PARTITION=""
142CONFIG_SUSPEND_SMP=y
139 143
140# 144#
141# ACPI (Advanced Configuration and Power Interface) Support 145# ACPI (Advanced Configuration and Power Interface) Support
142# 146#
143CONFIG_ACPI=y 147CONFIG_ACPI=y
148CONFIG_ACPI_SLEEP=y
149CONFIG_ACPI_SLEEP_PROC_FS=y
150CONFIG_ACPI_SLEEP_PROC_SLEEP=y
144CONFIG_ACPI_AC=y 151CONFIG_ACPI_AC=y
145CONFIG_ACPI_BATTERY=y 152CONFIG_ACPI_BATTERY=y
146CONFIG_ACPI_BUTTON=y 153CONFIG_ACPI_BUTTON=y
@@ -148,6 +155,7 @@ CONFIG_ACPI_BUTTON=y
148CONFIG_ACPI_HOTKEY=m 155CONFIG_ACPI_HOTKEY=m
149CONFIG_ACPI_FAN=y 156CONFIG_ACPI_FAN=y
150CONFIG_ACPI_PROCESSOR=y 157CONFIG_ACPI_PROCESSOR=y
158CONFIG_ACPI_HOTPLUG_CPU=y
151CONFIG_ACPI_THERMAL=y 159CONFIG_ACPI_THERMAL=y
152CONFIG_ACPI_NUMA=y 160CONFIG_ACPI_NUMA=y
153# CONFIG_ACPI_ASUS is not set 161# CONFIG_ACPI_ASUS is not set
@@ -158,7 +166,7 @@ CONFIG_ACPI_BLACKLIST_YEAR=2001
158CONFIG_ACPI_EC=y 166CONFIG_ACPI_EC=y
159CONFIG_ACPI_POWER=y 167CONFIG_ACPI_POWER=y
160CONFIG_ACPI_SYSTEM=y 168CONFIG_ACPI_SYSTEM=y
161# CONFIG_ACPI_CONTAINER is not set 169CONFIG_ACPI_CONTAINER=y
162 170
163# 171#
164# CPU Frequency scaling 172# CPU Frequency scaling
@@ -293,7 +301,6 @@ CONFIG_IPV6=y
293# Network testing 301# Network testing
294# 302#
295# CONFIG_NET_PKTGEN is not set 303# CONFIG_NET_PKTGEN is not set
296# CONFIG_NETFILTER_NETLINK is not set
297# CONFIG_HAMRADIO is not set 304# CONFIG_HAMRADIO is not set
298# CONFIG_IRDA is not set 305# CONFIG_IRDA is not set
299# CONFIG_BT is not set 306# CONFIG_BT is not set
@@ -312,6 +319,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
312# CONFIG_DEBUG_DRIVER is not set 319# CONFIG_DEBUG_DRIVER is not set
313 320
314# 321#
322# Connector - unified userspace <-> kernelspace linker
323#
324# CONFIG_CONNECTOR is not set
325
326#
315# Memory Technology Devices (MTD) 327# Memory Technology Devices (MTD)
316# 328#
317# CONFIG_MTD is not set 329# CONFIG_MTD is not set
@@ -354,6 +366,11 @@ CONFIG_IOSCHED_NOOP=y
354# CONFIG_IOSCHED_AS is not set 366# CONFIG_IOSCHED_AS is not set
355CONFIG_IOSCHED_DEADLINE=y 367CONFIG_IOSCHED_DEADLINE=y
356CONFIG_IOSCHED_CFQ=y 368CONFIG_IOSCHED_CFQ=y
369# CONFIG_DEFAULT_AS is not set
370CONFIG_DEFAULT_DEADLINE=y
371# CONFIG_DEFAULT_CFQ is not set
372# CONFIG_DEFAULT_NOOP is not set
373CONFIG_DEFAULT_IOSCHED="cfq"
357# CONFIG_ATA_OVER_ETH is not set 374# CONFIG_ATA_OVER_ETH is not set
358 375
359# 376#
@@ -450,6 +467,7 @@ CONFIG_BLK_DEV_SD=y
450CONFIG_SCSI_SPI_ATTRS=y 467CONFIG_SCSI_SPI_ATTRS=y
451# CONFIG_SCSI_FC_ATTRS is not set 468# CONFIG_SCSI_FC_ATTRS is not set
452# CONFIG_SCSI_ISCSI_ATTRS is not set 469# CONFIG_SCSI_ISCSI_ATTRS is not set
470# CONFIG_SCSI_SAS_ATTRS is not set
453 471
454# 472#
455# SCSI low-level drivers 473# SCSI low-level drivers
@@ -469,20 +487,24 @@ CONFIG_AIC79XX_DEBUG_MASK=0
469# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set 487# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
470# CONFIG_MEGARAID_NEWGEN is not set 488# CONFIG_MEGARAID_NEWGEN is not set
471# CONFIG_MEGARAID_LEGACY is not set 489# CONFIG_MEGARAID_LEGACY is not set
490# CONFIG_MEGARAID_SAS is not set
472CONFIG_SCSI_SATA=y 491CONFIG_SCSI_SATA=y
473# CONFIG_SCSI_SATA_AHCI is not set 492# CONFIG_SCSI_SATA_AHCI is not set
474# CONFIG_SCSI_SATA_SVW is not set 493# CONFIG_SCSI_SATA_SVW is not set
475CONFIG_SCSI_ATA_PIIX=y 494CONFIG_SCSI_ATA_PIIX=y
476# CONFIG_SCSI_SATA_MV is not set 495# CONFIG_SCSI_SATA_MV is not set
477# CONFIG_SCSI_SATA_NV is not set 496CONFIG_SCSI_SATA_NV=y
478# CONFIG_SCSI_SATA_PROMISE is not set 497# CONFIG_SCSI_PDC_ADMA is not set
479# CONFIG_SCSI_SATA_QSTOR is not set 498# CONFIG_SCSI_SATA_QSTOR is not set
499# CONFIG_SCSI_SATA_PROMISE is not set
480# CONFIG_SCSI_SATA_SX4 is not set 500# CONFIG_SCSI_SATA_SX4 is not set
481# CONFIG_SCSI_SATA_SIL is not set 501# CONFIG_SCSI_SATA_SIL is not set
502# CONFIG_SCSI_SATA_SIL24 is not set
482# CONFIG_SCSI_SATA_SIS is not set 503# CONFIG_SCSI_SATA_SIS is not set
483# CONFIG_SCSI_SATA_ULI is not set 504# CONFIG_SCSI_SATA_ULI is not set
484CONFIG_SCSI_SATA_VIA=y 505CONFIG_SCSI_SATA_VIA=y
485# CONFIG_SCSI_SATA_VITESSE is not set 506# CONFIG_SCSI_SATA_VITESSE is not set
507CONFIG_SCSI_SATA_INTEL_COMBINED=y
486# CONFIG_SCSI_BUSLOGIC is not set 508# CONFIG_SCSI_BUSLOGIC is not set
487# CONFIG_SCSI_DMX3191D is not set 509# CONFIG_SCSI_DMX3191D is not set
488# CONFIG_SCSI_EATA is not set 510# CONFIG_SCSI_EATA is not set
@@ -525,6 +547,7 @@ CONFIG_BLK_DEV_DM=y
525CONFIG_FUSION=y 547CONFIG_FUSION=y
526CONFIG_FUSION_SPI=y 548CONFIG_FUSION_SPI=y
527# CONFIG_FUSION_FC is not set 549# CONFIG_FUSION_FC is not set
550# CONFIG_FUSION_SAS is not set
528CONFIG_FUSION_MAX_SGE=128 551CONFIG_FUSION_MAX_SGE=128
529# CONFIG_FUSION_CTL is not set 552# CONFIG_FUSION_CTL is not set
530 553
@@ -564,6 +587,7 @@ CONFIG_NET_ETHERNET=y
564CONFIG_MII=y 587CONFIG_MII=y
565# CONFIG_HAPPYMEAL is not set 588# CONFIG_HAPPYMEAL is not set
566# CONFIG_SUNGEM is not set 589# CONFIG_SUNGEM is not set
590# CONFIG_CASSINI is not set
567CONFIG_NET_VENDOR_3COM=y 591CONFIG_NET_VENDOR_3COM=y
568CONFIG_VORTEX=y 592CONFIG_VORTEX=y
569# CONFIG_TYPHOON is not set 593# CONFIG_TYPHOON is not set
@@ -740,7 +764,43 @@ CONFIG_LEGACY_PTY_COUNT=256
740# 764#
741# Watchdog Cards 765# Watchdog Cards
742# 766#
743# CONFIG_WATCHDOG is not set 767CONFIG_WATCHDOG=y
768# CONFIG_WATCHDOG_NOWAYOUT is not set
769
770#
771# Watchdog Device Drivers
772#
773CONFIG_SOFT_WATCHDOG=y
774# CONFIG_ACQUIRE_WDT is not set
775# CONFIG_ADVANTECH_WDT is not set
776# CONFIG_ALIM1535_WDT is not set
777# CONFIG_ALIM7101_WDT is not set
778# CONFIG_SC520_WDT is not set
779# CONFIG_EUROTECH_WDT is not set
780# CONFIG_IB700_WDT is not set
781# CONFIG_IBMASR is not set
782# CONFIG_WAFER_WDT is not set
783# CONFIG_I6300ESB_WDT is not set
784# CONFIG_I8XX_TCO is not set
785# CONFIG_SC1200_WDT is not set
786# CONFIG_60XX_WDT is not set
787# CONFIG_SBC8360_WDT is not set
788# CONFIG_CPU5_WDT is not set
789# CONFIG_W83627HF_WDT is not set
790# CONFIG_W83877F_WDT is not set
791# CONFIG_W83977F_WDT is not set
792# CONFIG_MACHZ_WDT is not set
793
794#
795# PCI-based Watchdog Cards
796#
797# CONFIG_PCIPCWATCHDOG is not set
798# CONFIG_WDTPCI is not set
799
800#
801# USB-based Watchdog Cards
802#
803# CONFIG_USBPCWATCHDOG is not set
744CONFIG_HW_RANDOM=y 804CONFIG_HW_RANDOM=y
745# CONFIG_NVRAM is not set 805# CONFIG_NVRAM is not set
746CONFIG_RTC=y 806CONFIG_RTC=y
@@ -767,6 +827,7 @@ CONFIG_MAX_RAW_DEVS=256
767# TPM devices 827# TPM devices
768# 828#
769# CONFIG_TCG_TPM is not set 829# CONFIG_TCG_TPM is not set
830# CONFIG_TELCLOCK is not set
770 831
771# 832#
772# I2C support 833# I2C support
@@ -783,6 +844,7 @@ CONFIG_MAX_RAW_DEVS=256
783# 844#
784CONFIG_HWMON=y 845CONFIG_HWMON=y
785# CONFIG_HWMON_VID is not set 846# CONFIG_HWMON_VID is not set
847# CONFIG_SENSORS_HDAPS is not set
786# CONFIG_HWMON_DEBUG_CHIP is not set 848# CONFIG_HWMON_DEBUG_CHIP is not set
787 849
788# 850#
@@ -886,12 +948,15 @@ CONFIG_USB_UHCI_HCD=y
886# USB Device Class drivers 948# USB Device Class drivers
887# 949#
888# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set 950# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
889# CONFIG_USB_BLUETOOTH_TTY is not set
890# CONFIG_USB_ACM is not set 951# CONFIG_USB_ACM is not set
891CONFIG_USB_PRINTER=y 952CONFIG_USB_PRINTER=y
892 953
893# 954#
894# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 955# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
956#
957
958#
959# may also be needed; see USB_STORAGE Help for more information
895# 960#
896CONFIG_USB_STORAGE=y 961CONFIG_USB_STORAGE=y
897# CONFIG_USB_STORAGE_DEBUG is not set 962# CONFIG_USB_STORAGE_DEBUG is not set
@@ -924,6 +989,7 @@ CONFIG_USB_HIDINPUT=y
924# CONFIG_USB_XPAD is not set 989# CONFIG_USB_XPAD is not set
925# CONFIG_USB_ATI_REMOTE is not set 990# CONFIG_USB_ATI_REMOTE is not set
926# CONFIG_USB_KEYSPAN_REMOTE is not set 991# CONFIG_USB_KEYSPAN_REMOTE is not set
992# CONFIG_USB_APPLETOUCH is not set
927 993
928# 994#
929# USB Imaging devices 995# USB Imaging devices
@@ -1005,7 +1071,7 @@ CONFIG_USB_MON=y
1005# 1071#
1006# CONFIG_EDD is not set 1072# CONFIG_EDD is not set
1007# CONFIG_DELL_RBU is not set 1073# CONFIG_DELL_RBU is not set
1008CONFIG_DCDBAS=m 1074# CONFIG_DCDBAS is not set
1009 1075
1010# 1076#
1011# File systems 1077# File systems
@@ -1037,7 +1103,7 @@ CONFIG_INOTIFY=y
1037# CONFIG_QUOTA is not set 1103# CONFIG_QUOTA is not set
1038CONFIG_DNOTIFY=y 1104CONFIG_DNOTIFY=y
1039CONFIG_AUTOFS_FS=y 1105CONFIG_AUTOFS_FS=y
1040# CONFIG_AUTOFS4_FS is not set 1106CONFIG_AUTOFS4_FS=y
1041# CONFIG_FUSE_FS is not set 1107# CONFIG_FUSE_FS is not set
1042 1108
1043# 1109#
@@ -1068,7 +1134,7 @@ CONFIG_TMPFS=y
1068CONFIG_HUGETLBFS=y 1134CONFIG_HUGETLBFS=y
1069CONFIG_HUGETLB_PAGE=y 1135CONFIG_HUGETLB_PAGE=y
1070CONFIG_RAMFS=y 1136CONFIG_RAMFS=y
1071# CONFIG_RELAYFS_FS is not set 1137CONFIG_RELAYFS_FS=y
1072 1138
1073# 1139#
1074# Miscellaneous filesystems 1140# Miscellaneous filesystems
@@ -1186,7 +1252,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
1186# CONFIG_DEBUG_KOBJECT is not set 1252# CONFIG_DEBUG_KOBJECT is not set
1187# CONFIG_DEBUG_INFO is not set 1253# CONFIG_DEBUG_INFO is not set
1188CONFIG_DEBUG_FS=y 1254CONFIG_DEBUG_FS=y
1255# CONFIG_DEBUG_VM is not set
1189# CONFIG_FRAME_POINTER is not set 1256# CONFIG_FRAME_POINTER is not set
1257# CONFIG_RCU_TORTURE_TEST is not set
1190CONFIG_INIT_DEBUG=y 1258CONFIG_INIT_DEBUG=y
1191# CONFIG_IOMMU_DEBUG is not set 1259# CONFIG_IOMMU_DEBUG is not set
1192CONFIG_KPROBES=y 1260CONFIG_KPROBES=y
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 93c60f4aa47a..3bf58af98936 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -36,9 +36,6 @@
36#undef WARN_OLD 36#undef WARN_OLD
37#undef CORE_DUMP /* probably broken */ 37#undef CORE_DUMP /* probably broken */
38 38
39extern int ia32_setup_arg_pages(struct linux_binprm *bprm,
40 unsigned long stack_top, int exec_stack);
41
42static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); 39static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
43static int load_aout_library(struct file*); 40static int load_aout_library(struct file*);
44 41
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index d9161e395978..830feb272eca 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -335,7 +335,8 @@ static void elf32_init(struct pt_regs *regs)
335 me->thread.es = __USER_DS; 335 me->thread.es = __USER_DS;
336} 336}
337 337
338int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int executable_stack) 338int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top,
339 int executable_stack)
339{ 340{
340 unsigned long stack_base; 341 unsigned long stack_base;
341 struct vm_area_struct *mpnt; 342 struct vm_area_struct *mpnt;
@@ -389,6 +390,7 @@ int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int exec
389 390
390 return 0; 391 return 0;
391} 392}
393EXPORT_SYMBOL(ia32_setup_arg_pages);
392 394
393static unsigned long 395static unsigned long
394elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) 396elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 14328cab5d3a..fe4cbd1c4b2f 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -11,6 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
11 11
12obj-$(CONFIG_X86_MCE) += mce.o 12obj-$(CONFIG_X86_MCE) += mce.o
13obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o 13obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
14obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o
14obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ 15obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/
15obj-$(CONFIG_ACPI) += acpi/ 16obj-$(CONFIG_ACPI) += acpi/
16obj-$(CONFIG_X86_MSR) += msr.o 17obj-$(CONFIG_X86_MSR) += msr.o
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 962ad4823b6a..c7f4fdd20f05 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -196,7 +196,7 @@ static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
196void __init iommu_hole_init(void) 196void __init iommu_hole_init(void)
197{ 197{
198 int fix, num; 198 int fix, num;
199 u32 aper_size, aper_alloc = 0, aper_order, last_aper_order = 0; 199 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
200 u64 aper_base, last_aper_base = 0; 200 u64 aper_base, last_aper_base = 0;
201 int valid_agp = 0; 201 int valid_agp = 0;
202 202
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index b6e7715d877f..18691ce4c759 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -833,6 +833,16 @@ int setup_profiling_timer(unsigned int multiplier)
833 return 0; 833 return 0;
834} 834}
835 835
836#ifdef CONFIG_X86_MCE_AMD
837void setup_threshold_lvt(unsigned long lvt_off)
838{
839 unsigned int v = 0;
840 unsigned long reg = (lvt_off << 4) + 0x500;
841 v |= THRESHOLD_APIC_VECTOR;
842 apic_write(reg, v);
843}
844#endif /* CONFIG_X86_MCE_AMD */
845
836#undef APIC_DIVISOR 846#undef APIC_DIVISOR
837 847
838/* 848/*
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index ab3f87aaff70..17579a1a174b 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -23,8 +23,7 @@
23#include <asm/e820.h> 23#include <asm/e820.h>
24#include <asm/proto.h> 24#include <asm/proto.h>
25#include <asm/bootsetup.h> 25#include <asm/bootsetup.h>
26 26#include <asm/sections.h>
27extern char _end[];
28 27
29/* 28/*
30 * PFN of last memory page. 29 * PFN of last memory page.
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 7937971d1853..9ff42041bb6b 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -612,6 +612,9 @@ retint_kernel:
612ENTRY(thermal_interrupt) 612ENTRY(thermal_interrupt)
613 apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt 613 apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
614 614
615ENTRY(threshold_interrupt)
616 apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
617
615#ifdef CONFIG_SMP 618#ifdef CONFIG_SMP
616ENTRY(reschedule_interrupt) 619ENTRY(reschedule_interrupt)
617 apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt 620 apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index b92e5f45ed46..15290968e49d 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -12,6 +12,7 @@
12 12
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/threads.h> 14#include <linux/threads.h>
15#include <linux/init.h>
15#include <asm/desc.h> 16#include <asm/desc.h>
16#include <asm/segment.h> 17#include <asm/segment.h>
17#include <asm/page.h> 18#include <asm/page.h>
@@ -70,7 +71,7 @@ startup_32:
70 movl %eax, %cr4 71 movl %eax, %cr4
71 72
72 /* Setup early boot stage 4 level pagetables */ 73 /* Setup early boot stage 4 level pagetables */
73 movl $(init_level4_pgt - __START_KERNEL_map), %eax 74 movl $(boot_level4_pgt - __START_KERNEL_map), %eax
74 movl %eax, %cr3 75 movl %eax, %cr3
75 76
76 /* Setup EFER (Extended Feature Enable Register) */ 77 /* Setup EFER (Extended Feature Enable Register) */
@@ -113,7 +114,7 @@ startup_64:
113 movq %rax, %cr4 114 movq %rax, %cr4
114 115
115 /* Setup early boot stage 4 level pagetables. */ 116 /* Setup early boot stage 4 level pagetables. */
116 movq $(init_level4_pgt - __START_KERNEL_map), %rax 117 movq $(boot_level4_pgt - __START_KERNEL_map), %rax
117 movq %rax, %cr3 118 movq %rax, %cr3
118 119
119 /* Check if nx is implemented */ 120 /* Check if nx is implemented */
@@ -240,20 +241,10 @@ ljumpvector:
240ENTRY(stext) 241ENTRY(stext)
241ENTRY(_stext) 242ENTRY(_stext)
242 243
243 /*
244 * This default setting generates an ident mapping at address 0x100000
245 * and a mapping for the kernel that precisely maps virtual address
246 * 0xffffffff80000000 to physical address 0x000000. (always using
247 * 2Mbyte large pages provided by PAE mode)
248 */
249.org 0x1000 244.org 0x1000
250ENTRY(init_level4_pgt) 245ENTRY(init_level4_pgt)
251 .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ 246 /* This gets initialized in x86_64_start_kernel */
252 .fill 255,8,0 247 .fill 512,8,0
253 .quad 0x000000000000a007 + __PHYSICAL_START
254 .fill 254,8,0
255 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
256 .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */
257 248
258.org 0x2000 249.org 0x2000
259ENTRY(level3_ident_pgt) 250ENTRY(level3_ident_pgt)
@@ -350,6 +341,24 @@ ENTRY(wakeup_level4_pgt)
350 .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ 341 .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */
351#endif 342#endif
352 343
344#ifndef CONFIG_HOTPLUG_CPU
345 __INITDATA
346#endif
347 /*
348 * This default setting generates an ident mapping at address 0x100000
349 * and a mapping for the kernel that precisely maps virtual address
350 * 0xffffffff80000000 to physical address 0x000000. (always using
351 * 2Mbyte large pages provided by PAE mode)
352 */
353 .align PAGE_SIZE
354ENTRY(boot_level4_pgt)
355 .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */
356 .fill 255,8,0
357 .quad 0x000000000000a007 + __PHYSICAL_START
358 .fill 254,8,0
359 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
360 .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */
361
353 .data 362 .data
354 363
355 .align 16 364 .align 16
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index cf6ab147a2a5..b675c5add01e 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -19,14 +19,15 @@
19#include <asm/bootsetup.h> 19#include <asm/bootsetup.h>
20#include <asm/setup.h> 20#include <asm/setup.h>
21#include <asm/desc.h> 21#include <asm/desc.h>
22#include <asm/pgtable.h>
23#include <asm/sections.h>
22 24
23/* Don't add a printk in there. printk relies on the PDA which is not initialized 25/* Don't add a printk in there. printk relies on the PDA which is not initialized
24 yet. */ 26 yet. */
25static void __init clear_bss(void) 27static void __init clear_bss(void)
26{ 28{
27 extern char __bss_start[], __bss_end[];
28 memset(__bss_start, 0, 29 memset(__bss_start, 0,
29 (unsigned long) __bss_end - (unsigned long) __bss_start); 30 (unsigned long) __bss_stop - (unsigned long) __bss_start);
30} 31}
31 32
32#define NEW_CL_POINTER 0x228 /* Relative to real mode data */ 33#define NEW_CL_POINTER 0x228 /* Relative to real mode data */
@@ -75,8 +76,6 @@ static void __init setup_boot_cpu_data(void)
75 boot_cpu_data.x86_mask = eax & 0xf; 76 boot_cpu_data.x86_mask = eax & 0xf;
76} 77}
77 78
78extern char _end[];
79
80void __init x86_64_start_kernel(char * real_mode_data) 79void __init x86_64_start_kernel(char * real_mode_data)
81{ 80{
82 char *s; 81 char *s;
@@ -86,6 +85,13 @@ void __init x86_64_start_kernel(char * real_mode_data)
86 set_intr_gate(i, early_idt_handler); 85 set_intr_gate(i, early_idt_handler);
87 asm volatile("lidt %0" :: "m" (idt_descr)); 86 asm volatile("lidt %0" :: "m" (idt_descr));
88 clear_bss(); 87 clear_bss();
88
89 /*
90 * switch to init_level4_pgt from boot_level4_pgt
91 */
92 memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t));
93 asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
94
89 pda_init(0); 95 pda_init(0);
90 copy_bootdata(real_mode_data); 96 copy_bootdata(real_mode_data);
91#ifdef CONFIG_SMP 97#ifdef CONFIG_SMP
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index c6c9791d77c1..6e5101ad3d1a 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -492,6 +492,7 @@ void invalidate_interrupt5(void);
492void invalidate_interrupt6(void); 492void invalidate_interrupt6(void);
493void invalidate_interrupt7(void); 493void invalidate_interrupt7(void);
494void thermal_interrupt(void); 494void thermal_interrupt(void);
495void threshold_interrupt(void);
495void i8254_timer_resume(void); 496void i8254_timer_resume(void);
496 497
497static void setup_timer_hardware(void) 498static void setup_timer_hardware(void)
@@ -515,7 +516,7 @@ void i8254_timer_resume(void)
515} 516}
516 517
517static struct sysdev_class timer_sysclass = { 518static struct sysdev_class timer_sysclass = {
518 set_kset_name("timer"), 519 set_kset_name("timer_pit"),
519 .resume = timer_resume, 520 .resume = timer_resume,
520}; 521};
521 522
@@ -580,6 +581,7 @@ void __init init_IRQ(void)
580 set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 581 set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
581#endif 582#endif
582 set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); 583 set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
584 set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
583 585
584#ifdef CONFIG_X86_LOCAL_APIC 586#ifdef CONFIG_X86_LOCAL_APIC
585 /* self generated IPI for local APIC timer */ 587 /* self generated IPI for local APIC timer */
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c8eee20cd519..97154ab058b4 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -57,7 +57,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
57 * Rough estimation of how many shared IRQs there are, can 57 * Rough estimation of how many shared IRQs there are, can
58 * be changed anytime. 58 * be changed anytime.
59 */ 59 */
60#define MAX_PLUS_SHARED_IRQS NR_IRQS 60#define MAX_PLUS_SHARED_IRQS NR_IRQ_VECTORS
61#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS) 61#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
62 62
63/* 63/*
@@ -85,6 +85,7 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
85 int pin; \ 85 int pin; \
86 struct irq_pin_list *entry = irq_2_pin + irq; \ 86 struct irq_pin_list *entry = irq_2_pin + irq; \
87 \ 87 \
88 BUG_ON(irq >= NR_IRQS); \
88 for (;;) { \ 89 for (;;) { \
89 unsigned int reg; \ 90 unsigned int reg; \
90 pin = entry->pin; \ 91 pin = entry->pin; \
@@ -127,6 +128,8 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
127} 128}
128#endif 129#endif
129 130
131static u8 gsi_2_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS-1] = 0xFF };
132
130/* 133/*
131 * The common case is 1:1 IRQ<->pin mappings. Sometimes there are 134 * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
132 * shared ISA-space IRQs, so we have to support them. We are super 135 * shared ISA-space IRQs, so we have to support them. We are super
@@ -137,6 +140,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
137 static int first_free_entry = NR_IRQS; 140 static int first_free_entry = NR_IRQS;
138 struct irq_pin_list *entry = irq_2_pin + irq; 141 struct irq_pin_list *entry = irq_2_pin + irq;
139 142
143 BUG_ON(irq >= NR_IRQS);
140 while (entry->next) 144 while (entry->next)
141 entry = irq_2_pin + entry->next; 145 entry = irq_2_pin + entry->next;
142 146
@@ -144,7 +148,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
144 entry->next = first_free_entry; 148 entry->next = first_free_entry;
145 entry = irq_2_pin + entry->next; 149 entry = irq_2_pin + entry->next;
146 if (++first_free_entry >= PIN_MAP_SIZE) 150 if (++first_free_entry >= PIN_MAP_SIZE)
147 panic("io_apic.c: whoops"); 151 panic("io_apic.c: ran out of irq_2_pin entries!");
148 } 152 }
149 entry->apic = apic; 153 entry->apic = apic;
150 entry->pin = pin; 154 entry->pin = pin;
@@ -420,6 +424,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
420 best_guess = irq; 424 best_guess = irq;
421 } 425 }
422 } 426 }
427 BUG_ON(best_guess >= NR_IRQS);
423 return best_guess; 428 return best_guess;
424} 429}
425 430
@@ -610,6 +615,64 @@ static inline int irq_trigger(int idx)
610 return MPBIOS_trigger(idx); 615 return MPBIOS_trigger(idx);
611} 616}
612 617
618static int next_irq = 16;
619
620/*
621 * gsi_irq_sharing -- Name overload! "irq" can be either a legacy IRQ
622 * in the range 0-15, a linux IRQ in the range 0-223, or a GSI number
623 * from ACPI, which can reach 800 in large boxen.
624 *
625 * Compact the sparse GSI space into a sequential IRQ series and reuse
626 * vectors if possible.
627 */
628int gsi_irq_sharing(int gsi)
629{
630 int i, tries, vector;
631
632 BUG_ON(gsi >= NR_IRQ_VECTORS);
633
634 if (platform_legacy_irq(gsi))
635 return gsi;
636
637 if (gsi_2_irq[gsi] != 0xFF)
638 return (int)gsi_2_irq[gsi];
639
640 tries = NR_IRQS;
641 try_again:
642 vector = assign_irq_vector(gsi);
643
644 /*
645 * Sharing vectors means sharing IRQs, so scan irq_vectors for previous
646 * use of vector and if found, return that IRQ. However, we never want
647 * to share legacy IRQs, which usually have a different trigger mode
648 * than PCI.
649 */
650 for (i = 0; i < NR_IRQS; i++)
651 if (IO_APIC_VECTOR(i) == vector)
652 break;
653 if (platform_legacy_irq(i)) {
654 if (--tries >= 0) {
655 IO_APIC_VECTOR(i) = 0;
656 goto try_again;
657 }
658 panic("gsi_irq_sharing: didn't find an IRQ using vector 0x%02X for GSI %d", vector, gsi);
659 }
660 if (i < NR_IRQS) {
661 gsi_2_irq[gsi] = i;
662 printk(KERN_INFO "GSI %d sharing vector 0x%02X and IRQ %d\n",
663 gsi, vector, i);
664 return i;
665 }
666
667 i = next_irq++;
668 BUG_ON(i >= NR_IRQS);
669 gsi_2_irq[gsi] = i;
670 IO_APIC_VECTOR(i) = vector;
671 printk(KERN_INFO "GSI %d assigned vector 0x%02X and IRQ %d\n",
672 gsi, vector, i);
673 return i;
674}
675
613static int pin_2_irq(int idx, int apic, int pin) 676static int pin_2_irq(int idx, int apic, int pin)
614{ 677{
615 int irq, i; 678 int irq, i;
@@ -639,6 +702,7 @@ static int pin_2_irq(int idx, int apic, int pin)
639 while (i < apic) 702 while (i < apic)
640 irq += nr_ioapic_registers[i++]; 703 irq += nr_ioapic_registers[i++];
641 irq += pin; 704 irq += pin;
705 irq = gsi_irq_sharing(irq);
642 break; 706 break;
643 } 707 }
644 default: 708 default:
@@ -648,6 +712,7 @@ static int pin_2_irq(int idx, int apic, int pin)
648 break; 712 break;
649 } 713 }
650 } 714 }
715 BUG_ON(irq >= NR_IRQS);
651 716
652 /* 717 /*
653 * PCI IRQ command line redirection. Yes, limits are hardcoded. 718 * PCI IRQ command line redirection. Yes, limits are hardcoded.
@@ -663,6 +728,7 @@ static int pin_2_irq(int idx, int apic, int pin)
663 } 728 }
664 } 729 }
665 } 730 }
731 BUG_ON(irq >= NR_IRQS);
666 return irq; 732 return irq;
667} 733}
668 734
@@ -690,8 +756,8 @@ int assign_irq_vector(int irq)
690{ 756{
691 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 757 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
692 758
693 BUG_ON(irq >= NR_IRQ_VECTORS); 759 BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
694 if (IO_APIC_VECTOR(irq) > 0) 760 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
695 return IO_APIC_VECTOR(irq); 761 return IO_APIC_VECTOR(irq);
696next: 762next:
697 current_vector += 8; 763 current_vector += 8;
@@ -699,9 +765,8 @@ next:
699 goto next; 765 goto next;
700 766
701 if (current_vector >= FIRST_SYSTEM_VECTOR) { 767 if (current_vector >= FIRST_SYSTEM_VECTOR) {
702 offset++; 768 /* If we run out of vectors on large boxen, must share them. */
703 if (!(offset%8)) 769 offset = (offset + 1) % 8;
704 return -ENOSPC;
705 current_vector = FIRST_DEVICE_VECTOR + offset; 770 current_vector = FIRST_DEVICE_VECTOR + offset;
706 } 771 }
707 772
@@ -1917,6 +1982,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
1917 entry.polarity = active_high_low; 1982 entry.polarity = active_high_low;
1918 entry.mask = 1; /* Disabled (masked) */ 1983 entry.mask = 1; /* Disabled (masked) */
1919 1984
1985 irq = gsi_irq_sharing(irq);
1920 /* 1986 /*
1921 * IRQs < 16 are already in the irq_2_pin[] map 1987 * IRQs < 16 are already in the irq_2_pin[] map
1922 */ 1988 */
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 69541db5ff2c..183dc6105429 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -37,7 +37,7 @@ static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
37static unsigned long console_logged; 37static unsigned long console_logged;
38static int notify_user; 38static int notify_user;
39static int rip_msr; 39static int rip_msr;
40static int mce_bootlog; 40static int mce_bootlog = 1;
41 41
42/* 42/*
43 * Lockless MCE logging infrastructure. 43 * Lockless MCE logging infrastructure.
@@ -347,7 +347,11 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
347 /* disable GART TBL walk error reporting, which trips off 347 /* disable GART TBL walk error reporting, which trips off
348 incorrectly with the IOMMU & 3ware & Cerberus. */ 348 incorrectly with the IOMMU & 3ware & Cerberus. */
349 clear_bit(10, &bank[4]); 349 clear_bit(10, &bank[4]);
350 /* Lots of broken BIOS around that don't clear them
351 by default and leave crap in there. Don't log. */
352 mce_bootlog = 0;
350 } 353 }
354
351} 355}
352 356
353static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) 357static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
@@ -356,6 +360,9 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
356 case X86_VENDOR_INTEL: 360 case X86_VENDOR_INTEL:
357 mce_intel_feature_init(c); 361 mce_intel_feature_init(c);
358 break; 362 break;
363 case X86_VENDOR_AMD:
364 mce_amd_feature_init(c);
365 break;
359 default: 366 default:
360 break; 367 break;
361 } 368 }
@@ -495,16 +502,16 @@ static int __init mcheck_disable(char *str)
495/* mce=off disables machine check. Note you can reenable it later 502/* mce=off disables machine check. Note you can reenable it later
496 using sysfs. 503 using sysfs.
497 mce=TOLERANCELEVEL (number, see above) 504 mce=TOLERANCELEVEL (number, see above)
498 mce=bootlog Log MCEs from before booting. Disabled by default to work 505 mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
499 around buggy BIOS that leave bogus MCEs. */ 506 mce=nobootlog Don't log MCEs from before booting. */
500static int __init mcheck_enable(char *str) 507static int __init mcheck_enable(char *str)
501{ 508{
502 if (*str == '=') 509 if (*str == '=')
503 str++; 510 str++;
504 if (!strcmp(str, "off")) 511 if (!strcmp(str, "off"))
505 mce_dont_init = 1; 512 mce_dont_init = 1;
506 else if (!strcmp(str, "bootlog")) 513 else if (!strcmp(str, "bootlog") || !strcmp(str,"nobootlog"))
507 mce_bootlog = 1; 514 mce_bootlog = str[0] == 'b';
508 else if (isdigit(str[0])) 515 else if (isdigit(str[0]))
509 get_option(&str, &tolerant); 516 get_option(&str, &tolerant);
510 else 517 else
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c
new file mode 100644
index 000000000000..1f76175ace02
--- /dev/null
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -0,0 +1,538 @@
1/*
2 * (c) 2005 Advanced Micro Devices, Inc.
3 * Your use of this code is subject to the terms and conditions of the
4 * GNU general public license version 2. See "COPYING" or
5 * http://www.gnu.org/licenses/gpl.html
6 *
7 * Written by Jacob Shin - AMD, Inc.
8 *
9 * Support : jacob.shin@amd.com
10 *
11 * MC4_MISC0 DRAM ECC Error Threshold available under AMD K8 Rev F.
12 * MC4_MISC0 exists per physical processor.
13 *
14 */
15
16#include <linux/cpu.h>
17#include <linux/errno.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kobject.h>
21#include <linux/notifier.h>
22#include <linux/sched.h>
23#include <linux/smp.h>
24#include <linux/sysdev.h>
25#include <linux/sysfs.h>
26#include <asm/apic.h>
27#include <asm/mce.h>
28#include <asm/msr.h>
29#include <asm/percpu.h>
30
31#define PFX "mce_threshold: "
32#define VERSION "version 1.00.9"
33#define NR_BANKS 5
34#define THRESHOLD_MAX 0xFFF
35#define INT_TYPE_APIC 0x00020000
36#define MASK_VALID_HI 0x80000000
37#define MASK_LVTOFF_HI 0x00F00000
38#define MASK_COUNT_EN_HI 0x00080000
39#define MASK_INT_TYPE_HI 0x00060000
40#define MASK_OVERFLOW_HI 0x00010000
41#define MASK_ERR_COUNT_HI 0x00000FFF
42#define MASK_OVERFLOW 0x0001000000000000L
43
44struct threshold_bank {
45 unsigned int cpu;
46 u8 bank;
47 u8 interrupt_enable;
48 u16 threshold_limit;
49 struct kobject kobj;
50};
51
52static struct threshold_bank threshold_defaults = {
53 .interrupt_enable = 0,
54 .threshold_limit = THRESHOLD_MAX,
55};
56
57#ifdef CONFIG_SMP
58static unsigned char shared_bank[NR_BANKS] = {
59 0, 0, 0, 0, 1
60};
61#endif
62
63static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
64
65/*
66 * CPU Initialization
67 */
68
69/* must be called with correct cpu affinity */
70static void threshold_restart_bank(struct threshold_bank *b,
71 int reset, u16 old_limit)
72{
73 u32 mci_misc_hi, mci_misc_lo;
74
75 rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
76
77 if (b->threshold_limit < (mci_misc_hi & THRESHOLD_MAX))
78 reset = 1; /* limit cannot be lower than err count */
79
80 if (reset) { /* reset err count and overflow bit */
81 mci_misc_hi =
82 (mci_misc_hi & ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI)) |
83 (THRESHOLD_MAX - b->threshold_limit);
84 } else if (old_limit) { /* change limit w/o reset */
85 int new_count = (mci_misc_hi & THRESHOLD_MAX) +
86 (old_limit - b->threshold_limit);
87 mci_misc_hi = (mci_misc_hi & ~MASK_ERR_COUNT_HI) |
88 (new_count & THRESHOLD_MAX);
89 }
90
91 b->interrupt_enable ?
92 (mci_misc_hi = (mci_misc_hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
93 (mci_misc_hi &= ~MASK_INT_TYPE_HI);
94
95 mci_misc_hi |= MASK_COUNT_EN_HI;
96 wrmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
97}
98
99void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
100{
101 int bank;
102 u32 mci_misc_lo, mci_misc_hi;
103 unsigned int cpu = smp_processor_id();
104
105 for (bank = 0; bank < NR_BANKS; ++bank) {
106 rdmsr(MSR_IA32_MC0_MISC + bank * 4, mci_misc_lo, mci_misc_hi);
107
108 /* !valid, !counter present, bios locked */
109 if (!(mci_misc_hi & MASK_VALID_HI) ||
110 !(mci_misc_hi & MASK_VALID_HI >> 1) ||
111 (mci_misc_hi & MASK_VALID_HI >> 2))
112 continue;
113
114 per_cpu(bank_map, cpu) |= (1 << bank);
115
116#ifdef CONFIG_SMP
117 if (shared_bank[bank] && cpu_core_id[cpu])
118 continue;
119#endif
120
121 setup_threshold_lvt((mci_misc_hi & MASK_LVTOFF_HI) >> 20);
122 threshold_defaults.cpu = cpu;
123 threshold_defaults.bank = bank;
124 threshold_restart_bank(&threshold_defaults, 0, 0);
125 }
126}
127
128/*
129 * APIC Interrupt Handler
130 */
131
132/*
133 * threshold interrupt handler will service THRESHOLD_APIC_VECTOR.
134 * the interrupt goes off when error_count reaches threshold_limit.
135 * the handler will simply log mcelog w/ software defined bank number.
136 */
137asmlinkage void mce_threshold_interrupt(void)
138{
139 int bank;
140 struct mce m;
141
142 ack_APIC_irq();
143 irq_enter();
144
145 memset(&m, 0, sizeof(m));
146 rdtscll(m.tsc);
147 m.cpu = smp_processor_id();
148
149 /* assume first bank caused it */
150 for (bank = 0; bank < NR_BANKS; ++bank) {
151 m.bank = MCE_THRESHOLD_BASE + bank;
152 rdmsrl(MSR_IA32_MC0_MISC + bank * 4, m.misc);
153
154 if (m.misc & MASK_OVERFLOW) {
155 mce_log(&m);
156 goto out;
157 }
158 }
159 out:
160 irq_exit();
161}
162
163/*
164 * Sysfs Interface
165 */
166
167static struct sysdev_class threshold_sysclass = {
168 set_kset_name("threshold"),
169};
170
171static DEFINE_PER_CPU(struct sys_device, device_threshold);
172
173struct threshold_attr {
174 struct attribute attr;
175 ssize_t(*show) (struct threshold_bank *, char *);
176 ssize_t(*store) (struct threshold_bank *, const char *, size_t count);
177};
178
179static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
180
181static cpumask_t affinity_set(unsigned int cpu)
182{
183 cpumask_t oldmask = current->cpus_allowed;
184 cpumask_t newmask = CPU_MASK_NONE;
185 cpu_set(cpu, newmask);
186 set_cpus_allowed(current, newmask);
187 return oldmask;
188}
189
190static void affinity_restore(cpumask_t oldmask)
191{
192 set_cpus_allowed(current, oldmask);
193}
194
195#define SHOW_FIELDS(name) \
196 static ssize_t show_ ## name(struct threshold_bank * b, char *buf) \
197 { \
198 return sprintf(buf, "%lx\n", (unsigned long) b->name); \
199 }
200SHOW_FIELDS(interrupt_enable)
201SHOW_FIELDS(threshold_limit)
202
203static ssize_t store_interrupt_enable(struct threshold_bank *b,
204 const char *buf, size_t count)
205{
206 char *end;
207 cpumask_t oldmask;
208 unsigned long new = simple_strtoul(buf, &end, 0);
209 if (end == buf)
210 return -EINVAL;
211 b->interrupt_enable = !!new;
212
213 oldmask = affinity_set(b->cpu);
214 threshold_restart_bank(b, 0, 0);
215 affinity_restore(oldmask);
216
217 return end - buf;
218}
219
220static ssize_t store_threshold_limit(struct threshold_bank *b,
221 const char *buf, size_t count)
222{
223 char *end;
224 cpumask_t oldmask;
225 u16 old;
226 unsigned long new = simple_strtoul(buf, &end, 0);
227 if (end == buf)
228 return -EINVAL;
229 if (new > THRESHOLD_MAX)
230 new = THRESHOLD_MAX;
231 if (new < 1)
232 new = 1;
233 old = b->threshold_limit;
234 b->threshold_limit = new;
235
236 oldmask = affinity_set(b->cpu);
237 threshold_restart_bank(b, 0, old);
238 affinity_restore(oldmask);
239
240 return end - buf;
241}
242
243static ssize_t show_error_count(struct threshold_bank *b, char *buf)
244{
245 u32 high, low;
246 cpumask_t oldmask;
247 oldmask = affinity_set(b->cpu);
248 rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, low, high); /* ignore low 32 */
249 affinity_restore(oldmask);
250 return sprintf(buf, "%x\n",
251 (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit));
252}
253
254static ssize_t store_error_count(struct threshold_bank *b,
255 const char *buf, size_t count)
256{
257 cpumask_t oldmask;
258 oldmask = affinity_set(b->cpu);
259 threshold_restart_bank(b, 1, 0);
260 affinity_restore(oldmask);
261 return 1;
262}
263
264#define THRESHOLD_ATTR(_name,_mode,_show,_store) { \
265 .attr = {.name = __stringify(_name), .mode = _mode }, \
266 .show = _show, \
267 .store = _store, \
268};
269
270#define ATTR_FIELDS(name) \
271 static struct threshold_attr name = \
272 THRESHOLD_ATTR(name, 0644, show_## name, store_## name)
273
274ATTR_FIELDS(interrupt_enable);
275ATTR_FIELDS(threshold_limit);
276ATTR_FIELDS(error_count);
277
278static struct attribute *default_attrs[] = {
279 &interrupt_enable.attr,
280 &threshold_limit.attr,
281 &error_count.attr,
282 NULL
283};
284
285#define to_bank(k) container_of(k,struct threshold_bank,kobj)
286#define to_attr(a) container_of(a,struct threshold_attr,attr)
287
288static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
289{
290 struct threshold_bank *b = to_bank(kobj);
291 struct threshold_attr *a = to_attr(attr);
292 ssize_t ret;
293 ret = a->show ? a->show(b, buf) : -EIO;
294 return ret;
295}
296
297static ssize_t store(struct kobject *kobj, struct attribute *attr,
298 const char *buf, size_t count)
299{
300 struct threshold_bank *b = to_bank(kobj);
301 struct threshold_attr *a = to_attr(attr);
302 ssize_t ret;
303 ret = a->store ? a->store(b, buf, count) : -EIO;
304 return ret;
305}
306
307static struct sysfs_ops threshold_ops = {
308 .show = show,
309 .store = store,
310};
311
312static struct kobj_type threshold_ktype = {
313 .sysfs_ops = &threshold_ops,
314 .default_attrs = default_attrs,
315};
316
317/* symlinks sibling shared banks to first core. first core owns dir/files. */
318static __cpuinit int threshold_create_bank(unsigned int cpu, int bank)
319{
320 int err = 0;
321 struct threshold_bank *b = 0;
322
323#ifdef CONFIG_SMP
324 if (cpu_core_id[cpu] && shared_bank[bank]) { /* symlink */
325 char name[16];
326 unsigned lcpu = first_cpu(cpu_core_map[cpu]);
327 if (cpu_core_id[lcpu])
328 goto out; /* first core not up yet */
329
330 b = per_cpu(threshold_banks, lcpu)[bank];
331 if (!b)
332 goto out;
333 sprintf(name, "bank%i", bank);
334 err = sysfs_create_link(&per_cpu(device_threshold, cpu).kobj,
335 &b->kobj, name);
336 if (err)
337 goto out;
338 per_cpu(threshold_banks, cpu)[bank] = b;
339 goto out;
340 }
341#endif
342
343 b = kmalloc(sizeof(struct threshold_bank), GFP_KERNEL);
344 if (!b) {
345 err = -ENOMEM;
346 goto out;
347 }
348 memset(b, 0, sizeof(struct threshold_bank));
349
350 b->cpu = cpu;
351 b->bank = bank;
352 b->interrupt_enable = 0;
353 b->threshold_limit = THRESHOLD_MAX;
354 kobject_set_name(&b->kobj, "bank%i", bank);
355 b->kobj.parent = &per_cpu(device_threshold, cpu).kobj;
356 b->kobj.ktype = &threshold_ktype;
357
358 err = kobject_register(&b->kobj);
359 if (err) {
360 kfree(b);
361 goto out;
362 }
363 per_cpu(threshold_banks, cpu)[bank] = b;
364 out:
365 return err;
366}
367
368/* create dir/files for all valid threshold banks */
369static __cpuinit int threshold_create_device(unsigned int cpu)
370{
371 int bank;
372 int err = 0;
373
374 per_cpu(device_threshold, cpu).id = cpu;
375 per_cpu(device_threshold, cpu).cls = &threshold_sysclass;
376 err = sysdev_register(&per_cpu(device_threshold, cpu));
377 if (err)
378 goto out;
379
380 for (bank = 0; bank < NR_BANKS; ++bank) {
381 if (!(per_cpu(bank_map, cpu) & 1 << bank))
382 continue;
383 err = threshold_create_bank(cpu, bank);
384 if (err)
385 goto out;
386 }
387 out:
388 return err;
389}
390
391#ifdef CONFIG_HOTPLUG_CPU
392/*
393 * let's be hotplug friendly.
394 * in case of multiple core processors, the first core always takes ownership
395 * of shared sysfs dir/files, and rest of the cores will be symlinked to it.
396 */
397
398/* cpu hotplug call removes all symlinks before first core dies */
399static __cpuinit void threshold_remove_bank(unsigned int cpu, int bank)
400{
401 struct threshold_bank *b;
402 char name[16];
403
404 b = per_cpu(threshold_banks, cpu)[bank];
405 if (!b)
406 return;
407 if (shared_bank[bank] && atomic_read(&b->kobj.kref.refcount) > 2) {
408 sprintf(name, "bank%i", bank);
409 sysfs_remove_link(&per_cpu(device_threshold, cpu).kobj, name);
410 per_cpu(threshold_banks, cpu)[bank] = 0;
411 } else {
412 kobject_unregister(&b->kobj);
413 kfree(per_cpu(threshold_banks, cpu)[bank]);
414 }
415}
416
417static __cpuinit void threshold_remove_device(unsigned int cpu)
418{
419 int bank;
420
421 for (bank = 0; bank < NR_BANKS; ++bank) {
422 if (!(per_cpu(bank_map, cpu) & 1 << bank))
423 continue;
424 threshold_remove_bank(cpu, bank);
425 }
426 sysdev_unregister(&per_cpu(device_threshold, cpu));
427}
428
429/* link all existing siblings when first core comes up */
430static __cpuinit int threshold_create_symlinks(unsigned int cpu)
431{
432 int bank, err = 0;
433 unsigned int lcpu = 0;
434
435 if (cpu_core_id[cpu])
436 return 0;
437 for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
438 if (lcpu == cpu)
439 continue;
440 for (bank = 0; bank < NR_BANKS; ++bank) {
441 if (!(per_cpu(bank_map, cpu) & 1 << bank))
442 continue;
443 if (!shared_bank[bank])
444 continue;
445 err = threshold_create_bank(lcpu, bank);
446 }
447 }
448 return err;
449}
450
451/* remove all symlinks before first core dies. */
452static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
453{
454 int bank;
455 unsigned int lcpu = 0;
456 if (cpu_core_id[cpu])
457 return;
458 for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
459 if (lcpu == cpu)
460 continue;
461 for (bank = 0; bank < NR_BANKS; ++bank) {
462 if (!(per_cpu(bank_map, cpu) & 1 << bank))
463 continue;
464 if (!shared_bank[bank])
465 continue;
466 threshold_remove_bank(lcpu, bank);
467 }
468 }
469}
470#else /* !CONFIG_HOTPLUG_CPU */
471static __cpuinit void threshold_create_symlinks(unsigned int cpu)
472{
473}
474static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
475{
476}
477static void threshold_remove_device(unsigned int cpu)
478{
479}
480#endif
481
482/* get notified when a cpu comes on/off */
483static __cpuinit int threshold_cpu_callback(struct notifier_block *nfb,
484 unsigned long action, void *hcpu)
485{
486 /* cpu was unsigned int to begin with */
487 unsigned int cpu = (unsigned long)hcpu;
488
489 if (cpu >= NR_CPUS)
490 goto out;
491
492 switch (action) {
493 case CPU_ONLINE:
494 threshold_create_device(cpu);
495 threshold_create_symlinks(cpu);
496 break;
497 case CPU_DOWN_PREPARE:
498 threshold_remove_symlinks(cpu);
499 break;
500 case CPU_DOWN_FAILED:
501 threshold_create_symlinks(cpu);
502 break;
503 case CPU_DEAD:
504 threshold_remove_device(cpu);
505 break;
506 default:
507 break;
508 }
509 out:
510 return NOTIFY_OK;
511}
512
513static struct notifier_block threshold_cpu_notifier = {
514 .notifier_call = threshold_cpu_callback,
515};
516
517static __init int threshold_init_device(void)
518{
519 int err;
520 int lcpu = 0;
521
522 err = sysdev_class_register(&threshold_sysclass);
523 if (err)
524 goto out;
525
526 /* to hit CPUs online before the notifier is up */
527 for_each_online_cpu(lcpu) {
528 err = threshold_create_device(lcpu);
529 if (err)
530 goto out;
531 }
532 register_cpu_notifier(&threshold_cpu_notifier);
533
534 out:
535 return err;
536}
537
538device_initcall(threshold_init_device);
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index f16d38d09daf..1105250bf02c 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -42,7 +42,7 @@ int acpi_found_madt;
42 * Various Linux-internal data structures created from the 42 * Various Linux-internal data structures created from the
43 * MP-table. 43 * MP-table.
44 */ 44 */
45int apic_version [MAX_APICS]; 45unsigned char apic_version [MAX_APICS];
46unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 46unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
47int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 47int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
48 48
@@ -65,7 +65,9 @@ unsigned long mp_lapic_addr = 0;
65/* Processor that is doing the boot up */ 65/* Processor that is doing the boot up */
66unsigned int boot_cpu_id = -1U; 66unsigned int boot_cpu_id = -1U;
67/* Internal processor count */ 67/* Internal processor count */
68static unsigned int num_processors = 0; 68unsigned int num_processors __initdata = 0;
69
70unsigned disabled_cpus __initdata;
69 71
70/* Bitmask of physically existing CPUs */ 72/* Bitmask of physically existing CPUs */
71physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; 73physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
@@ -106,11 +108,14 @@ static int __init mpf_checksum(unsigned char *mp, int len)
106 108
107static void __init MP_processor_info (struct mpc_config_processor *m) 109static void __init MP_processor_info (struct mpc_config_processor *m)
108{ 110{
109 int ver, cpu; 111 int cpu;
112 unsigned char ver;
110 static int found_bsp=0; 113 static int found_bsp=0;
111 114
112 if (!(m->mpc_cpuflag & CPU_ENABLED)) 115 if (!(m->mpc_cpuflag & CPU_ENABLED)) {
116 disabled_cpus++;
113 return; 117 return;
118 }
114 119
115 printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n", 120 printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
116 m->mpc_apicid, 121 m->mpc_apicid,
@@ -129,12 +134,14 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
129 } 134 }
130 135
131 cpu = num_processors++; 136 cpu = num_processors++;
132 137
133 if (m->mpc_apicid > MAX_APICS) { 138#if MAX_APICS < 255
139 if ((int)m->mpc_apicid > MAX_APICS) {
134 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", 140 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
135 m->mpc_apicid, MAX_APICS); 141 m->mpc_apicid, MAX_APICS);
136 return; 142 return;
137 } 143 }
144#endif
138 ver = m->mpc_apicver; 145 ver = m->mpc_apicver;
139 146
140 physid_set(m->mpc_apicid, phys_cpu_present_map); 147 physid_set(m->mpc_apicid, phys_cpu_present_map);
@@ -218,7 +225,7 @@ static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
218 m->mpc_irqtype, m->mpc_irqflag & 3, 225 m->mpc_irqtype, m->mpc_irqflag & 3,
219 (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, 226 (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
220 m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq); 227 m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
221 if (++mp_irq_entries == MAX_IRQ_SOURCES) 228 if (++mp_irq_entries >= MAX_IRQ_SOURCES)
222 panic("Max # of irq sources exceeded!!\n"); 229 panic("Max # of irq sources exceeded!!\n");
223} 230}
224 231
@@ -549,7 +556,7 @@ void __init get_smp_config (void)
549 * Read the physical hardware table. Anything here will 556 * Read the physical hardware table. Anything here will
550 * override the defaults. 557 * override the defaults.
551 */ 558 */
552 if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) { 559 if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
553 smp_found_config = 0; 560 smp_found_config = 0;
554 printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); 561 printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
555 printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); 562 printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 88be97c96987..2e28e855ec3c 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -220,6 +220,12 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
220 uses the normal dma_mask for alloc_coherent. */ 220 uses the normal dma_mask for alloc_coherent. */
221 dma_mask &= *dev->dma_mask; 221 dma_mask &= *dev->dma_mask;
222 222
223 /* Why <=? Even when the mask is smaller than 4GB it is often larger
224 than 16MB and in this case we have a chance of finding fitting memory
225 in the next higher zone first. If not retry with true GFP_DMA. -AK */
226 if (dma_mask <= 0xffffffff)
227 gfp |= GFP_DMA32;
228
223 again: 229 again:
224 memory = dma_alloc_pages(dev, gfp, get_order(size)); 230 memory = dma_alloc_pages(dev, gfp, get_order(size));
225 if (memory == NULL) 231 if (memory == NULL)
@@ -245,7 +251,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
245 } 251 }
246 252
247 if (!(gfp & GFP_DMA)) { 253 if (!(gfp & GFP_DMA)) {
248 gfp |= GFP_DMA; 254 gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
249 goto again; 255 goto again;
250 } 256 }
251 return NULL; 257 return NULL;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 59be85d9a4bc..5afd63e8cef7 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -144,7 +144,8 @@ void cpu_idle_wait(void)
144 do { 144 do {
145 ssleep(1); 145 ssleep(1);
146 for_each_online_cpu(cpu) { 146 for_each_online_cpu(cpu) {
147 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) 147 if (cpu_isset(cpu, map) &&
148 !per_cpu(cpu_idle_state, cpu))
148 cpu_clear(cpu, map); 149 cpu_clear(cpu, map);
149 } 150 }
150 cpus_and(map, map, cpu_online_map); 151 cpus_and(map, map, cpu_online_map);
@@ -275,7 +276,8 @@ void __show_regs(struct pt_regs * regs)
275 system_utsname.version); 276 system_utsname.version);
276 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); 277 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
277 printk_address(regs->rip); 278 printk_address(regs->rip);
278 printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags); 279 printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
280 regs->eflags);
279 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", 281 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
280 regs->rax, regs->rbx, regs->rcx); 282 regs->rax, regs->rbx, regs->rcx);
281 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", 283 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
@@ -427,15 +429,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
427 struct pt_regs * childregs; 429 struct pt_regs * childregs;
428 struct task_struct *me = current; 430 struct task_struct *me = current;
429 431
430 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; 432 childregs = ((struct pt_regs *)
431 433 (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
432 *childregs = *regs; 434 *childregs = *regs;
433 435
434 childregs->rax = 0; 436 childregs->rax = 0;
435 childregs->rsp = rsp; 437 childregs->rsp = rsp;
436 if (rsp == ~0UL) { 438 if (rsp == ~0UL)
437 childregs->rsp = (unsigned long)childregs; 439 childregs->rsp = (unsigned long)childregs;
438 }
439 440
440 p->thread.rsp = (unsigned long) childregs; 441 p->thread.rsp = (unsigned long) childregs;
441 p->thread.rsp0 = (unsigned long) (childregs+1); 442 p->thread.rsp0 = (unsigned long) (childregs+1);
@@ -457,7 +458,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
457 p->thread.io_bitmap_max = 0; 458 p->thread.io_bitmap_max = 0;
458 return -ENOMEM; 459 return -ENOMEM;
459 } 460 }
460 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, IO_BITMAP_BYTES); 461 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
462 IO_BITMAP_BYTES);
461 } 463 }
462 464
463 /* 465 /*
@@ -494,7 +496,8 @@ out:
494 * - fold all the options into a flag word and test it with a single test. 496 * - fold all the options into a flag word and test it with a single test.
495 * - could test fs/gs bitsliced 497 * - could test fs/gs bitsliced
496 */ 498 */
497struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *next_p) 499struct task_struct *
500__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
498{ 501{
499 struct thread_struct *prev = &prev_p->thread, 502 struct thread_struct *prev = &prev_p->thread,
500 *next = &next_p->thread; 503 *next = &next_p->thread;
@@ -565,7 +568,8 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *
565 prev->userrsp = read_pda(oldrsp); 568 prev->userrsp = read_pda(oldrsp);
566 write_pda(oldrsp, next->userrsp); 569 write_pda(oldrsp, next->userrsp);
567 write_pda(pcurrent, next_p); 570 write_pda(pcurrent, next_p);
568 write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET); 571 write_pda(kernelstack,
572 (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
569 573
570 /* 574 /*
571 * Now maybe reload the debug registers 575 * Now maybe reload the debug registers
@@ -646,7 +650,9 @@ asmlinkage long sys_fork(struct pt_regs *regs)
646 return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL); 650 return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
647} 651}
648 652
649asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) 653asmlinkage long
654sys_clone(unsigned long clone_flags, unsigned long newsp,
655 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
650{ 656{
651 if (!newsp) 657 if (!newsp)
652 newsp = regs->rsp; 658 newsp = regs->rsp;
@@ -682,7 +688,8 @@ unsigned long get_wchan(struct task_struct *p)
682 return 0; 688 return 0;
683 fp = *(u64 *)(p->thread.rsp); 689 fp = *(u64 *)(p->thread.rsp);
684 do { 690 do {
685 if (fp < (unsigned long)stack || fp > (unsigned long)stack+THREAD_SIZE) 691 if (fp < (unsigned long)stack ||
692 fp > (unsigned long)stack+THREAD_SIZE)
686 return 0; 693 return 0;
687 rip = *(u64 *)(fp+8); 694 rip = *(u64 *)(fp+8);
688 if (!in_sched_functions(rip)) 695 if (!in_sched_functions(rip))
@@ -717,8 +724,8 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
717 task->thread.gsindex = 0; 724 task->thread.gsindex = 0;
718 task->thread.gs = addr; 725 task->thread.gs = addr;
719 if (doit) { 726 if (doit) {
720 load_gs_index(0); 727 load_gs_index(0);
721 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 728 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
722 } 729 }
723 } 730 }
724 put_cpu(); 731 put_cpu();
@@ -735,7 +742,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
735 set_32bit_tls(task, FS_TLS, addr); 742 set_32bit_tls(task, FS_TLS, addr);
736 if (doit) { 743 if (doit) {
737 load_TLS(&task->thread, cpu); 744 load_TLS(&task->thread, cpu);
738 asm volatile("movl %0,%%fs" :: "r" (FS_TLS_SEL)); 745 asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
739 } 746 }
740 task->thread.fsindex = FS_TLS_SEL; 747 task->thread.fsindex = FS_TLS_SEL;
741 task->thread.fs = 0; 748 task->thread.fs = 0;
@@ -745,8 +752,8 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
745 if (doit) { 752 if (doit) {
746 /* set the selector to 0 to not confuse 753 /* set the selector to 0 to not confuse
747 __switch_to */ 754 __switch_to */
748 asm volatile("movl %0,%%fs" :: "r" (0)); 755 asm volatile("movl %0,%%fs" :: "r" (0));
749 ret = checking_wrmsrl(MSR_FS_BASE, addr); 756 ret = checking_wrmsrl(MSR_FS_BASE, addr);
750 } 757 }
751 } 758 }
752 put_cpu(); 759 put_cpu();
@@ -755,9 +762,9 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
755 unsigned long base; 762 unsigned long base;
756 if (task->thread.fsindex == FS_TLS_SEL) 763 if (task->thread.fsindex == FS_TLS_SEL)
757 base = read_32bit_tls(task, FS_TLS); 764 base = read_32bit_tls(task, FS_TLS);
758 else if (doit) { 765 else if (doit)
759 rdmsrl(MSR_FS_BASE, base); 766 rdmsrl(MSR_FS_BASE, base);
760 } else 767 else
761 base = task->thread.fs; 768 base = task->thread.fs;
762 ret = put_user(base, (unsigned long __user *)addr); 769 ret = put_user(base, (unsigned long __user *)addr);
763 break; 770 break;
@@ -766,9 +773,9 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
766 unsigned long base; 773 unsigned long base;
767 if (task->thread.gsindex == GS_TLS_SEL) 774 if (task->thread.gsindex == GS_TLS_SEL)
768 base = read_32bit_tls(task, GS_TLS); 775 base = read_32bit_tls(task, GS_TLS);
769 else if (doit) { 776 else if (doit)
770 rdmsrl(MSR_KERNEL_GS_BASE, base); 777 rdmsrl(MSR_KERNEL_GS_BASE, base);
771 } else 778 else
772 base = task->thread.gs; 779 base = task->thread.gs;
773 ret = put_user(base, (unsigned long __user *)addr); 780 ret = put_user(base, (unsigned long __user *)addr);
774 break; 781 break;
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 47f95687905f..75235ed2b31b 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -77,6 +77,7 @@ static inline void kb_wait(void)
77 77
78void machine_shutdown(void) 78void machine_shutdown(void)
79{ 79{
80 unsigned long flags;
80 /* Stop the cpus and apics */ 81 /* Stop the cpus and apics */
81#ifdef CONFIG_SMP 82#ifdef CONFIG_SMP
82 int reboot_cpu_id; 83 int reboot_cpu_id;
@@ -98,7 +99,7 @@ void machine_shutdown(void)
98 smp_send_stop(); 99 smp_send_stop();
99#endif 100#endif
100 101
101 local_irq_disable(); 102 local_irq_save(flags);
102 103
103#ifndef CONFIG_SMP 104#ifndef CONFIG_SMP
104 disable_local_APIC(); 105 disable_local_APIC();
@@ -106,7 +107,7 @@ void machine_shutdown(void)
106 107
107 disable_IO_APIC(); 108 disable_IO_APIC();
108 109
109 local_irq_enable(); 110 local_irq_restore(flags);
110} 111}
111 112
112void machine_emergency_restart(void) 113void machine_emergency_restart(void)
@@ -120,7 +121,7 @@ void machine_emergency_restart(void)
120 /* Could also try the reset bit in the Hammer NB */ 121 /* Could also try the reset bit in the Hammer NB */
121 switch (reboot_type) { 122 switch (reboot_type) {
122 case BOOT_KBD: 123 case BOOT_KBD:
123 for (i=0; i<100; i++) { 124 for (i=0; i<10; i++) {
124 kb_wait(); 125 kb_wait();
125 udelay(50); 126 udelay(50);
126 outb(0xfe,0x64); /* pulse reset low */ 127 outb(0xfe,0x64); /* pulse reset low */
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index da0bc3e7bdf5..750e01dcbdf4 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -60,6 +60,7 @@
60#include <asm/setup.h> 60#include <asm/setup.h>
61#include <asm/mach_apic.h> 61#include <asm/mach_apic.h>
62#include <asm/numa.h> 62#include <asm/numa.h>
63#include <asm/sections.h>
63 64
64/* 65/*
65 * Machine setup.. 66 * Machine setup..
@@ -103,7 +104,6 @@ struct edid_info edid_info;
103struct e820map e820; 104struct e820map e820;
104 105
105extern int root_mountflags; 106extern int root_mountflags;
106extern char _text, _etext, _edata, _end;
107 107
108char command_line[COMMAND_LINE_SIZE]; 108char command_line[COMMAND_LINE_SIZE];
109 109
@@ -412,7 +412,6 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
412{ 412{
413 unsigned long bootmap_size, bootmap; 413 unsigned long bootmap_size, bootmap;
414 414
415 memory_present(0, start_pfn, end_pfn);
416 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; 415 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
417 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); 416 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
418 if (bootmap == -1L) 417 if (bootmap == -1L)
@@ -571,6 +570,8 @@ void __init setup_arch(char **cmdline_p)
571 570
572 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); 571 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
573 572
573 zap_low_mappings(0);
574
574#ifdef CONFIG_ACPI 575#ifdef CONFIG_ACPI
575 /* 576 /*
576 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). 577 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -657,8 +658,6 @@ void __init setup_arch(char **cmdline_p)
657 } 658 }
658#endif 659#endif
659 660
660 sparse_init();
661
662 paging_init(); 661 paging_init();
663 662
664 check_ioapic(); 663 check_ioapic();
@@ -793,7 +792,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
793#endif 792#endif
794 793
795 bits = 0; 794 bits = 0;
796 while ((1 << bits) < c->x86_num_cores) 795 while ((1 << bits) < c->x86_max_cores)
797 bits++; 796 bits++;
798 797
799 /* Low order bits define the core id (index of core in socket) */ 798 /* Low order bits define the core id (index of core in socket) */
@@ -823,10 +822,10 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
823 if (!node_online(node)) 822 if (!node_online(node))
824 node = nearby_node(apicid); 823 node = nearby_node(apicid);
825 } 824 }
826 cpu_to_node[cpu] = node; 825 numa_set_node(cpu, node);
827 826
828 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", 827 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
829 cpu, c->x86_num_cores, node, cpu_core_id[cpu]); 828 cpu, c->x86_max_cores, node, cpu_core_id[cpu]);
830#endif 829#endif
831#endif 830#endif
832} 831}
@@ -875,9 +874,9 @@ static int __init init_amd(struct cpuinfo_x86 *c)
875 display_cacheinfo(c); 874 display_cacheinfo(c);
876 875
877 if (c->extended_cpuid_level >= 0x80000008) { 876 if (c->extended_cpuid_level >= 0x80000008) {
878 c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; 877 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
879 if (c->x86_num_cores & (c->x86_num_cores - 1)) 878 if (c->x86_max_cores & (c->x86_max_cores - 1))
880 c->x86_num_cores = 1; 879 c->x86_max_cores = 1;
881 880
882 amd_detect_cmp(c); 881 amd_detect_cmp(c);
883 } 882 }
@@ -889,54 +888,44 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
889{ 888{
890#ifdef CONFIG_SMP 889#ifdef CONFIG_SMP
891 u32 eax, ebx, ecx, edx; 890 u32 eax, ebx, ecx, edx;
892 int index_msb, tmp; 891 int index_msb, core_bits;
893 int cpu = smp_processor_id(); 892 int cpu = smp_processor_id();
894 893
894 cpuid(1, &eax, &ebx, &ecx, &edx);
895
896 c->apicid = phys_pkg_id(0);
897
895 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 898 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
896 return; 899 return;
897 900
898 cpuid(1, &eax, &ebx, &ecx, &edx);
899 smp_num_siblings = (ebx & 0xff0000) >> 16; 901 smp_num_siblings = (ebx & 0xff0000) >> 16;
900 902
901 if (smp_num_siblings == 1) { 903 if (smp_num_siblings == 1) {
902 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 904 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
903 } else if (smp_num_siblings > 1) { 905 } else if (smp_num_siblings > 1 ) {
904 index_msb = 31; 906
905 /*
906 * At this point we only support two siblings per
907 * processor package.
908 */
909 if (smp_num_siblings > NR_CPUS) { 907 if (smp_num_siblings > NR_CPUS) {
910 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); 908 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
911 smp_num_siblings = 1; 909 smp_num_siblings = 1;
912 return; 910 return;
913 } 911 }
914 tmp = smp_num_siblings; 912
915 while ((tmp & 0x80000000 ) == 0) { 913 index_msb = get_count_order(smp_num_siblings);
916 tmp <<=1 ;
917 index_msb--;
918 }
919 if (smp_num_siblings & (smp_num_siblings - 1))
920 index_msb++;
921 phys_proc_id[cpu] = phys_pkg_id(index_msb); 914 phys_proc_id[cpu] = phys_pkg_id(index_msb);
922 915
923 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 916 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
924 phys_proc_id[cpu]); 917 phys_proc_id[cpu]);
925 918
926 smp_num_siblings = smp_num_siblings / c->x86_num_cores; 919 smp_num_siblings = smp_num_siblings / c->x86_max_cores;
927 920
928 tmp = smp_num_siblings; 921 index_msb = get_count_order(smp_num_siblings) ;
929 index_msb = 31;
930 while ((tmp & 0x80000000) == 0) {
931 tmp <<=1 ;
932 index_msb--;
933 }
934 if (smp_num_siblings & (smp_num_siblings - 1))
935 index_msb++;
936 922
937 cpu_core_id[cpu] = phys_pkg_id(index_msb); 923 core_bits = get_count_order(c->x86_max_cores);
938 924
939 if (c->x86_num_cores > 1) 925 cpu_core_id[cpu] = phys_pkg_id(index_msb) &
926 ((1 << core_bits) - 1);
927
928 if (c->x86_max_cores > 1)
940 printk(KERN_INFO "CPU: Processor Core ID: %d\n", 929 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
941 cpu_core_id[cpu]); 930 cpu_core_id[cpu]);
942 } 931 }
@@ -975,7 +964,7 @@ static void srat_detect_node(void)
975 node = apicid_to_node[hard_smp_processor_id()]; 964 node = apicid_to_node[hard_smp_processor_id()];
976 if (node == NUMA_NO_NODE) 965 if (node == NUMA_NO_NODE)
977 node = 0; 966 node = 0;
978 cpu_to_node[cpu] = node; 967 numa_set_node(cpu, node);
979 968
980 if (acpi_numa > 0) 969 if (acpi_numa > 0)
981 printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node); 970 printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
@@ -993,13 +982,18 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
993 unsigned eax = cpuid_eax(0x80000008); 982 unsigned eax = cpuid_eax(0x80000008);
994 c->x86_virt_bits = (eax >> 8) & 0xff; 983 c->x86_virt_bits = (eax >> 8) & 0xff;
995 c->x86_phys_bits = eax & 0xff; 984 c->x86_phys_bits = eax & 0xff;
985 /* CPUID workaround for Intel 0F34 CPU */
986 if (c->x86_vendor == X86_VENDOR_INTEL &&
987 c->x86 == 0xF && c->x86_model == 0x3 &&
988 c->x86_mask == 0x4)
989 c->x86_phys_bits = 36;
996 } 990 }
997 991
998 if (c->x86 == 15) 992 if (c->x86 == 15)
999 c->x86_cache_alignment = c->x86_clflush_size * 2; 993 c->x86_cache_alignment = c->x86_clflush_size * 2;
1000 if (c->x86 >= 15) 994 if (c->x86 >= 15)
1001 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); 995 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
1002 c->x86_num_cores = intel_num_cpu_cores(c); 996 c->x86_max_cores = intel_num_cpu_cores(c);
1003 997
1004 srat_detect_node(); 998 srat_detect_node();
1005} 999}
@@ -1037,7 +1031,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
1037 c->x86_model_id[0] = '\0'; /* Unset */ 1031 c->x86_model_id[0] = '\0'; /* Unset */
1038 c->x86_clflush_size = 64; 1032 c->x86_clflush_size = 64;
1039 c->x86_cache_alignment = c->x86_clflush_size; 1033 c->x86_cache_alignment = c->x86_clflush_size;
1040 c->x86_num_cores = 1; 1034 c->x86_max_cores = 1;
1041 c->extended_cpuid_level = 0; 1035 c->extended_cpuid_level = 0;
1042 memset(&c->x86_capability, 0, sizeof c->x86_capability); 1036 memset(&c->x86_capability, 0, sizeof c->x86_capability);
1043 1037
@@ -1060,10 +1054,10 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
1060 c->x86 = (tfms >> 8) & 0xf; 1054 c->x86 = (tfms >> 8) & 0xf;
1061 c->x86_model = (tfms >> 4) & 0xf; 1055 c->x86_model = (tfms >> 4) & 0xf;
1062 c->x86_mask = tfms & 0xf; 1056 c->x86_mask = tfms & 0xf;
1063 if (c->x86 == 0xf) { 1057 if (c->x86 == 0xf)
1064 c->x86 += (tfms >> 20) & 0xff; 1058 c->x86 += (tfms >> 20) & 0xff;
1059 if (c->x86 >= 0x6)
1065 c->x86_model += ((tfms >> 16) & 0xF) << 4; 1060 c->x86_model += ((tfms >> 16) & 0xF) << 4;
1066 }
1067 if (c->x86_capability[0] & (1<<19)) 1061 if (c->x86_capability[0] & (1<<19))
1068 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; 1062 c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
1069 } else { 1063 } else {
@@ -1271,13 +1265,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1271 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); 1265 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
1272 1266
1273#ifdef CONFIG_SMP 1267#ifdef CONFIG_SMP
1274 if (smp_num_siblings * c->x86_num_cores > 1) { 1268 if (smp_num_siblings * c->x86_max_cores > 1) {
1275 int cpu = c - cpu_data; 1269 int cpu = c - cpu_data;
1276 seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); 1270 seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
1277 seq_printf(m, "siblings\t: %d\n", 1271 seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu]));
1278 c->x86_num_cores * smp_num_siblings);
1279 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); 1272 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
1280 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores); 1273 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
1281 } 1274 }
1282#endif 1275#endif
1283 1276
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 79190891fbc5..06dc354375c3 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -141,7 +141,6 @@ void pda_init(int cpu)
141 panic("cannot allocate irqstack for cpu %d", cpu); 141 panic("cannot allocate irqstack for cpu %d", cpu);
142 } 142 }
143 143
144 asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
145 144
146 pda->irqstackptr += IRQSTACKSIZE-64; 145 pda->irqstackptr += IRQSTACKSIZE-64;
147} 146}
@@ -197,6 +196,7 @@ void __cpuinit cpu_init (void)
197 /* CPU 0 is initialised in head64.c */ 196 /* CPU 0 is initialised in head64.c */
198 if (cpu != 0) { 197 if (cpu != 0) {
199 pda_init(cpu); 198 pda_init(cpu);
199 zap_low_mappings(cpu);
200 } else 200 } else
201 estacks = boot_exception_stacks; 201 estacks = boot_exception_stacks;
202 202
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index d642fbf3da29..5876df116c92 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -110,6 +110,15 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
110 COPY(r14); 110 COPY(r14);
111 COPY(r15); 111 COPY(r15);
112 112
113 /* Kernel saves and restores only the CS segment register on signals,
114 * which is the bare minimum needed to allow mixed 32/64-bit code.
115 * App's signal handler can save/restore other segments if needed. */
116 {
117 unsigned cs;
118 err |= __get_user(cs, &sc->cs);
119 regs->cs = cs | 3; /* Force into user mode */
120 }
121
113 { 122 {
114 unsigned int tmpflags; 123 unsigned int tmpflags;
115 err |= __get_user(tmpflags, &sc->eflags); 124 err |= __get_user(tmpflags, &sc->eflags);
@@ -187,6 +196,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
187{ 196{
188 int err = 0; 197 int err = 0;
189 198
199 err |= __put_user(regs->cs, &sc->cs);
190 err |= __put_user(0, &sc->gs); 200 err |= __put_user(0, &sc->gs);
191 err |= __put_user(0, &sc->fs); 201 err |= __put_user(0, &sc->fs);
192 202
@@ -318,7 +328,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
318 328
319 regs->rsp = (unsigned long)frame; 329 regs->rsp = (unsigned long)frame;
320 330
331 /* Set up the CS register to run signal handlers in 64-bit mode,
332 even if the handler happens to be interrupting 32-bit code. */
333 regs->cs = __USER_CS;
334
335 /* This, by contrast, has nothing to do with segment registers -
336 see include/asm-x86_64/uaccess.h for details. */
321 set_fs(USER_DS); 337 set_fs(USER_DS);
338
322 regs->eflags &= ~TF_MASK; 339 regs->eflags &= ~TF_MASK;
323 if (test_thread_flag(TIF_SINGLESTEP)) 340 if (test_thread_flag(TIF_SINGLESTEP))
324 ptrace_notify(SIGTRAP); 341 ptrace_notify(SIGTRAP);
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 9db9dda161b4..cfc3d9dccbd9 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -28,8 +28,6 @@
28#include <asm/proto.h> 28#include <asm/proto.h>
29#include <asm/apicdef.h> 29#include <asm/apicdef.h>
30 30
31#define __cpuinit __init
32
33/* 31/*
34 * Smarter SMP flushing macros. 32 * Smarter SMP flushing macros.
35 * c/o Linus Torvalds. 33 * c/o Linus Torvalds.
@@ -452,13 +450,14 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
452 450
453void smp_stop_cpu(void) 451void smp_stop_cpu(void)
454{ 452{
453 unsigned long flags;
455 /* 454 /*
456 * Remove this CPU: 455 * Remove this CPU:
457 */ 456 */
458 cpu_clear(smp_processor_id(), cpu_online_map); 457 cpu_clear(smp_processor_id(), cpu_online_map);
459 local_irq_disable(); 458 local_irq_save(flags);
460 disable_local_APIC(); 459 disable_local_APIC();
461 local_irq_enable(); 460 local_irq_restore(flags);
462} 461}
463 462
464static void smp_really_stop_cpu(void *dummy) 463static void smp_really_stop_cpu(void *dummy)
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index c4e59bbdc187..683c33f7b967 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -64,6 +64,7 @@
64int smp_num_siblings = 1; 64int smp_num_siblings = 1;
65/* Package ID of each logical CPU */ 65/* Package ID of each logical CPU */
66u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 66u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
67/* core ID of each logical CPU */
67u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 68u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
68 69
69/* Bitmask of currently online CPUs */ 70/* Bitmask of currently online CPUs */
@@ -87,7 +88,10 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
87/* Set when the idlers are all forked */ 88/* Set when the idlers are all forked */
88int smp_threads_ready; 89int smp_threads_ready;
89 90
91/* representing HT siblings of each logical CPU */
90cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 92cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
93
94/* representing HT and core siblings of each logical CPU */
91cpumask_t cpu_core_map[NR_CPUS] __read_mostly; 95cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
92EXPORT_SYMBOL(cpu_core_map); 96EXPORT_SYMBOL(cpu_core_map);
93 97
@@ -434,30 +438,59 @@ void __cpuinit smp_callin(void)
434 cpu_set(cpuid, cpu_callin_map); 438 cpu_set(cpuid, cpu_callin_map);
435} 439}
436 440
441/* representing cpus for which sibling maps can be computed */
442static cpumask_t cpu_sibling_setup_map;
443
437static inline void set_cpu_sibling_map(int cpu) 444static inline void set_cpu_sibling_map(int cpu)
438{ 445{
439 int i; 446 int i;
447 struct cpuinfo_x86 *c = cpu_data;
448
449 cpu_set(cpu, cpu_sibling_setup_map);
440 450
441 if (smp_num_siblings > 1) { 451 if (smp_num_siblings > 1) {
442 for_each_cpu(i) { 452 for_each_cpu_mask(i, cpu_sibling_setup_map) {
443 if (cpu_core_id[cpu] == cpu_core_id[i]) { 453 if (phys_proc_id[cpu] == phys_proc_id[i] &&
454 cpu_core_id[cpu] == cpu_core_id[i]) {
444 cpu_set(i, cpu_sibling_map[cpu]); 455 cpu_set(i, cpu_sibling_map[cpu]);
445 cpu_set(cpu, cpu_sibling_map[i]); 456 cpu_set(cpu, cpu_sibling_map[i]);
457 cpu_set(i, cpu_core_map[cpu]);
458 cpu_set(cpu, cpu_core_map[i]);
446 } 459 }
447 } 460 }
448 } else { 461 } else {
449 cpu_set(cpu, cpu_sibling_map[cpu]); 462 cpu_set(cpu, cpu_sibling_map[cpu]);
450 } 463 }
451 464
452 if (current_cpu_data.x86_num_cores > 1) { 465 if (current_cpu_data.x86_max_cores == 1) {
453 for_each_cpu(i) {
454 if (phys_proc_id[cpu] == phys_proc_id[i]) {
455 cpu_set(i, cpu_core_map[cpu]);
456 cpu_set(cpu, cpu_core_map[i]);
457 }
458 }
459 } else {
460 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 466 cpu_core_map[cpu] = cpu_sibling_map[cpu];
467 c[cpu].booted_cores = 1;
468 return;
469 }
470
471 for_each_cpu_mask(i, cpu_sibling_setup_map) {
472 if (phys_proc_id[cpu] == phys_proc_id[i]) {
473 cpu_set(i, cpu_core_map[cpu]);
474 cpu_set(cpu, cpu_core_map[i]);
475 /*
476 * Does this new cpu bringup a new core?
477 */
478 if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
479 /*
480 * for each core in package, increment
481 * the booted_cores for this new cpu
482 */
483 if (first_cpu(cpu_sibling_map[i]) == i)
484 c[cpu].booted_cores++;
485 /*
486 * increment the core count for all
487 * the other cpus in this package
488 */
489 if (i != cpu)
490 c[i].booted_cores++;
491 } else if (i != cpu && !c[cpu].booted_cores)
492 c[cpu].booted_cores = c[i].booted_cores;
493 }
461 } 494 }
462} 495}
463 496
@@ -879,6 +912,9 @@ static __init void disable_smp(void)
879} 912}
880 913
881#ifdef CONFIG_HOTPLUG_CPU 914#ifdef CONFIG_HOTPLUG_CPU
915
916int additional_cpus __initdata = -1;
917
882/* 918/*
883 * cpu_possible_map should be static, it cannot change as cpu's 919 * cpu_possible_map should be static, it cannot change as cpu's
884 * are onlined, or offlined. The reason is per-cpu data-structures 920 * are onlined, or offlined. The reason is per-cpu data-structures
@@ -887,14 +923,38 @@ static __init void disable_smp(void)
887 * cpu_present_map on the other hand can change dynamically. 923 * cpu_present_map on the other hand can change dynamically.
888 * In case when cpu_hotplug is not compiled, then we resort to current 924 * In case when cpu_hotplug is not compiled, then we resort to current
889 * behaviour, which is cpu_possible == cpu_present. 925 * behaviour, which is cpu_possible == cpu_present.
890 * If cpu-hotplug is supported, then we need to preallocate for all
891 * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
892 * - Ashok Raj 926 * - Ashok Raj
927 *
928 * Three ways to find out the number of additional hotplug CPUs:
929 * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
930 * - otherwise use half of the available CPUs or 2, whatever is more.
931 * - The user can overwrite it with additional_cpus=NUM
932 * We do this because additional CPUs waste a lot of memory.
933 * -AK
893 */ 934 */
894__init void prefill_possible_map(void) 935__init void prefill_possible_map(void)
895{ 936{
896 int i; 937 int i;
897 for (i = 0; i < NR_CPUS; i++) 938 int possible;
939
940 if (additional_cpus == -1) {
941 if (disabled_cpus > 0) {
942 additional_cpus = disabled_cpus;
943 } else {
944 additional_cpus = num_processors / 2;
945 if (additional_cpus == 0)
946 additional_cpus = 2;
947 }
948 }
949 possible = num_processors + additional_cpus;
950 if (possible > NR_CPUS)
951 possible = NR_CPUS;
952
953 printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
954 possible,
955 max_t(int, possible - num_processors, 0));
956
957 for (i = 0; i < possible; i++)
898 cpu_set(i, cpu_possible_map); 958 cpu_set(i, cpu_possible_map);
899} 959}
900#endif 960#endif
@@ -965,6 +1025,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
965 nmi_watchdog_default(); 1025 nmi_watchdog_default();
966 current_cpu_data = boot_cpu_data; 1026 current_cpu_data = boot_cpu_data;
967 current_thread_info()->cpu = 0; /* needed? */ 1027 current_thread_info()->cpu = 0; /* needed? */
1028 set_cpu_sibling_map(0);
968 1029
969 if (smp_sanity_check(max_cpus) < 0) { 1030 if (smp_sanity_check(max_cpus) < 0) {
970 printk(KERN_INFO "SMP disabled\n"); 1031 printk(KERN_INFO "SMP disabled\n");
@@ -1008,8 +1069,6 @@ void __init smp_prepare_boot_cpu(void)
1008 int me = smp_processor_id(); 1069 int me = smp_processor_id();
1009 cpu_set(me, cpu_online_map); 1070 cpu_set(me, cpu_online_map);
1010 cpu_set(me, cpu_callout_map); 1071 cpu_set(me, cpu_callout_map);
1011 cpu_set(0, cpu_sibling_map[0]);
1012 cpu_set(0, cpu_core_map[0]);
1013 per_cpu(cpu_state, me) = CPU_ONLINE; 1072 per_cpu(cpu_state, me) = CPU_ONLINE;
1014} 1073}
1015 1074
@@ -1062,9 +1121,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
1062 */ 1121 */
1063void __init smp_cpus_done(unsigned int max_cpus) 1122void __init smp_cpus_done(unsigned int max_cpus)
1064{ 1123{
1065#ifndef CONFIG_HOTPLUG_CPU
1066 zap_low_mappings();
1067#endif
1068 smp_cleanup_boot(); 1124 smp_cleanup_boot();
1069 1125
1070#ifdef CONFIG_X86_IO_APIC 1126#ifdef CONFIG_X86_IO_APIC
@@ -1081,15 +1137,24 @@ void __init smp_cpus_done(unsigned int max_cpus)
1081static void remove_siblinginfo(int cpu) 1137static void remove_siblinginfo(int cpu)
1082{ 1138{
1083 int sibling; 1139 int sibling;
1140 struct cpuinfo_x86 *c = cpu_data;
1084 1141
1142 for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
1143 cpu_clear(cpu, cpu_core_map[sibling]);
1144 /*
1145 * last thread sibling in this cpu core going down
1146 */
1147 if (cpus_weight(cpu_sibling_map[cpu]) == 1)
1148 c[sibling].booted_cores--;
1149 }
1150
1085 for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) 1151 for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
1086 cpu_clear(cpu, cpu_sibling_map[sibling]); 1152 cpu_clear(cpu, cpu_sibling_map[sibling]);
1087 for_each_cpu_mask(sibling, cpu_core_map[cpu])
1088 cpu_clear(cpu, cpu_core_map[sibling]);
1089 cpus_clear(cpu_sibling_map[cpu]); 1153 cpus_clear(cpu_sibling_map[cpu]);
1090 cpus_clear(cpu_core_map[cpu]); 1154 cpus_clear(cpu_core_map[cpu]);
1091 phys_proc_id[cpu] = BAD_APICID; 1155 phys_proc_id[cpu] = BAD_APICID;
1092 cpu_core_id[cpu] = BAD_APICID; 1156 cpu_core_id[cpu] = BAD_APICID;
1157 cpu_clear(cpu, cpu_sibling_setup_map);
1093} 1158}
1094 1159
1095void remove_cpu_from_maps(void) 1160void remove_cpu_from_maps(void)
@@ -1153,6 +1218,12 @@ void __cpu_die(unsigned int cpu)
1153 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1218 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1154} 1219}
1155 1220
1221static __init int setup_additional_cpus(char *s)
1222{
1223 return get_option(&s, &additional_cpus);
1224}
1225__setup("additional_cpus=", setup_additional_cpus);
1226
1156#else /* ... !CONFIG_HOTPLUG_CPU */ 1227#else /* ... !CONFIG_HOTPLUG_CPU */
1157 1228
1158int __cpu_disable(void) 1229int __cpu_disable(void)
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index cc7821c68851..6449ea8fe756 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -154,17 +154,3 @@ asmlinkage long sys_uname(struct new_utsname __user * name)
154 err |= copy_to_user(&name->machine, "i686", 5); 154 err |= copy_to_user(&name->machine, "i686", 5);
155 return err ? -EFAULT : 0; 155 return err ? -EFAULT : 0;
156} 156}
157
158asmlinkage long sys_time64(long __user * tloc)
159{
160 struct timeval now;
161 int i;
162
163 do_gettimeofday(&now);
164 i = now.tv_sec;
165 if (tloc) {
166 if (put_user(i,tloc))
167 i = -EFAULT;
168 }
169 return i;
170}
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index b5e09e6b5536..bf337f493189 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -428,19 +428,6 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
428{ 428{
429 conditional_sti(regs); 429 conditional_sti(regs);
430 430
431#ifdef CONFIG_CHECKING
432 {
433 unsigned long gs;
434 struct x8664_pda *pda = cpu_pda + safe_smp_processor_id();
435 rdmsrl(MSR_GS_BASE, gs);
436 if (gs != (unsigned long)pda) {
437 wrmsrl(MSR_GS_BASE, pda);
438 printk("%s: wrong gs %lx expected %p rip %lx\n", str, gs, pda,
439 regs->rip);
440 }
441 }
442#endif
443
444 if (user_mode(regs)) { 431 if (user_mode(regs)) {
445 struct task_struct *tsk = current; 432 struct task_struct *tsk = current;
446 433
@@ -513,20 +500,6 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
513{ 500{
514 conditional_sti(regs); 501 conditional_sti(regs);
515 502
516#ifdef CONFIG_CHECKING
517 {
518 unsigned long gs;
519 struct x8664_pda *pda = cpu_pda + safe_smp_processor_id();
520 rdmsrl(MSR_GS_BASE, gs);
521 if (gs != (unsigned long)pda) {
522 wrmsrl(MSR_GS_BASE, pda);
523 oops_in_progress++;
524 printk("general protection handler: wrong gs %lx expected %p\n", gs, pda);
525 oops_in_progress--;
526 }
527 }
528#endif
529
530 if (user_mode(regs)) { 503 if (user_mode(regs)) {
531 struct task_struct *tsk = current; 504 struct task_struct *tsk = current;
532 505
@@ -665,19 +638,6 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
665 struct task_struct *tsk = current; 638 struct task_struct *tsk = current;
666 siginfo_t info; 639 siginfo_t info;
667 640
668#ifdef CONFIG_CHECKING
669 {
670 /* RED-PEN interaction with debugger - could destroy gs */
671 unsigned long gs;
672 struct x8664_pda *pda = cpu_pda + safe_smp_processor_id();
673 rdmsrl(MSR_GS_BASE, gs);
674 if (gs != (unsigned long)pda) {
675 wrmsrl(MSR_GS_BASE, pda);
676 printk("debug handler: wrong gs %lx expected %p\n", gs, pda);
677 }
678 }
679#endif
680
681 get_debugreg(condition, 6); 641 get_debugreg(condition, 6);
682 642
683 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 643 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
@@ -888,6 +848,10 @@ asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
888{ 848{
889} 849}
890 850
851asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
852{
853}
854
891/* 855/*
892 * 'math_state_restore()' saves the current math information in the 856 * 'math_state_restore()' saves the current math information in the
893 * old math state array, and gets the new ones from the current task 857 * old math state array, and gets the new ones from the current task
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 6dd642cad2ef..58b19215b4b3 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
50 *(.bss.page_aligned) 50 *(.bss.page_aligned)
51 *(.bss) 51 *(.bss)
52 } 52 }
53 __bss_end = .; 53 __bss_stop = .;
54 54
55 . = ALIGN(PAGE_SIZE); 55 . = ALIGN(PAGE_SIZE);
56 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 56 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index fd99ddd009bc..4a54221e10bc 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -203,3 +203,6 @@ EXPORT_SYMBOL(flush_tlb_page);
203#endif 203#endif
204 204
205EXPORT_SYMBOL(cpu_khz); 205EXPORT_SYMBOL(cpu_khz);
206
207EXPORT_SYMBOL(load_gs_index);
208
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
index 30a9da458c15..43d9fa136180 100644
--- a/arch/x86_64/lib/clear_page.S
+++ b/arch/x86_64/lib/clear_page.S
@@ -5,46 +5,8 @@
5 .globl clear_page 5 .globl clear_page
6 .p2align 4 6 .p2align 4
7clear_page: 7clear_page:
8 xorl %eax,%eax
9 movl $4096/64,%ecx
10 .p2align 4
11.Lloop:
12 decl %ecx
13#define PUT(x) movq %rax,x*8(%rdi)
14 movq %rax,(%rdi)
15 PUT(1)
16 PUT(2)
17 PUT(3)
18 PUT(4)
19 PUT(5)
20 PUT(6)
21 PUT(7)
22 leaq 64(%rdi),%rdi
23 jnz .Lloop
24 nop
25 ret
26clear_page_end:
27
28 /* C stepping K8 run faster using the string instructions.
29 It is also a lot simpler. Use this when possible */
30
31#include <asm/cpufeature.h>
32
33 .section .altinstructions,"a"
34 .align 8
35 .quad clear_page
36 .quad clear_page_c
37 .byte X86_FEATURE_K8_C
38 .byte clear_page_end-clear_page
39 .byte clear_page_c_end-clear_page_c
40 .previous
41
42 .section .altinstr_replacement,"ax"
43clear_page_c:
44 movl $4096/8,%ecx 8 movl $4096/8,%ecx
45 xorl %eax,%eax 9 xorl %eax,%eax
46 rep 10 rep
47 stosq 11 stosq
48 ret 12 ret
49clear_page_c_end:
50 .previous
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
index dd3aa47b6bf5..621a19769406 100644
--- a/arch/x86_64/lib/copy_page.S
+++ b/arch/x86_64/lib/copy_page.S
@@ -8,94 +8,7 @@
8 .globl copy_page 8 .globl copy_page
9 .p2align 4 9 .p2align 4
10copy_page: 10copy_page:
11 subq $3*8,%rsp
12 movq %rbx,(%rsp)
13 movq %r12,1*8(%rsp)
14 movq %r13,2*8(%rsp)
15
16 movl $(4096/64)-5,%ecx
17 .p2align 4
18.Loop64:
19 dec %rcx
20
21 movq (%rsi), %rax
22 movq 8 (%rsi), %rbx
23 movq 16 (%rsi), %rdx
24 movq 24 (%rsi), %r8
25 movq 32 (%rsi), %r9
26 movq 40 (%rsi), %r10
27 movq 48 (%rsi), %r11
28 movq 56 (%rsi), %r12
29
30 prefetcht0 5*64(%rsi)
31
32 movq %rax, (%rdi)
33 movq %rbx, 8 (%rdi)
34 movq %rdx, 16 (%rdi)
35 movq %r8, 24 (%rdi)
36 movq %r9, 32 (%rdi)
37 movq %r10, 40 (%rdi)
38 movq %r11, 48 (%rdi)
39 movq %r12, 56 (%rdi)
40
41 leaq 64 (%rsi), %rsi
42 leaq 64 (%rdi), %rdi
43
44 jnz .Loop64
45
46 movl $5,%ecx
47 .p2align 4
48.Loop2:
49 decl %ecx
50
51 movq (%rsi), %rax
52 movq 8 (%rsi), %rbx
53 movq 16 (%rsi), %rdx
54 movq 24 (%rsi), %r8
55 movq 32 (%rsi), %r9
56 movq 40 (%rsi), %r10
57 movq 48 (%rsi), %r11
58 movq 56 (%rsi), %r12
59
60 movq %rax, (%rdi)
61 movq %rbx, 8 (%rdi)
62 movq %rdx, 16 (%rdi)
63 movq %r8, 24 (%rdi)
64 movq %r9, 32 (%rdi)
65 movq %r10, 40 (%rdi)
66 movq %r11, 48 (%rdi)
67 movq %r12, 56 (%rdi)
68
69 leaq 64(%rdi),%rdi
70 leaq 64(%rsi),%rsi
71
72 jnz .Loop2
73
74 movq (%rsp),%rbx
75 movq 1*8(%rsp),%r12
76 movq 2*8(%rsp),%r13
77 addq $3*8,%rsp
78 ret
79
80 /* C stepping K8 run faster using the string copy instructions.
81 It is also a lot simpler. Use this when possible */
82
83#include <asm/cpufeature.h>
84
85 .section .altinstructions,"a"
86 .align 8
87 .quad copy_page
88 .quad copy_page_c
89 .byte X86_FEATURE_K8_C
90 .byte copy_page_c_end-copy_page_c
91 .byte copy_page_c_end-copy_page_c
92 .previous
93
94 .section .altinstr_replacement,"ax"
95copy_page_c:
96 movl $4096/8,%ecx 11 movl $4096/8,%ecx
97 rep 12 rep
98 movsq 13 movsq
99 ret 14 ret
100copy_page_c_end:
101 .previous
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
index c6c46494fef5..92dd80544602 100644
--- a/arch/x86_64/lib/memcpy.S
+++ b/arch/x86_64/lib/memcpy.S
@@ -11,6 +11,8 @@
11 * 11 *
12 * Output: 12 * Output:
13 * rax original destination 13 * rax original destination
14 *
15 * TODO: check best memcpy for PSC
14 */ 16 */
15 17
16 .globl __memcpy 18 .globl __memcpy
@@ -18,95 +20,6 @@
18 .p2align 4 20 .p2align 4
19__memcpy: 21__memcpy:
20memcpy: 22memcpy:
21 pushq %rbx
22 movq %rdi,%rax
23
24 movl %edx,%ecx
25 shrl $6,%ecx
26 jz .Lhandle_tail
27
28 .p2align 4
29.Lloop_64:
30 decl %ecx
31
32 movq (%rsi),%r11
33 movq 8(%rsi),%r8
34
35 movq %r11,(%rdi)
36 movq %r8,1*8(%rdi)
37
38 movq 2*8(%rsi),%r9
39 movq 3*8(%rsi),%r10
40
41 movq %r9,2*8(%rdi)
42 movq %r10,3*8(%rdi)
43
44 movq 4*8(%rsi),%r11
45 movq 5*8(%rsi),%r8
46
47 movq %r11,4*8(%rdi)
48 movq %r8,5*8(%rdi)
49
50 movq 6*8(%rsi),%r9
51 movq 7*8(%rsi),%r10
52
53 movq %r9,6*8(%rdi)
54 movq %r10,7*8(%rdi)
55
56 leaq 64(%rsi),%rsi
57 leaq 64(%rdi),%rdi
58 jnz .Lloop_64
59
60.Lhandle_tail:
61 movl %edx,%ecx
62 andl $63,%ecx
63 shrl $3,%ecx
64 jz .Lhandle_7
65 .p2align 4
66.Lloop_8:
67 decl %ecx
68 movq (%rsi),%r8
69 movq %r8,(%rdi)
70 leaq 8(%rdi),%rdi
71 leaq 8(%rsi),%rsi
72 jnz .Lloop_8
73
74.Lhandle_7:
75 movl %edx,%ecx
76 andl $7,%ecx
77 jz .Lende
78 .p2align 4
79.Lloop_1:
80 movb (%rsi),%r8b
81 movb %r8b,(%rdi)
82 incq %rdi
83 incq %rsi
84 decl %ecx
85 jnz .Lloop_1
86
87.Lende:
88 popq %rbx
89 ret
90.Lfinal:
91
92 /* C stepping K8 run faster using the string copy instructions.
93 It is also a lot simpler. Use this when possible */
94
95 .section .altinstructions,"a"
96 .align 8
97 .quad memcpy
98 .quad memcpy_c
99 .byte X86_FEATURE_K8_C
100 .byte .Lfinal-memcpy
101 .byte memcpy_c_end-memcpy_c
102 .previous
103
104 .section .altinstr_replacement,"ax"
105 /* rdi destination
106 * rsi source
107 * rdx count
108 */
109memcpy_c:
110 movq %rdi,%rax 23 movq %rdi,%rax
111 movl %edx,%ecx 24 movl %edx,%ecx
112 shrl $3,%ecx 25 shrl $3,%ecx
@@ -117,5 +30,3 @@ memcpy_c:
117 rep 30 rep
118 movsb 31 movsb
119 ret 32 ret
120memcpy_c_end:
121 .previous
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
index 4b4c40638640..2aa48f24ed1e 100644
--- a/arch/x86_64/lib/memset.S
+++ b/arch/x86_64/lib/memset.S
@@ -13,98 +13,6 @@
13 .p2align 4 13 .p2align 4
14memset: 14memset:
15__memset: 15__memset:
16 movq %rdi,%r10
17 movq %rdx,%r11
18
19 /* expand byte value */
20 movzbl %sil,%ecx
21 movabs $0x0101010101010101,%rax
22 mul %rcx /* with rax, clobbers rdx */
23
24 /* align dst */
25 movl %edi,%r9d
26 andl $7,%r9d
27 jnz .Lbad_alignment
28.Lafter_bad_alignment:
29
30 movl %r11d,%ecx
31 shrl $6,%ecx
32 jz .Lhandle_tail
33
34 .p2align 4
35.Lloop_64:
36 decl %ecx
37 movq %rax,(%rdi)
38 movq %rax,8(%rdi)
39 movq %rax,16(%rdi)
40 movq %rax,24(%rdi)
41 movq %rax,32(%rdi)
42 movq %rax,40(%rdi)
43 movq %rax,48(%rdi)
44 movq %rax,56(%rdi)
45 leaq 64(%rdi),%rdi
46 jnz .Lloop_64
47
48 /* Handle tail in loops. The loops should be faster than hard
49 to predict jump tables. */
50 .p2align 4
51.Lhandle_tail:
52 movl %r11d,%ecx
53 andl $63&(~7),%ecx
54 jz .Lhandle_7
55 shrl $3,%ecx
56 .p2align 4
57.Lloop_8:
58 decl %ecx
59 movq %rax,(%rdi)
60 leaq 8(%rdi),%rdi
61 jnz .Lloop_8
62
63.Lhandle_7:
64 movl %r11d,%ecx
65 andl $7,%ecx
66 jz .Lende
67 .p2align 4
68.Lloop_1:
69 decl %ecx
70 movb %al,(%rdi)
71 leaq 1(%rdi),%rdi
72 jnz .Lloop_1
73
74.Lende:
75 movq %r10,%rax
76 ret
77
78.Lbad_alignment:
79 cmpq $7,%r11
80 jbe .Lhandle_7
81 movq %rax,(%rdi) /* unaligned store */
82 movq $8,%r8
83 subq %r9,%r8
84 addq %r8,%rdi
85 subq %r8,%r11
86 jmp .Lafter_bad_alignment
87
88 /* C stepping K8 run faster using the string instructions.
89 It is also a lot simpler. Use this when possible */
90
91#include <asm/cpufeature.h>
92
93 .section .altinstructions,"a"
94 .align 8
95 .quad memset
96 .quad memset_c
97 .byte X86_FEATURE_K8_C
98 .byte memset_c_end-memset_c
99 .byte memset_c_end-memset_c
100 .previous
101
102 .section .altinstr_replacement,"ax"
103 /* rdi destination
104 * rsi value
105 * rdx count
106 */
107memset_c:
108 movq %rdi,%r9 16 movq %rdi,%r9
109 movl %edx,%r8d 17 movl %edx,%r8d
110 andl $7,%r8d 18 andl $7,%r8d
@@ -121,5 +29,3 @@ memset_c:
121 stosb 29 stosb
122 movq %r9,%rax 30 movq %r9,%rax
123 ret 31 ret
124memset_c_end:
125 .previous
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index b75b872ec154..3a63707a698b 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -308,18 +308,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
308 unsigned long flags; 308 unsigned long flags;
309 siginfo_t info; 309 siginfo_t info;
310 310
311#ifdef CONFIG_CHECKING
312 {
313 unsigned long gs;
314 struct x8664_pda *pda = cpu_pda + stack_smp_processor_id();
315 rdmsrl(MSR_GS_BASE, gs);
316 if (gs != (unsigned long)pda) {
317 wrmsrl(MSR_GS_BASE, pda);
318 printk("page_fault: wrong gs %lx expected %p\n", gs, pda);
319 }
320 }
321#endif
322
323 /* get the address */ 311 /* get the address */
324 __asm__("movq %%cr2,%0":"=r" (address)); 312 __asm__("movq %%cr2,%0":"=r" (address));
325 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, 313 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
@@ -571,3 +559,10 @@ do_sigbus:
571 force_sig_info(SIGBUS, &info, tsk); 559 force_sig_info(SIGBUS, &info, tsk);
572 return; 560 return;
573} 561}
562
563static int __init enable_pagefaulttrace(char *str)
564{
565 page_fault_trace = 1;
566 return 0;
567}
568__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index e60a1a848de8..286f6a624c3a 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -22,6 +22,7 @@
22#include <linux/pagemap.h> 22#include <linux/pagemap.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/proc_fs.h> 24#include <linux/proc_fs.h>
25#include <linux/pci.h>
25 26
26#include <asm/processor.h> 27#include <asm/processor.h>
27#include <asm/system.h> 28#include <asm/system.h>
@@ -36,16 +37,13 @@
36#include <asm/mmu_context.h> 37#include <asm/mmu_context.h>
37#include <asm/proto.h> 38#include <asm/proto.h>
38#include <asm/smp.h> 39#include <asm/smp.h>
40#include <asm/sections.h>
39 41
40#ifndef Dprintk 42#ifndef Dprintk
41#define Dprintk(x...) 43#define Dprintk(x...)
42#endif 44#endif
43 45
44#ifdef CONFIG_GART_IOMMU 46static unsigned long dma_reserve __initdata;
45extern int swiotlb;
46#endif
47
48extern char _stext[];
49 47
50DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 48DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
51 49
@@ -86,9 +84,6 @@ void show_mem(void)
86 84
87/* References to section boundaries */ 85/* References to section boundaries */
88 86
89extern char _text, _etext, _edata, __bss_start, _end[];
90extern char __init_begin, __init_end;
91
92int after_bootmem; 87int after_bootmem;
93 88
94static void *spp_getpage(void) 89static void *spp_getpage(void)
@@ -308,42 +303,81 @@ void __init init_memory_mapping(unsigned long start, unsigned long end)
308 table_end<<PAGE_SHIFT); 303 table_end<<PAGE_SHIFT);
309} 304}
310 305
311extern struct x8664_pda cpu_pda[NR_CPUS]; 306void __cpuinit zap_low_mappings(int cpu)
307{
308 if (cpu == 0) {
309 pgd_t *pgd = pgd_offset_k(0UL);
310 pgd_clear(pgd);
311 } else {
312 /*
313 * For AP's, zap the low identity mappings by changing the cr3
314 * to init_level4_pgt and doing local flush tlb all
315 */
316 asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
317 }
318 __flush_tlb_all();
319}
312 320
313/* Assumes all CPUs still execute in init_mm */ 321/* Compute zone sizes for the DMA and DMA32 zones in a node. */
314void zap_low_mappings(void) 322__init void
323size_zones(unsigned long *z, unsigned long *h,
324 unsigned long start_pfn, unsigned long end_pfn)
315{ 325{
316 pgd_t *pgd = pgd_offset_k(0UL); 326 int i;
317 pgd_clear(pgd); 327 unsigned long w;
318 flush_tlb_all(); 328
329 for (i = 0; i < MAX_NR_ZONES; i++)
330 z[i] = 0;
331
332 if (start_pfn < MAX_DMA_PFN)
333 z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
334 if (start_pfn < MAX_DMA32_PFN) {
335 unsigned long dma32_pfn = MAX_DMA32_PFN;
336 if (dma32_pfn > end_pfn)
337 dma32_pfn = end_pfn;
338 z[ZONE_DMA32] = dma32_pfn - start_pfn;
339 }
340 z[ZONE_NORMAL] = end_pfn - start_pfn;
341
342 /* Remove lower zones from higher ones. */
343 w = 0;
344 for (i = 0; i < MAX_NR_ZONES; i++) {
345 if (z[i])
346 z[i] -= w;
347 w += z[i];
348 }
349
350 /* Compute holes */
351 w = 0;
352 for (i = 0; i < MAX_NR_ZONES; i++) {
353 unsigned long s = w;
354 w += z[i];
355 h[i] = e820_hole_size(s, w);
356 }
357
358 /* Add the space pace needed for mem_map to the holes too. */
359 for (i = 0; i < MAX_NR_ZONES; i++)
360 h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
361
362 /* The 16MB DMA zone has the kernel and other misc mappings.
363 Account them too */
364 if (h[ZONE_DMA]) {
365 h[ZONE_DMA] += dma_reserve;
366 if (h[ZONE_DMA] >= z[ZONE_DMA]) {
367 printk(KERN_WARNING
368 "Kernel too large and filling up ZONE_DMA?\n");
369 h[ZONE_DMA] = z[ZONE_DMA];
370 }
371 }
319} 372}
320 373
321#ifndef CONFIG_NUMA 374#ifndef CONFIG_NUMA
322void __init paging_init(void) 375void __init paging_init(void)
323{ 376{
324 { 377 unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES];
325 unsigned long zones_size[MAX_NR_ZONES]; 378 size_zones(zones, holes, 0, end_pfn);
326 unsigned long holes[MAX_NR_ZONES]; 379 free_area_init_node(0, NODE_DATA(0), zones,
327 unsigned int max_dma; 380 __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
328
329 memset(zones_size, 0, sizeof(zones_size));
330 memset(holes, 0, sizeof(holes));
331
332 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
333
334 if (end_pfn < max_dma) {
335 zones_size[ZONE_DMA] = end_pfn;
336 holes[ZONE_DMA] = e820_hole_size(0, end_pfn);
337 } else {
338 zones_size[ZONE_DMA] = max_dma;
339 holes[ZONE_DMA] = e820_hole_size(0, max_dma);
340 zones_size[ZONE_NORMAL] = end_pfn - max_dma;
341 holes[ZONE_NORMAL] = e820_hole_size(max_dma, end_pfn);
342 }
343 free_area_init_node(0, NODE_DATA(0), zones_size,
344 __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
345 }
346 return;
347} 381}
348#endif 382#endif
349 383
@@ -438,19 +472,16 @@ void __init mem_init(void)
438 datasize >> 10, 472 datasize >> 10,
439 initsize >> 10); 473 initsize >> 10);
440 474
475#ifdef CONFIG_SMP
441 /* 476 /*
442 * Subtle. SMP is doing its boot stuff late (because it has to 477 * Sync boot_level4_pgt mappings with the init_level4_pgt
443 * fork idle threads) - but it also needs low mappings for the 478 * except for the low identity mappings which are already zapped
444 * protected-mode entry to work. We zap these entries only after 479 * in init_level4_pgt. This sync-up is essential for AP's bringup
445 * the WP-bit has been tested.
446 */ 480 */
447#ifndef CONFIG_SMP 481 memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t));
448 zap_low_mappings();
449#endif 482#endif
450} 483}
451 484
452extern char __initdata_begin[], __initdata_end[];
453
454void free_initmem(void) 485void free_initmem(void)
455{ 486{
456 unsigned long addr; 487 unsigned long addr;
@@ -464,7 +495,7 @@ void free_initmem(void)
464 totalram_pages++; 495 totalram_pages++;
465 } 496 }
466 memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); 497 memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin);
467 printk ("Freeing unused kernel memory: %luk freed\n", (&__init_end - &__init_begin) >> 10); 498 printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
468} 499}
469 500
470#ifdef CONFIG_BLK_DEV_INITRD 501#ifdef CONFIG_BLK_DEV_INITRD
@@ -491,6 +522,8 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
491#else 522#else
492 reserve_bootmem(phys, len); 523 reserve_bootmem(phys, len);
493#endif 524#endif
525 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE)
526 dma_reserve += len / PAGE_SIZE;
494} 527}
495 528
496int kern_addr_valid(unsigned long addr) 529int kern_addr_valid(unsigned long addr)
@@ -532,10 +565,6 @@ extern int exception_trace, page_fault_trace;
532static ctl_table debug_table2[] = { 565static ctl_table debug_table2[] = {
533 { 99, "exception-trace", &exception_trace, sizeof(int), 0644, NULL, 566 { 99, "exception-trace", &exception_trace, sizeof(int), 0644, NULL,
534 proc_dointvec }, 567 proc_dointvec },
535#ifdef CONFIG_CHECKING
536 { 100, "page-fault-trace", &page_fault_trace, sizeof(int), 0644, NULL,
537 proc_dointvec },
538#endif
539 { 0, } 568 { 0, }
540}; 569};
541 570
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index 65417b040c1b..a5663e0bb01c 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -108,6 +108,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
108 limit >>= 16; 108 limit >>= 16;
109 limit <<= 24; 109 limit <<= 24;
110 limit |= (1<<24)-1; 110 limit |= (1<<24)-1;
111 limit++;
111 112
112 if (limit > end_pfn << PAGE_SHIFT) 113 if (limit > end_pfn << PAGE_SHIFT)
113 limit = end_pfn << PAGE_SHIFT; 114 limit = end_pfn << PAGE_SHIFT;
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 214803821001..a828a01739cc 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -38,38 +38,57 @@ cpumask_t node_to_cpumask[MAX_NUMNODES] __read_mostly;
38 38
39int numa_off __initdata; 39int numa_off __initdata;
40 40
41int __init compute_hash_shift(struct node *nodes, int numnodes) 41
42/*
43 * Given a shift value, try to populate memnodemap[]
44 * Returns :
45 * 1 if OK
46 * 0 if memnodmap[] too small (of shift too small)
47 * -1 if node overlap or lost ram (shift too big)
48 */
49static int __init populate_memnodemap(
50 const struct node *nodes, int numnodes, int shift)
42{ 51{
43 int i; 52 int i;
44 int shift = 20; 53 int res = -1;
45 unsigned long addr,maxend=0; 54 unsigned long addr, end;
46
47 for (i = 0; i < numnodes; i++)
48 if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend))
49 maxend = nodes[i].end;
50 55
51 while ((1UL << shift) < (maxend / NODEMAPSIZE)) 56 memset(memnodemap, 0xff, sizeof(memnodemap));
52 shift++;
53
54 printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n",
55 shift,maxend);
56 memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE);
57 for (i = 0; i < numnodes; i++) { 57 for (i = 0; i < numnodes; i++) {
58 if (nodes[i].start == nodes[i].end) 58 addr = nodes[i].start;
59 end = nodes[i].end;
60 if (addr >= end)
59 continue; 61 continue;
60 for (addr = nodes[i].start; 62 if ((end >> shift) >= NODEMAPSIZE)
61 addr < nodes[i].end; 63 return 0;
62 addr += (1UL << shift)) { 64 do {
63 if (memnodemap[addr >> shift] != 0xff) { 65 if (memnodemap[addr >> shift] != 0xff)
64 printk(KERN_INFO
65 "Your memory is not aligned you need to rebuild your kernel "
66 "with a bigger NODEMAPSIZE shift=%d adder=%lu\n",
67 shift,addr);
68 return -1; 66 return -1;
69 }
70 memnodemap[addr >> shift] = i; 67 memnodemap[addr >> shift] = i;
71 } 68 addr += (1 << shift);
69 } while (addr < end);
70 res = 1;
72 } 71 }
72 return res;
73}
74
75int __init compute_hash_shift(struct node *nodes, int numnodes)
76{
77 int shift = 20;
78
79 while (populate_memnodemap(nodes, numnodes, shift + 1) >= 0)
80 shift++;
81
82 printk(KERN_DEBUG "Using %d for the hash shift.\n",
83 shift);
84
85 if (populate_memnodemap(nodes, numnodes, shift) != 1) {
86 printk(KERN_INFO
87 "Your memory is not aligned you need to rebuild your kernel "
88 "with a bigger NODEMAPSIZE shift=%d\n",
89 shift);
90 return -1;
91 }
73 return shift; 92 return shift;
74} 93}
75 94
@@ -94,7 +113,6 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
94 start_pfn = start >> PAGE_SHIFT; 113 start_pfn = start >> PAGE_SHIFT;
95 end_pfn = end >> PAGE_SHIFT; 114 end_pfn = end >> PAGE_SHIFT;
96 115
97 memory_present(nodeid, start_pfn, end_pfn);
98 nodedata_phys = find_e820_area(start, end, pgdat_size); 116 nodedata_phys = find_e820_area(start, end, pgdat_size);
99 if (nodedata_phys == -1L) 117 if (nodedata_phys == -1L)
100 panic("Cannot find memory pgdat in node %d\n", nodeid); 118 panic("Cannot find memory pgdat in node %d\n", nodeid);
@@ -132,29 +150,14 @@ void __init setup_node_zones(int nodeid)
132 unsigned long start_pfn, end_pfn; 150 unsigned long start_pfn, end_pfn;
133 unsigned long zones[MAX_NR_ZONES]; 151 unsigned long zones[MAX_NR_ZONES];
134 unsigned long holes[MAX_NR_ZONES]; 152 unsigned long holes[MAX_NR_ZONES];
135 unsigned long dma_end_pfn;
136 153
137 memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 154 start_pfn = node_start_pfn(nodeid);
138 memset(holes, 0, sizeof(unsigned long) * MAX_NR_ZONES); 155 end_pfn = node_end_pfn(nodeid);
139 156
140 start_pfn = node_start_pfn(nodeid); 157 Dprintk(KERN_INFO "setting up node %d %lx-%lx\n",
141 end_pfn = node_end_pfn(nodeid); 158 nodeid, start_pfn, end_pfn);
142 159
143 Dprintk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 160 size_zones(zones, holes, start_pfn, end_pfn);
144
145 /* All nodes > 0 have a zero length zone DMA */
146 dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT;
147 if (start_pfn < dma_end_pfn) {
148 zones[ZONE_DMA] = dma_end_pfn - start_pfn;
149 holes[ZONE_DMA] = e820_hole_size(start_pfn, dma_end_pfn);
150 zones[ZONE_NORMAL] = end_pfn - dma_end_pfn;
151 holes[ZONE_NORMAL] = e820_hole_size(dma_end_pfn, end_pfn);
152
153 } else {
154 zones[ZONE_NORMAL] = end_pfn - start_pfn;
155 holes[ZONE_NORMAL] = e820_hole_size(start_pfn, end_pfn);
156 }
157
158 free_area_init_node(nodeid, NODE_DATA(nodeid), zones, 161 free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
159 start_pfn, holes); 162 start_pfn, holes);
160} 163}
@@ -171,7 +174,7 @@ void __init numa_init_array(void)
171 for (i = 0; i < NR_CPUS; i++) { 174 for (i = 0; i < NR_CPUS; i++) {
172 if (cpu_to_node[i] != NUMA_NO_NODE) 175 if (cpu_to_node[i] != NUMA_NO_NODE)
173 continue; 176 continue;
174 cpu_to_node[i] = rr; 177 numa_set_node(i, rr);
175 rr = next_node(rr, node_online_map); 178 rr = next_node(rr, node_online_map);
176 if (rr == MAX_NUMNODES) 179 if (rr == MAX_NUMNODES)
177 rr = first_node(node_online_map); 180 rr = first_node(node_online_map);
@@ -205,8 +208,6 @@ static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
205 if (i == numa_fake-1) 208 if (i == numa_fake-1)
206 sz = (end_pfn<<PAGE_SHIFT) - nodes[i].start; 209 sz = (end_pfn<<PAGE_SHIFT) - nodes[i].start;
207 nodes[i].end = nodes[i].start + sz; 210 nodes[i].end = nodes[i].start + sz;
208 if (i != numa_fake-1)
209 nodes[i].end--;
210 printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", 211 printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n",
211 i, 212 i,
212 nodes[i].start, nodes[i].end, 213 nodes[i].start, nodes[i].end,
@@ -257,7 +258,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
257 nodes_clear(node_online_map); 258 nodes_clear(node_online_map);
258 node_set_online(0); 259 node_set_online(0);
259 for (i = 0; i < NR_CPUS; i++) 260 for (i = 0; i < NR_CPUS; i++)
260 cpu_to_node[i] = 0; 261 numa_set_node(i, 0);
261 node_to_cpumask[0] = cpumask_of_cpu(0); 262 node_to_cpumask[0] = cpumask_of_cpu(0);
262 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); 263 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
263} 264}
@@ -267,6 +268,12 @@ __cpuinit void numa_add_cpu(int cpu)
267 set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]); 268 set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
268} 269}
269 270
271void __cpuinit numa_set_node(int cpu, int node)
272{
273 cpu_pda[cpu].nodenumber = node;
274 cpu_to_node[cpu] = node;
275}
276
270unsigned long __init numa_free_all_bootmem(void) 277unsigned long __init numa_free_all_bootmem(void)
271{ 278{
272 int i; 279 int i;
@@ -277,9 +284,26 @@ unsigned long __init numa_free_all_bootmem(void)
277 return pages; 284 return pages;
278} 285}
279 286
287#ifdef CONFIG_SPARSEMEM
288static void __init arch_sparse_init(void)
289{
290 int i;
291
292 for_each_online_node(i)
293 memory_present(i, node_start_pfn(i), node_end_pfn(i));
294
295 sparse_init();
296}
297#else
298#define arch_sparse_init() do {} while (0)
299#endif
300
280void __init paging_init(void) 301void __init paging_init(void)
281{ 302{
282 int i; 303 int i;
304
305 arch_sparse_init();
306
283 for_each_online_node(i) { 307 for_each_online_node(i) {
284 setup_node_zones(i); 308 setup_node_zones(i);
285 } 309 }
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 4b2e844c15a7..33340bd1e328 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -71,8 +71,6 @@ static __init void cutoff_node(int i, unsigned long start, unsigned long end)
71 nd->start = nd->end; 71 nd->start = nd->end;
72 } 72 }
73 if (nd->end > end) { 73 if (nd->end > end) {
74 if (!(end & 0xfff))
75 end--;
76 nd->end = end; 74 nd->end = end;
77 if (nd->start > nd->end) 75 if (nd->start > nd->end)
78 nd->start = nd->end; 76 nd->start = nd->end;
@@ -166,8 +164,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
166 if (nd->end < end) 164 if (nd->end < end)
167 nd->end = end; 165 nd->end = end;
168 } 166 }
169 if (!(nd->end & 0xfff))
170 nd->end--;
171 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, 167 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
172 nd->start, nd->end); 168 nd->start, nd->end);
173} 169}
@@ -203,7 +199,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
203 if (cpu_to_node[i] == NUMA_NO_NODE) 199 if (cpu_to_node[i] == NUMA_NO_NODE)
204 continue; 200 continue;
205 if (!node_isset(cpu_to_node[i], nodes_parsed)) 201 if (!node_isset(cpu_to_node[i], nodes_parsed))
206 cpu_to_node[i] = NUMA_NO_NODE; 202 numa_set_node(i, NUMA_NO_NODE);
207 } 203 }
208 numa_init_array(); 204 numa_init_array();
209 return 0; 205 return 0;