aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
commitf541ae326fa120fa5c57433e4d9a133df212ce41 (patch)
treebdbd94ec72cfc601118051cb35e8617d55510177 /arch/powerpc/kernel
parente255357764f92afcafafbd4879b222b8c752065a (diff)
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream Conflicts: arch/powerpc/kernel/Makefile arch/x86/ia32/ia32entry.S arch/x86/include/asm/hardirq.h arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h arch/x86/kernel/cpu/common.c arch/x86/kernel/irq.c arch/x86/kernel/syscall_table_32.S arch/x86/mm/iomap_32.c include/linux/sched.h kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile12
-rw-r--r--arch/powerpc/kernel/align.c2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c7
-rw-r--r--arch/powerpc/kernel/cpu_setup_44x.S1
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S5
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S31
-rw-r--r--arch/powerpc/kernel/cputable.c166
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/dbell.c44
-rw-r--r--arch/powerpc/kernel/entry_32.S129
-rw-r--r--arch/powerpc/kernel/entry_64.S89
-rw-r--r--arch/powerpc/kernel/ftrace.c218
-rw-r--r--arch/powerpc/kernel/head_32.S116
-rw-r--r--arch/powerpc/kernel/head_64.S6
-rw-r--r--arch/powerpc/kernel/head_booke.h19
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S101
-rw-r--r--arch/powerpc/kernel/irq.c6
-rw-r--r--arch/powerpc/kernel/module_64.c2
-rw-r--r--arch/powerpc/kernel/msi.c5
-rw-r--r--arch/powerpc/kernel/pci-common.c45
-rw-r--r--arch/powerpc/kernel/pci_32.c36
-rw-r--r--arch/powerpc/kernel/pci_64.c19
-rw-r--r--arch/powerpc/kernel/process.c60
-rw-r--r--arch/powerpc/kernel/prom.c6
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh2
-rw-r--r--arch/powerpc/kernel/rtas.c10
-rw-r--r--arch/powerpc/kernel/rtas_flash.c1
-rw-r--r--arch/powerpc/kernel/setup-common.c36
-rw-r--r--arch/powerpc/kernel/setup_64.c42
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/signal.h12
-rw-r--r--arch/powerpc/kernel/signal_32.c4
-rw-r--r--arch/powerpc/kernel/signal_64.c2
-rw-r--r--arch/powerpc/kernel/sysfs.c35
-rw-r--r--arch/powerpc/kernel/time.c16
-rw-r--r--arch/powerpc/kernel/traps.c79
-rw-r--r--arch/powerpc/kernel/udbg.c7
-rw-r--r--arch/powerpc/kernel/udbg_16550.c60
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S10
41 files changed, 958 insertions, 493 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8e5e2c74971e..9ba1bb731fcc 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -18,12 +18,10 @@ CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
18CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog 18CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
19CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog 19CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
20CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog 20CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
21 21# do not trace tracer code
22ifdef CONFIG_DYNAMIC_FTRACE
23# dynamic ftrace setup.
24CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog 22CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
25endif 23# timers used by tracing
26 24CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog
27endif 25endif
28 26
29obj-y := cputable.o ptrace.o syscalls.o \ 27obj-y := cputable.o ptrace.o syscalls.o \
@@ -61,6 +59,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \
61obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o 59obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o
62obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o 60obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o
63obj-$(CONFIG_44x) += cpu_setup_44x.o 61obj-$(CONFIG_44x) += cpu_setup_44x.o
62obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o
64 63
65extra-$(CONFIG_PPC_STD_MMU) := head_32.o 64extra-$(CONFIG_PPC_STD_MMU) := head_32.o
66extra-$(CONFIG_PPC64) := head_64.o 65extra-$(CONFIG_PPC64) := head_64.o
@@ -76,7 +75,7 @@ obj-y += time.o prom.o traps.o setup-common.o \
76obj-$(CONFIG_PPC32) += entry_32.o setup_32.o 75obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
77obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o 76obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
78obj-$(CONFIG_KGDB) += kgdb.o 77obj-$(CONFIG_KGDB) += kgdb.o
79obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 78obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
80obj-$(CONFIG_MODULES) += ppc_ksyms.o 79obj-$(CONFIG_MODULES) += ppc_ksyms.o
81obj-$(CONFIG_BOOTX_TEXT) += btext.o 80obj-$(CONFIG_BOOTX_TEXT) += btext.o
82obj-$(CONFIG_SMP) += smp.o 81obj-$(CONFIG_SMP) += smp.o
@@ -94,6 +93,7 @@ obj-$(CONFIG_AUDIT) += audit.o
94obj64-$(CONFIG_AUDIT) += compat_audit.o 93obj64-$(CONFIG_AUDIT) += compat_audit.o
95 94
96obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 95obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
96obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
97obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o power4-pmu.o ppc970-pmu.o \ 97obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o power4-pmu.o ppc970-pmu.o \
98 power5-pmu.o power5+-pmu.o power6-pmu.o 98 power5-pmu.o power5+-pmu.o power6-pmu.o
99 99
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 73cb6a3229ae..5ffcfaa77d6a 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -187,7 +187,7 @@ static struct aligninfo aligninfo[128] = {
187 { 4, ST+F+S+U }, /* 11 1 1010: stfsux */ 187 { 4, ST+F+S+U }, /* 11 1 1010: stfsux */
188 { 8, ST+F+U }, /* 11 1 1011: stfdux */ 188 { 8, ST+F+U }, /* 11 1 1011: stfdux */
189 INVALID, /* 11 1 1100 */ 189 INVALID, /* 11 1 1100 */
190 INVALID, /* 11 1 1101 */ 190 { 4, LD+F }, /* 11 1 1101: lfiwzx */
191 INVALID, /* 11 1 1110 */ 191 INVALID, /* 11 1 1110 */
192 INVALID, /* 11 1 1111 */ 192 INVALID, /* 11 1 1111 */
193}; 193};
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 3734973f7394..e981d1ce1914 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -49,7 +49,7 @@
49#include <asm/iseries/alpaca.h> 49#include <asm/iseries/alpaca.h>
50#endif 50#endif
51#ifdef CONFIG_KVM 51#ifdef CONFIG_KVM
52#include <asm/kvm_44x.h> 52#include <linux/kvm_host.h>
53#endif 53#endif
54 54
55#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) 55#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
@@ -285,9 +285,6 @@ int main(void)
285#endif /* ! CONFIG_PPC64 */ 285#endif /* ! CONFIG_PPC64 */
286 286
287 /* About the CPU features table */ 287 /* About the CPU features table */
288 DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
289 DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
290 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
291 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); 288 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
292 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 289 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
293 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); 290 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
@@ -362,8 +359,6 @@ int main(void)
362 DEFINE(PTE_SIZE, sizeof(pte_t)); 359 DEFINE(PTE_SIZE, sizeof(pte_t));
363 360
364#ifdef CONFIG_KVM 361#ifdef CONFIG_KVM
365 DEFINE(TLBE_BYTES, sizeof(struct kvmppc_44x_tlbe));
366
367 DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); 362 DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
368 DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); 363 DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
369 DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); 364 DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S
index 10b4ab1008af..7d606f89a839 100644
--- a/arch/powerpc/kernel/cpu_setup_44x.S
+++ b/arch/powerpc/kernel/cpu_setup_44x.S
@@ -34,6 +34,7 @@ _GLOBAL(__setup_cpu_440grx)
34 blr 34 blr
35_GLOBAL(__setup_cpu_460ex) 35_GLOBAL(__setup_cpu_460ex)
36_GLOBAL(__setup_cpu_460gt) 36_GLOBAL(__setup_cpu_460gt)
37_GLOBAL(__setup_cpu_460sx)
37 mflr r4 38 mflr r4
38 bl __init_fpu_44x 39 bl __init_fpu_44x
39 bl __fixup_440A_mcheck 40 bl __fixup_440A_mcheck
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 72d1d7395254..54f767e31a1a 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -15,9 +15,14 @@
15#include <asm/ppc_asm.h> 15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18#include <asm/mmu.h>
18 19
19_GLOBAL(__setup_cpu_603) 20_GLOBAL(__setup_cpu_603)
20 mflr r4 21 mflr r4
22BEGIN_MMU_FTR_SECTION
23 li r10,0
24 mtspr SPRN_SPRG4,r10 /* init SW LRU tracking */
25END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
21BEGIN_FTR_SECTION 26BEGIN_FTR_SECTION
22 bl __init_fpu_registers 27 bl __init_fpu_registers
23END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) 28END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
new file mode 100644
index 000000000000..eb4b9adcedb4
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -0,0 +1,31 @@
1/*
2 * This file contains low level CPU setup functions.
3 * Kumar Gala <galak@kernel.crashing.org>
4 * Copyright 2009 Freescale Semiconductor, Inc.
5 *
6 * Based on cpu_setup_6xx code by
7 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 *
14 */
15
16#include <asm/processor.h>
17#include <asm/cputable.h>
18#include <asm/ppc_asm.h>
19
20_GLOBAL(__setup_cpu_e200)
21 /* enable dedicated debug exception handling resources (Debug APU) */
22 mfspr r3,SPRN_HID0
23 ori r3,r3,HID0_DAPUEN@l
24 mtspr SPRN_HID0,r3
25 b __setup_e200_ivors
26_GLOBAL(__setup_cpu_e500v1)
27_GLOBAL(__setup_cpu_e500v2)
28 b __setup_e500_ivors
29_GLOBAL(__setup_cpu_e500mc)
30 b __setup_e500mc_ivors
31
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 923f87aff20a..cd1b687544f3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -35,6 +35,10 @@ const char *powerpc_base_platform;
35 * and ppc64 35 * and ppc64
36 */ 36 */
37#ifdef CONFIG_PPC32 37#ifdef CONFIG_PPC32
38extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec);
41extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec);
38extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); 42extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); 43extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec); 44extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
@@ -43,6 +47,7 @@ extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
43extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec); 47extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec);
44extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec); 48extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
45extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec); 49extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
50extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec);
46extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); 51extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
47extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); 52extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
48extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); 53extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -726,6 +731,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
726 .cpu_setup = __setup_cpu_750, 731 .cpu_setup = __setup_cpu_750,
727 .machine_check = machine_check_generic, 732 .machine_check = machine_check_generic,
728 .platform = "ppc750", 733 .platform = "ppc750",
734 .oprofile_cpu_type = "ppc/750",
735 .oprofile_type = PPC_OPROFILE_G4,
729 }, 736 },
730 { /* 750FX rev 2.0 must disable HID0[DPM] */ 737 { /* 750FX rev 2.0 must disable HID0[DPM] */
731 .pvr_mask = 0xffffffff, 738 .pvr_mask = 0xffffffff,
@@ -741,6 +748,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
741 .cpu_setup = __setup_cpu_750, 748 .cpu_setup = __setup_cpu_750,
742 .machine_check = machine_check_generic, 749 .machine_check = machine_check_generic,
743 .platform = "ppc750", 750 .platform = "ppc750",
751 .oprofile_cpu_type = "ppc/750",
752 .oprofile_type = PPC_OPROFILE_G4,
744 }, 753 },
745 { /* 750FX (All revs except 2.0) */ 754 { /* 750FX (All revs except 2.0) */
746 .pvr_mask = 0xffff0000, 755 .pvr_mask = 0xffff0000,
@@ -756,6 +765,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
756 .cpu_setup = __setup_cpu_750fx, 765 .cpu_setup = __setup_cpu_750fx,
757 .machine_check = machine_check_generic, 766 .machine_check = machine_check_generic,
758 .platform = "ppc750", 767 .platform = "ppc750",
768 .oprofile_cpu_type = "ppc/750",
769 .oprofile_type = PPC_OPROFILE_G4,
759 }, 770 },
760 { /* 750GX */ 771 { /* 750GX */
761 .pvr_mask = 0xffff0000, 772 .pvr_mask = 0xffff0000,
@@ -771,6 +782,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
771 .cpu_setup = __setup_cpu_750fx, 782 .cpu_setup = __setup_cpu_750fx,
772 .machine_check = machine_check_generic, 783 .machine_check = machine_check_generic,
773 .platform = "ppc750", 784 .platform = "ppc750",
785 .oprofile_cpu_type = "ppc/750",
786 .oprofile_type = PPC_OPROFILE_G4,
774 }, 787 },
775 { /* 740/750 (L2CR bit need fixup for 740) */ 788 { /* 740/750 (L2CR bit need fixup for 740) */
776 .pvr_mask = 0xffff0000, 789 .pvr_mask = 0xffff0000,
@@ -1077,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1077 .cpu_name = "e300c2", 1090 .cpu_name = "e300c2",
1078 .cpu_features = CPU_FTRS_E300C2, 1091 .cpu_features = CPU_FTRS_E300C2,
1079 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1092 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
1080 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1093 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1094 MMU_FTR_NEED_DTLB_SW_LRU,
1081 .icache_bsize = 32, 1095 .icache_bsize = 32,
1082 .dcache_bsize = 32, 1096 .dcache_bsize = 32,
1083 .cpu_setup = __setup_cpu_603, 1097 .cpu_setup = __setup_cpu_603,
@@ -1090,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1090 .cpu_name = "e300c3", 1104 .cpu_name = "e300c3",
1091 .cpu_features = CPU_FTRS_E300, 1105 .cpu_features = CPU_FTRS_E300,
1092 .cpu_user_features = COMMON_USER, 1106 .cpu_user_features = COMMON_USER,
1093 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1107 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1108 MMU_FTR_NEED_DTLB_SW_LRU,
1094 .icache_bsize = 32, 1109 .icache_bsize = 32,
1095 .dcache_bsize = 32, 1110 .dcache_bsize = 32,
1096 .cpu_setup = __setup_cpu_603, 1111 .cpu_setup = __setup_cpu_603,
@@ -1105,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1105 .cpu_name = "e300c4", 1120 .cpu_name = "e300c4",
1106 .cpu_features = CPU_FTRS_E300, 1121 .cpu_features = CPU_FTRS_E300,
1107 .cpu_user_features = COMMON_USER, 1122 .cpu_user_features = COMMON_USER,
1108 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1123 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1124 MMU_FTR_NEED_DTLB_SW_LRU,
1109 .icache_bsize = 32, 1125 .icache_bsize = 32,
1110 .dcache_bsize = 32, 1126 .dcache_bsize = 32,
1111 .cpu_setup = __setup_cpu_603, 1127 .cpu_setup = __setup_cpu_603,
@@ -1634,6 +1650,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
1634 .machine_check = machine_check_440A, 1650 .machine_check = machine_check_440A,
1635 .platform = "ppc440", 1651 .platform = "ppc440",
1636 }, 1652 },
1653 { /* 460SX */
1654 .pvr_mask = 0xffffff00,
1655 .pvr_value = 0x13541800,
1656 .cpu_name = "460SX",
1657 .cpu_features = CPU_FTRS_44X,
1658 .cpu_user_features = COMMON_USER_BOOKE,
1659 .mmu_features = MMU_FTR_TYPE_44x,
1660 .icache_bsize = 32,
1661 .dcache_bsize = 32,
1662 .cpu_setup = __setup_cpu_460sx,
1663 .machine_check = machine_check_440A,
1664 .platform = "ppc440",
1665 },
1637 { /* default match */ 1666 { /* default match */
1638 .pvr_mask = 0x00000000, 1667 .pvr_mask = 0x00000000,
1639 .pvr_value = 0x00000000, 1668 .pvr_value = 0x00000000,
@@ -1687,6 +1716,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1687 PPC_FEATURE_UNIFIED_CACHE, 1716 PPC_FEATURE_UNIFIED_CACHE,
1688 .mmu_features = MMU_FTR_TYPE_FSL_E, 1717 .mmu_features = MMU_FTR_TYPE_FSL_E,
1689 .dcache_bsize = 32, 1718 .dcache_bsize = 32,
1719 .cpu_setup = __setup_cpu_e200,
1690 .machine_check = machine_check_e200, 1720 .machine_check = machine_check_e200,
1691 .platform = "ppc5554", 1721 .platform = "ppc5554",
1692 } 1722 }
@@ -1706,6 +1736,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1706 .num_pmcs = 4, 1736 .num_pmcs = 4,
1707 .oprofile_cpu_type = "ppc/e500", 1737 .oprofile_cpu_type = "ppc/e500",
1708 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1738 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1739 .cpu_setup = __setup_cpu_e500v1,
1709 .machine_check = machine_check_e500, 1740 .machine_check = machine_check_e500,
1710 .platform = "ppc8540", 1741 .platform = "ppc8540",
1711 }, 1742 },
@@ -1724,6 +1755,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1724 .num_pmcs = 4, 1755 .num_pmcs = 4,
1725 .oprofile_cpu_type = "ppc/e500", 1756 .oprofile_cpu_type = "ppc/e500",
1726 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1757 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1758 .cpu_setup = __setup_cpu_e500v2,
1727 .machine_check = machine_check_e500, 1759 .machine_check = machine_check_e500,
1728 .platform = "ppc8548", 1760 .platform = "ppc8548",
1729 }, 1761 },
@@ -1733,12 +1765,14 @@ static struct cpu_spec __initdata cpu_specs[] = {
1733 .cpu_name = "e500mc", 1765 .cpu_name = "e500mc",
1734 .cpu_features = CPU_FTRS_E500MC, 1766 .cpu_features = CPU_FTRS_E500MC,
1735 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1767 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1736 .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS, 1768 .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
1769 MMU_FTR_USE_TLBILX,
1737 .icache_bsize = 64, 1770 .icache_bsize = 64,
1738 .dcache_bsize = 64, 1771 .dcache_bsize = 64,
1739 .num_pmcs = 4, 1772 .num_pmcs = 4,
1740 .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */ 1773 .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */
1741 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1774 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1775 .cpu_setup = __setup_cpu_e500mc,
1742 .machine_check = machine_check_e500, 1776 .machine_check = machine_check_e500,
1743 .platform = "ppce500mc", 1777 .platform = "ppce500mc",
1744 }, 1778 },
@@ -1762,74 +1796,84 @@ static struct cpu_spec __initdata cpu_specs[] = {
1762 1796
1763static struct cpu_spec the_cpu_spec; 1797static struct cpu_spec the_cpu_spec;
1764 1798
1765struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) 1799static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s)
1766{ 1800{
1767 struct cpu_spec *s = cpu_specs;
1768 struct cpu_spec *t = &the_cpu_spec; 1801 struct cpu_spec *t = &the_cpu_spec;
1769 int i; 1802 struct cpu_spec old;
1770 1803
1771 s = PTRRELOC(s);
1772 t = PTRRELOC(t); 1804 t = PTRRELOC(t);
1805 old = *t;
1773 1806
1774 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) 1807 /* Copy everything, then do fixups */
1775 if ((pvr & s->pvr_mask) == s->pvr_value) { 1808 *t = *s;
1776 /* 1809
1777 * If we are overriding a previous value derived 1810 /*
1778 * from the real PVR with a new value obtained 1811 * If we are overriding a previous value derived from the real
1779 * using a logical PVR value, don't modify the 1812 * PVR with a new value obtained using a logical PVR value,
1780 * performance monitor fields. 1813 * don't modify the performance monitor fields.
1781 */ 1814 */
1782 if (t->num_pmcs && !s->num_pmcs) { 1815 if (old.num_pmcs && !s->num_pmcs) {
1783 t->cpu_name = s->cpu_name; 1816 t->num_pmcs = old.num_pmcs;
1784 t->cpu_features = s->cpu_features; 1817 t->pmc_type = old.pmc_type;
1785 t->cpu_user_features = s->cpu_user_features; 1818 t->oprofile_type = old.oprofile_type;
1786 t->icache_bsize = s->icache_bsize; 1819 t->oprofile_mmcra_sihv = old.oprofile_mmcra_sihv;
1787 t->dcache_bsize = s->dcache_bsize; 1820 t->oprofile_mmcra_sipr = old.oprofile_mmcra_sipr;
1788 t->cpu_setup = s->cpu_setup; 1821 t->oprofile_mmcra_clear = old.oprofile_mmcra_clear;
1789 t->cpu_restore = s->cpu_restore; 1822
1790 t->platform = s->platform; 1823 /*
1791 /* 1824 * If we have passed through this logic once before and
1792 * If we have passed through this logic once 1825 * have pulled the default case because the real PVR was
1793 * before and have pulled the default case 1826 * not found inside cpu_specs[], then we are possibly
1794 * because the real PVR was not found inside 1827 * running in compatibility mode. In that case, let the
1795 * cpu_specs[], then we are possibly running in 1828 * oprofiler know which set of compatibility counters to
1796 * compatibility mode. In that case, let the 1829 * pull from by making sure the oprofile_cpu_type string
1797 * oprofiler know which set of compatibility 1830 * is set to that of compatibility mode. If the
1798 * counters to pull from by making sure the 1831 * oprofile_cpu_type already has a value, then we are
1799 * oprofile_cpu_type string is set to that of 1832 * possibly overriding a real PVR with a logical one,
1800 * compatibility mode. If the oprofile_cpu_type 1833 * and, in that case, keep the current value for
1801 * already has a value, then we are possibly 1834 * oprofile_cpu_type.
1802 * overriding a real PVR with a logical one, and, 1835 */
1803 * in that case, keep the current value for 1836 if (old.oprofile_cpu_type == NULL)
1804 * oprofile_cpu_type. 1837 t->oprofile_cpu_type = s->oprofile_cpu_type;
1805 */ 1838 }
1806 if (t->oprofile_cpu_type == NULL)
1807 t->oprofile_cpu_type = s->oprofile_cpu_type;
1808 } else
1809 *t = *s;
1810 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
1811 1839
1812 /* 1840 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
1813 * Set the base platform string once; assumes 1841
1814 * we're called with real pvr first. 1842 /*
1815 */ 1843 * Set the base platform string once; assumes
1816 if (*PTRRELOC(&powerpc_base_platform) == NULL) 1844 * we're called with real pvr first.
1817 *PTRRELOC(&powerpc_base_platform) = t->platform; 1845 */
1846 if (*PTRRELOC(&powerpc_base_platform) == NULL)
1847 *PTRRELOC(&powerpc_base_platform) = t->platform;
1818 1848
1819#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) 1849#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
1820 /* ppc64 and booke expect identify_cpu to also call 1850 /* ppc64 and booke expect identify_cpu to also call setup_cpu for
1821 * setup_cpu for that processor. I will consolidate 1851 * that processor. I will consolidate that at a later time, for now,
1822 * that at a later time, for now, just use #ifdef. 1852 * just use #ifdef. We also don't need to PTRRELOC the function
1823 * we also don't need to PTRRELOC the function pointer 1853 * pointer on ppc64 and booke as we are running at 0 in real mode
1824 * on ppc64 and booke as we are running at 0 in real 1854 * on ppc64 and reloc_offset is always 0 on booke.
1825 * mode on ppc64 and reloc_offset is always 0 on booke. 1855 */
1826 */ 1856 if (s->cpu_setup) {
1827 if (s->cpu_setup) { 1857 s->cpu_setup(offset, s);
1828 s->cpu_setup(offset, s); 1858 }
1829 }
1830#endif /* CONFIG_PPC64 || CONFIG_BOOKE */ 1859#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
1860}
1861
1862struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
1863{
1864 struct cpu_spec *s = cpu_specs;
1865 int i;
1866
1867 s = PTRRELOC(s);
1868
1869 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
1870 if ((pvr & s->pvr_mask) == s->pvr_value) {
1871 setup_cpu_spec(offset, s);
1831 return s; 1872 return s;
1832 } 1873 }
1874 }
1875
1833 BUG(); 1876 BUG();
1877
1834 return NULL; 1878 return NULL;
1835} 1879}
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 19671aca6591..5fb667a60894 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -48,7 +48,7 @@ static void __init create_trampoline(unsigned long addr)
48 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires 48 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires
49 * two instructions it doesn't require any registers. 49 * two instructions it doesn't require any registers.
50 */ 50 */
51 patch_instruction(p, PPC_NOP_INSTR); 51 patch_instruction(p, PPC_INST_NOP);
52 patch_branch(++p, addr + PHYSICAL_START, 0); 52 patch_branch(++p, addr + PHYSICAL_START, 0);
53} 53}
54 54
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
new file mode 100644
index 000000000000..1493734cd871
--- /dev/null
+++ b/arch/powerpc/kernel/dbell.c
@@ -0,0 +1,44 @@
1/*
2 * Author: Kumar Gala <galak@kernel.crashing.org>
3 *
4 * Copyright 2009 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/stddef.h>
13#include <linux/kernel.h>
14#include <linux/smp.h>
15#include <linux/threads.h>
16
17#include <asm/dbell.h>
18
19#ifdef CONFIG_SMP
20unsigned long dbell_smp_message[NR_CPUS];
21
22void smp_dbell_message_pass(int target, int msg)
23{
24 int i;
25
26 if(target < NR_CPUS) {
27 set_bit(msg, &dbell_smp_message[target]);
28 ppc_msgsnd(PPC_DBELL, 0, target);
29 }
30 else if(target == MSG_ALL_BUT_SELF) {
31 for_each_online_cpu(i) {
32 if (i == smp_processor_id())
33 continue;
34 set_bit(msg, &dbell_smp_message[i]);
35 ppc_msgsnd(PPC_DBELL, 0, i);
36 }
37 }
38 else { /* target == MSG_ALL */
39 for_each_online_cpu(i)
40 set_bit(msg, &dbell_smp_message[i]);
41 ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0);
42 }
43}
44#endif
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 6f7eb7e00c79..4dd38f129153 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -63,7 +63,7 @@ debug_transfer_to_handler:
63 63
64 .globl crit_transfer_to_handler 64 .globl crit_transfer_to_handler
65crit_transfer_to_handler: 65crit_transfer_to_handler:
66#ifdef CONFIG_FSL_BOOKE 66#ifdef CONFIG_PPC_BOOK3E_MMU
67 mfspr r0,SPRN_MAS0 67 mfspr r0,SPRN_MAS0
68 stw r0,MAS0(r11) 68 stw r0,MAS0(r11)
69 mfspr r0,SPRN_MAS1 69 mfspr r0,SPRN_MAS1
@@ -78,7 +78,7 @@ crit_transfer_to_handler:
78 mfspr r0,SPRN_MAS7 78 mfspr r0,SPRN_MAS7
79 stw r0,MAS7(r11) 79 stw r0,MAS7(r11)
80#endif /* CONFIG_PHYS_64BIT */ 80#endif /* CONFIG_PHYS_64BIT */
81#endif /* CONFIG_FSL_BOOKE */ 81#endif /* CONFIG_PPC_BOOK3E_MMU */
82#ifdef CONFIG_44x 82#ifdef CONFIG_44x
83 mfspr r0,SPRN_MMUCR 83 mfspr r0,SPRN_MMUCR
84 stw r0,MMUCR(r11) 84 stw r0,MMUCR(r11)
@@ -914,7 +914,7 @@ exc_exit_restart_end:
914 mtspr SPRN_##exc_lvl_srr0,r9; \ 914 mtspr SPRN_##exc_lvl_srr0,r9; \
915 mtspr SPRN_##exc_lvl_srr1,r10; 915 mtspr SPRN_##exc_lvl_srr1,r10;
916 916
917#if defined(CONFIG_FSL_BOOKE) 917#if defined(CONFIG_PPC_BOOK3E_MMU)
918#ifdef CONFIG_PHYS_64BIT 918#ifdef CONFIG_PHYS_64BIT
919#define RESTORE_MAS7 \ 919#define RESTORE_MAS7 \
920 lwz r11,MAS7(r1); \ 920 lwz r11,MAS7(r1); \
@@ -956,7 +956,7 @@ ret_from_crit_exc:
956 lwz r10,crit_srr1@l(r10); 956 lwz r10,crit_srr1@l(r10);
957 mtspr SPRN_SRR0,r9; 957 mtspr SPRN_SRR0,r9;
958 mtspr SPRN_SRR1,r10; 958 mtspr SPRN_SRR1,r10;
959 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) 959 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
960#endif /* CONFIG_40x */ 960#endif /* CONFIG_40x */
961 961
962#ifdef CONFIG_BOOKE 962#ifdef CONFIG_BOOKE
@@ -967,7 +967,7 @@ ret_from_crit_exc:
967 stw r10,KSP_LIMIT(r9) 967 stw r10,KSP_LIMIT(r9)
968 RESTORE_xSRR(SRR0,SRR1); 968 RESTORE_xSRR(SRR0,SRR1);
969 RESTORE_MMU_REGS; 969 RESTORE_MMU_REGS;
970 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) 970 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
971 971
972 .globl ret_from_debug_exc 972 .globl ret_from_debug_exc
973ret_from_debug_exc: 973ret_from_debug_exc:
@@ -981,7 +981,7 @@ ret_from_debug_exc:
981 RESTORE_xSRR(SRR0,SRR1); 981 RESTORE_xSRR(SRR0,SRR1);
982 RESTORE_xSRR(CSRR0,CSRR1); 982 RESTORE_xSRR(CSRR0,CSRR1);
983 RESTORE_MMU_REGS; 983 RESTORE_MMU_REGS;
984 RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) 984 RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI)
985 985
986 .globl ret_from_mcheck_exc 986 .globl ret_from_mcheck_exc
987ret_from_mcheck_exc: 987ret_from_mcheck_exc:
@@ -992,7 +992,7 @@ ret_from_mcheck_exc:
992 RESTORE_xSRR(CSRR0,CSRR1); 992 RESTORE_xSRR(CSRR0,CSRR1);
993 RESTORE_xSRR(DSRR0,DSRR1); 993 RESTORE_xSRR(DSRR0,DSRR1);
994 RESTORE_MMU_REGS; 994 RESTORE_MMU_REGS;
995 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) 995 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
996#endif /* CONFIG_BOOKE */ 996#endif /* CONFIG_BOOKE */
997 997
998/* 998/*
@@ -1176,59 +1176,27 @@ _GLOBAL(_mcount)
1176 bctr 1176 bctr
1177 1177
1178_GLOBAL(ftrace_caller) 1178_GLOBAL(ftrace_caller)
1179 /* Based off of objdump optput from glibc */ 1179 MCOUNT_SAVE_FRAME
1180 stwu r1,-48(r1) 1180 /* r3 ends up with link register */
1181 stw r3, 12(r1)
1182 stw r4, 16(r1)
1183 stw r5, 20(r1)
1184 stw r6, 24(r1)
1185 mflr r3
1186 lwz r4, 52(r1)
1187 mfcr r5
1188 stw r7, 28(r1)
1189 stw r8, 32(r1)
1190 stw r9, 36(r1)
1191 stw r10,40(r1)
1192 stw r3, 44(r1)
1193 stw r5, 8(r1)
1194 subi r3, r3, MCOUNT_INSN_SIZE 1181 subi r3, r3, MCOUNT_INSN_SIZE
1195.globl ftrace_call 1182.globl ftrace_call
1196ftrace_call: 1183ftrace_call:
1197 bl ftrace_stub 1184 bl ftrace_stub
1198 nop 1185 nop
1199 lwz r6, 8(r1) 1186#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1200 lwz r0, 44(r1) 1187.globl ftrace_graph_call
1201 lwz r3, 12(r1) 1188ftrace_graph_call:
1202 mtctr r0 1189 b ftrace_graph_stub
1203 lwz r4, 16(r1) 1190_GLOBAL(ftrace_graph_stub)
1204 mtcr r6 1191#endif
1205 lwz r5, 20(r1) 1192 MCOUNT_RESTORE_FRAME
1206 lwz r6, 24(r1) 1193 /* old link register ends up in ctr reg */
1207 lwz r0, 52(r1)
1208 lwz r7, 28(r1)
1209 lwz r8, 32(r1)
1210 mtlr r0
1211 lwz r9, 36(r1)
1212 lwz r10,40(r1)
1213 addi r1, r1, 48
1214 bctr 1194 bctr
1215#else 1195#else
1216_GLOBAL(mcount) 1196_GLOBAL(mcount)
1217_GLOBAL(_mcount) 1197_GLOBAL(_mcount)
1218 stwu r1,-48(r1) 1198
1219 stw r3, 12(r1) 1199 MCOUNT_SAVE_FRAME
1220 stw r4, 16(r1)
1221 stw r5, 20(r1)
1222 stw r6, 24(r1)
1223 mflr r3
1224 lwz r4, 52(r1)
1225 mfcr r5
1226 stw r7, 28(r1)
1227 stw r8, 32(r1)
1228 stw r9, 36(r1)
1229 stw r10,40(r1)
1230 stw r3, 44(r1)
1231 stw r5, 8(r1)
1232 1200
1233 subi r3, r3, MCOUNT_INSN_SIZE 1201 subi r3, r3, MCOUNT_INSN_SIZE
1234 LOAD_REG_ADDR(r5, ftrace_trace_function) 1202 LOAD_REG_ADDR(r5, ftrace_trace_function)
@@ -1236,28 +1204,55 @@ _GLOBAL(_mcount)
1236 1204
1237 mtctr r5 1205 mtctr r5
1238 bctrl 1206 bctrl
1239
1240 nop 1207 nop
1241 1208
1242 lwz r6, 8(r1) 1209#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1243 lwz r0, 44(r1) 1210 b ftrace_graph_caller
1244 lwz r3, 12(r1) 1211#endif
1245 mtctr r0 1212 MCOUNT_RESTORE_FRAME
1246 lwz r4, 16(r1)
1247 mtcr r6
1248 lwz r5, 20(r1)
1249 lwz r6, 24(r1)
1250 lwz r0, 52(r1)
1251 lwz r7, 28(r1)
1252 lwz r8, 32(r1)
1253 mtlr r0
1254 lwz r9, 36(r1)
1255 lwz r10,40(r1)
1256 addi r1, r1, 48
1257 bctr 1213 bctr
1258#endif 1214#endif
1259 1215
1260_GLOBAL(ftrace_stub) 1216_GLOBAL(ftrace_stub)
1261 blr 1217 blr
1262 1218
1219#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1220_GLOBAL(ftrace_graph_caller)
1221 /* load r4 with local address */
1222 lwz r4, 44(r1)
1223 subi r4, r4, MCOUNT_INSN_SIZE
1224
1225 /* get the parent address */
1226 addi r3, r1, 52
1227
1228 bl prepare_ftrace_return
1229 nop
1230
1231 MCOUNT_RESTORE_FRAME
1232 /* old link register ends up in ctr reg */
1233 bctr
1234
1235_GLOBAL(return_to_handler)
1236 /* need to save return values */
1237 stwu r1, -32(r1)
1238 stw r3, 20(r1)
1239 stw r4, 16(r1)
1240 stw r31, 12(r1)
1241 mr r31, r1
1242
1243 bl ftrace_return_to_handler
1244 nop
1245
1246 /* return value has real return address */
1247 mtlr r3
1248
1249 lwz r3, 20(r1)
1250 lwz r4, 16(r1)
1251 lwz r31,12(r1)
1252 lwz r1, 0(r1)
1253
1254 /* Jump back to real return address */
1255 blr
1256#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1257
1263#endif /* CONFIG_MCOUNT */ 1258#endif /* CONFIG_MCOUNT */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index f30b4e553c53..43e073477c34 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -917,6 +917,12 @@ _GLOBAL(ftrace_caller)
917ftrace_call: 917ftrace_call:
918 bl ftrace_stub 918 bl ftrace_stub
919 nop 919 nop
920#ifdef CONFIG_FUNCTION_GRAPH_TRACER
921.globl ftrace_graph_call
922ftrace_graph_call:
923 b ftrace_graph_stub
924_GLOBAL(ftrace_graph_stub)
925#endif
920 ld r0, 128(r1) 926 ld r0, 128(r1)
921 mtlr r0 927 mtlr r0
922 addi r1, r1, 112 928 addi r1, r1, 112
@@ -940,13 +946,90 @@ _GLOBAL(_mcount)
940 ld r5,0(r5) 946 ld r5,0(r5)
941 mtctr r5 947 mtctr r5
942 bctrl 948 bctrl
943
944 nop 949 nop
950
951
952#ifdef CONFIG_FUNCTION_GRAPH_TRACER
953 b ftrace_graph_caller
954#endif
945 ld r0, 128(r1) 955 ld r0, 128(r1)
946 mtlr r0 956 mtlr r0
947 addi r1, r1, 112 957 addi r1, r1, 112
948_GLOBAL(ftrace_stub) 958_GLOBAL(ftrace_stub)
949 blr 959 blr
950 960
951#endif 961#endif /* CONFIG_DYNAMIC_FTRACE */
952#endif 962
963#ifdef CONFIG_FUNCTION_GRAPH_TRACER
964_GLOBAL(ftrace_graph_caller)
965 /* load r4 with local address */
966 ld r4, 128(r1)
967 subi r4, r4, MCOUNT_INSN_SIZE
968
969 /* get the parent address */
970 ld r11, 112(r1)
971 addi r3, r11, 16
972
973 bl .prepare_ftrace_return
974 nop
975
976 ld r0, 128(r1)
977 mtlr r0
978 addi r1, r1, 112
979 blr
980
981_GLOBAL(return_to_handler)
982 /* need to save return values */
983 std r4, -24(r1)
984 std r3, -16(r1)
985 std r31, -8(r1)
986 mr r31, r1
987 stdu r1, -112(r1)
988
989 bl .ftrace_return_to_handler
990 nop
991
992 /* return value has real return address */
993 mtlr r3
994
995 ld r1, 0(r1)
996 ld r4, -24(r1)
997 ld r3, -16(r1)
998 ld r31, -8(r1)
999
1000 /* Jump back to real return address */
1001 blr
1002
1003_GLOBAL(mod_return_to_handler)
1004 /* need to save return values */
1005 std r4, -32(r1)
1006 std r3, -24(r1)
1007 /* save TOC */
1008 std r2, -16(r1)
1009 std r31, -8(r1)
1010 mr r31, r1
1011 stdu r1, -112(r1)
1012
1013 /*
1014 * We are in a module using the module's TOC.
1015 * Switch to our TOC to run inside the core kernel.
1016 */
1017 LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
1018 ld r2, 8(r4)
1019
1020 bl .ftrace_return_to_handler
1021 nop
1022
1023 /* return value has real return address */
1024 mtlr r3
1025
1026 ld r1, 0(r1)
1027 ld r4, -32(r1)
1028 ld r3, -24(r1)
1029 ld r2, -16(r1)
1030 ld r31, -8(r1)
1031
1032 /* Jump back to real return address */
1033 blr
1034#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1035#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 60c60ccf5e3c..5455943f16aa 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -5,6 +5,9 @@
5 * 5 *
6 * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box. 6 * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box.
7 * 7 *
8 * Added function graph tracer code, taken from x86 that was written
9 * by Frederic Weisbecker, and ported to PPC by Steven Rostedt.
10 *
8 */ 11 */
9 12
10#include <linux/spinlock.h> 13#include <linux/spinlock.h>
@@ -20,14 +23,6 @@
20#include <asm/code-patching.h> 23#include <asm/code-patching.h>
21#include <asm/ftrace.h> 24#include <asm/ftrace.h>
22 25
23#if 0
24#define DEBUGP printk
25#else
26#define DEBUGP(fmt , ...) do { } while (0)
27#endif
28
29static unsigned int ftrace_nop = PPC_NOP_INSTR;
30
31#ifdef CONFIG_PPC32 26#ifdef CONFIG_PPC32
32# define GET_ADDR(addr) addr 27# define GET_ADDR(addr) addr
33#else 28#else
@@ -35,37 +30,23 @@ static unsigned int ftrace_nop = PPC_NOP_INSTR;
35# define GET_ADDR(addr) (*(unsigned long *)addr) 30# define GET_ADDR(addr) (*(unsigned long *)addr)
36#endif 31#endif
37 32
38 33#ifdef CONFIG_DYNAMIC_FTRACE
39static unsigned int ftrace_calc_offset(long ip, long addr) 34static unsigned int ftrace_nop_replace(void)
40{ 35{
41 return (int)(addr - ip); 36 return PPC_INST_NOP;
42} 37}
43 38
44static unsigned char *ftrace_nop_replace(void) 39static unsigned int
40ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
45{ 41{
46 return (char *)&ftrace_nop; 42 unsigned int op;
47}
48
49static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
50{
51 static unsigned int op;
52 43
53 /*
54 * It would be nice to just use create_function_call, but that will
55 * update the code itself. Here we need to just return the
56 * instruction that is going to be modified, without modifying the
57 * code.
58 */
59 addr = GET_ADDR(addr); 44 addr = GET_ADDR(addr);
60 45
61 /* Set to "bl addr" */ 46 /* if (link) set op to 'bl' else 'b' */
62 op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc); 47 op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
63 48
64 /* 49 return op;
65 * No locking needed, this must be called via kstop_machine
66 * which in essence is like running on a uniprocessor machine.
67 */
68 return (unsigned char *)&op;
69} 50}
70 51
71#ifdef CONFIG_PPC64 52#ifdef CONFIG_PPC64
@@ -77,10 +58,9 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
77#endif 58#endif
78 59
79static int 60static int
80ftrace_modify_code(unsigned long ip, unsigned char *old_code, 61ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
81 unsigned char *new_code)
82{ 62{
83 unsigned char replaced[MCOUNT_INSN_SIZE]; 63 unsigned int replaced;
84 64
85 /* 65 /*
86 * Note: Due to modules and __init, code can 66 * Note: Due to modules and __init, code can
@@ -93,15 +73,15 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
93 */ 73 */
94 74
95 /* read the text we want to modify */ 75 /* read the text we want to modify */
96 if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) 76 if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
97 return -EFAULT; 77 return -EFAULT;
98 78
99 /* Make sure it is what we expect it to be */ 79 /* Make sure it is what we expect it to be */
100 if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) 80 if (replaced != old)
101 return -EINVAL; 81 return -EINVAL;
102 82
103 /* replace the text with the new text */ 83 /* replace the text with the new text */
104 if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) 84 if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE))
105 return -EPERM; 85 return -EPERM;
106 86
107 flush_icache_range(ip, ip + 8); 87 flush_icache_range(ip, ip + 8);
@@ -119,6 +99,8 @@ static int test_24bit_addr(unsigned long ip, unsigned long addr)
119 return create_branch((unsigned int *)ip, addr, 0); 99 return create_branch((unsigned int *)ip, addr, 0);
120} 100}
121 101
102#ifdef CONFIG_MODULES
103
122static int is_bl_op(unsigned int op) 104static int is_bl_op(unsigned int op)
123{ 105{
124 return (op & 0xfc000003) == 0x48000001; 106 return (op & 0xfc000003) == 0x48000001;
@@ -175,7 +157,7 @@ __ftrace_make_nop(struct module *mod,
175 * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) 157 * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12)
176 */ 158 */
177 159
178 DEBUGP("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); 160 pr_debug("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
179 161
180 /* Find where the trampoline jumps to */ 162 /* Find where the trampoline jumps to */
181 if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { 163 if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -183,7 +165,7 @@ __ftrace_make_nop(struct module *mod,
183 return -EFAULT; 165 return -EFAULT;
184 } 166 }
185 167
186 DEBUGP(" %08x %08x", jmp[0], jmp[1]); 168 pr_debug(" %08x %08x", jmp[0], jmp[1]);
187 169
188 /* verify that this is what we expect it to be */ 170 /* verify that this is what we expect it to be */
189 if (((jmp[0] & 0xffff0000) != 0x3d820000) || 171 if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
@@ -199,18 +181,18 @@ __ftrace_make_nop(struct module *mod,
199 offset = ((unsigned)((unsigned short)jmp[0]) << 16) + 181 offset = ((unsigned)((unsigned short)jmp[0]) << 16) +
200 (int)((short)jmp[1]); 182 (int)((short)jmp[1]);
201 183
202 DEBUGP(" %x ", offset); 184 pr_debug(" %x ", offset);
203 185
204 /* get the address this jumps too */ 186 /* get the address this jumps too */
205 tramp = mod->arch.toc + offset + 32; 187 tramp = mod->arch.toc + offset + 32;
206 DEBUGP("toc: %lx", tramp); 188 pr_debug("toc: %lx", tramp);
207 189
208 if (probe_kernel_read(jmp, (void *)tramp, 8)) { 190 if (probe_kernel_read(jmp, (void *)tramp, 8)) {
209 printk(KERN_ERR "Failed to read %lx\n", tramp); 191 printk(KERN_ERR "Failed to read %lx\n", tramp);
210 return -EFAULT; 192 return -EFAULT;
211 } 193 }
212 194
213 DEBUGP(" %08x %08x\n", jmp[0], jmp[1]); 195 pr_debug(" %08x %08x\n", jmp[0], jmp[1]);
214 196
215 ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; 197 ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
216 198
@@ -287,7 +269,7 @@ __ftrace_make_nop(struct module *mod,
287 * 0x4e, 0x80, 0x04, 0x20 bctr 269 * 0x4e, 0x80, 0x04, 0x20 bctr
288 */ 270 */
289 271
290 DEBUGP("ip:%lx jumps to %lx", ip, tramp); 272 pr_debug("ip:%lx jumps to %lx", ip, tramp);
291 273
292 /* Find where the trampoline jumps to */ 274 /* Find where the trampoline jumps to */
293 if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { 275 if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -295,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
295 return -EFAULT; 277 return -EFAULT;
296 } 278 }
297 279
298 DEBUGP(" %08x %08x ", jmp[0], jmp[1]); 280 pr_debug(" %08x %08x ", jmp[0], jmp[1]);
299 281
300 /* verify that this is what we expect it to be */ 282 /* verify that this is what we expect it to be */
301 if (((jmp[0] & 0xffff0000) != 0x3d600000) || 283 if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
@@ -311,7 +293,7 @@ __ftrace_make_nop(struct module *mod,
311 if (tramp & 0x8000) 293 if (tramp & 0x8000)
312 tramp -= 0x10000; 294 tramp -= 0x10000;
313 295
314 DEBUGP(" %x ", tramp); 296 pr_debug(" %x ", tramp);
315 297
316 if (tramp != addr) { 298 if (tramp != addr) {
317 printk(KERN_ERR 299 printk(KERN_ERR
@@ -320,7 +302,7 @@ __ftrace_make_nop(struct module *mod,
320 return -EINVAL; 302 return -EINVAL;
321 } 303 }
322 304
323 op = PPC_NOP_INSTR; 305 op = PPC_INST_NOP;
324 306
325 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) 307 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
326 return -EPERM; 308 return -EPERM;
@@ -330,12 +312,13 @@ __ftrace_make_nop(struct module *mod,
330 return 0; 312 return 0;
331} 313}
332#endif /* PPC64 */ 314#endif /* PPC64 */
315#endif /* CONFIG_MODULES */
333 316
334int ftrace_make_nop(struct module *mod, 317int ftrace_make_nop(struct module *mod,
335 struct dyn_ftrace *rec, unsigned long addr) 318 struct dyn_ftrace *rec, unsigned long addr)
336{ 319{
337 unsigned char *old, *new;
338 unsigned long ip = rec->ip; 320 unsigned long ip = rec->ip;
321 unsigned int old, new;
339 322
340 /* 323 /*
341 * If the calling address is more that 24 bits away, 324 * If the calling address is more that 24 bits away,
@@ -344,11 +327,12 @@ int ftrace_make_nop(struct module *mod,
344 */ 327 */
345 if (test_24bit_addr(ip, addr)) { 328 if (test_24bit_addr(ip, addr)) {
346 /* within range */ 329 /* within range */
347 old = ftrace_call_replace(ip, addr); 330 old = ftrace_call_replace(ip, addr, 1);
348 new = ftrace_nop_replace(); 331 new = ftrace_nop_replace();
349 return ftrace_modify_code(ip, old, new); 332 return ftrace_modify_code(ip, old, new);
350 } 333 }
351 334
335#ifdef CONFIG_MODULES
352 /* 336 /*
353 * Out of range jumps are called from modules. 337 * Out of range jumps are called from modules.
354 * We should either already have a pointer to the module 338 * We should either already have a pointer to the module
@@ -373,9 +357,13 @@ int ftrace_make_nop(struct module *mod,
373 mod = rec->arch.mod; 357 mod = rec->arch.mod;
374 358
375 return __ftrace_make_nop(mod, rec, addr); 359 return __ftrace_make_nop(mod, rec, addr);
376 360#else
361 /* We should not get here without modules */
362 return -EINVAL;
363#endif /* CONFIG_MODULES */
377} 364}
378 365
366#ifdef CONFIG_MODULES
379#ifdef CONFIG_PPC64 367#ifdef CONFIG_PPC64
380static int 368static int
381__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 369__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
@@ -392,7 +380,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
392 * b +8; ld r2,40(r1) 380 * b +8; ld r2,40(r1)
393 */ 381 */
394 if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && 382 if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
395 ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) { 383 ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
396 printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); 384 printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
397 return -EINVAL; 385 return -EINVAL;
398 } 386 }
@@ -414,7 +402,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
414 /* ld r2,40(r1) */ 402 /* ld r2,40(r1) */
415 op[1] = 0xe8410028; 403 op[1] = 0xe8410028;
416 404
417 DEBUGP("write to %lx\n", rec->ip); 405 pr_debug("write to %lx\n", rec->ip);
418 406
419 if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) 407 if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
420 return -EPERM; 408 return -EPERM;
@@ -435,7 +423,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
435 return -EFAULT; 423 return -EFAULT;
436 424
437 /* It should be pointing to a nop */ 425 /* It should be pointing to a nop */
438 if (op != PPC_NOP_INSTR) { 426 if (op != PPC_INST_NOP) {
439 printk(KERN_ERR "Expected NOP but have %x\n", op); 427 printk(KERN_ERR "Expected NOP but have %x\n", op);
440 return -EINVAL; 428 return -EINVAL;
441 } 429 }
@@ -454,7 +442,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
454 return -EINVAL; 442 return -EINVAL;
455 } 443 }
456 444
457 DEBUGP("write to %lx\n", rec->ip); 445 pr_debug("write to %lx\n", rec->ip);
458 446
459 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) 447 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
460 return -EPERM; 448 return -EPERM;
@@ -464,11 +452,12 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
464 return 0; 452 return 0;
465} 453}
466#endif /* CONFIG_PPC64 */ 454#endif /* CONFIG_PPC64 */
455#endif /* CONFIG_MODULES */
467 456
468int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 457int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
469{ 458{
470 unsigned char *old, *new;
471 unsigned long ip = rec->ip; 459 unsigned long ip = rec->ip;
460 unsigned int old, new;
472 461
473 /* 462 /*
474 * If the calling address is more that 24 bits away, 463 * If the calling address is more that 24 bits away,
@@ -478,10 +467,11 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
478 if (test_24bit_addr(ip, addr)) { 467 if (test_24bit_addr(ip, addr)) {
479 /* within range */ 468 /* within range */
480 old = ftrace_nop_replace(); 469 old = ftrace_nop_replace();
481 new = ftrace_call_replace(ip, addr); 470 new = ftrace_call_replace(ip, addr, 1);
482 return ftrace_modify_code(ip, old, new); 471 return ftrace_modify_code(ip, old, new);
483 } 472 }
484 473
474#ifdef CONFIG_MODULES
485 /* 475 /*
486 * Out of range jumps are called from modules. 476 * Out of range jumps are called from modules.
487 * Being that we are converting from nop, it had better 477 * Being that we are converting from nop, it had better
@@ -493,16 +483,20 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
493 } 483 }
494 484
495 return __ftrace_make_call(rec, addr); 485 return __ftrace_make_call(rec, addr);
486#else
487 /* We should not get here without modules */
488 return -EINVAL;
489#endif /* CONFIG_MODULES */
496} 490}
497 491
498int ftrace_update_ftrace_func(ftrace_func_t func) 492int ftrace_update_ftrace_func(ftrace_func_t func)
499{ 493{
500 unsigned long ip = (unsigned long)(&ftrace_call); 494 unsigned long ip = (unsigned long)(&ftrace_call);
501 unsigned char old[MCOUNT_INSN_SIZE], *new; 495 unsigned int old, new;
502 int ret; 496 int ret;
503 497
504 memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); 498 old = *(unsigned int *)&ftrace_call;
505 new = ftrace_call_replace(ip, (unsigned long)func); 499 new = ftrace_call_replace(ip, (unsigned long)func, 1);
506 ret = ftrace_modify_code(ip, old, new); 500 ret = ftrace_modify_code(ip, old, new);
507 501
508 return ret; 502 return ret;
@@ -517,3 +511,111 @@ int __init ftrace_dyn_arch_init(void *data)
517 511
518 return 0; 512 return 0;
519} 513}
514#endif /* CONFIG_DYNAMIC_FTRACE */
515
516#ifdef CONFIG_FUNCTION_GRAPH_TRACER
517
518#ifdef CONFIG_DYNAMIC_FTRACE
519extern void ftrace_graph_call(void);
520extern void ftrace_graph_stub(void);
521
522int ftrace_enable_ftrace_graph_caller(void)
523{
524 unsigned long ip = (unsigned long)(&ftrace_graph_call);
525 unsigned long addr = (unsigned long)(&ftrace_graph_caller);
526 unsigned long stub = (unsigned long)(&ftrace_graph_stub);
527 unsigned int old, new;
528
529 old = ftrace_call_replace(ip, stub, 0);
530 new = ftrace_call_replace(ip, addr, 0);
531
532 return ftrace_modify_code(ip, old, new);
533}
534
535int ftrace_disable_ftrace_graph_caller(void)
536{
537 unsigned long ip = (unsigned long)(&ftrace_graph_call);
538 unsigned long addr = (unsigned long)(&ftrace_graph_caller);
539 unsigned long stub = (unsigned long)(&ftrace_graph_stub);
540 unsigned int old, new;
541
542 old = ftrace_call_replace(ip, addr, 0);
543 new = ftrace_call_replace(ip, stub, 0);
544
545 return ftrace_modify_code(ip, old, new);
546}
547#endif /* CONFIG_DYNAMIC_FTRACE */
548
549#ifdef CONFIG_PPC64
550extern void mod_return_to_handler(void);
551#endif
552
553/*
554 * Hook the return address and push it in the stack of return addrs
555 * in current thread info.
556 */
557void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
558{
559 unsigned long old;
560 int faulted;
561 struct ftrace_graph_ent trace;
562 unsigned long return_hooker = (unsigned long)&return_to_handler;
563
564 if (unlikely(atomic_read(&current->tracing_graph_pause)))
565 return;
566
567#if CONFIG_PPC64
568 /* non core kernel code needs to save and restore the TOC */
569 if (REGION_ID(self_addr) != KERNEL_REGION_ID)
570 return_hooker = (unsigned long)&mod_return_to_handler;
571#endif
572
573 return_hooker = GET_ADDR(return_hooker);
574
575 /*
576 * Protect against fault, even if it shouldn't
577 * happen. This tool is too much intrusive to
578 * ignore such a protection.
579 */
580 asm volatile(
581 "1: " PPC_LL "%[old], 0(%[parent])\n"
582 "2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
583 " li %[faulted], 0\n"
584 "3:\n"
585
586 ".section .fixup, \"ax\"\n"
587 "4: li %[faulted], 1\n"
588 " b 3b\n"
589 ".previous\n"
590
591 ".section __ex_table,\"a\"\n"
592 PPC_LONG_ALIGN "\n"
593 PPC_LONG "1b,4b\n"
594 PPC_LONG "2b,4b\n"
595 ".previous"
596
597 : [old] "=r" (old), [faulted] "=r" (faulted)
598 : [parent] "r" (parent), [return_hooker] "r" (return_hooker)
599 : "memory"
600 );
601
602 if (unlikely(faulted)) {
603 ftrace_graph_stop();
604 WARN_ON(1);
605 return;
606 }
607
608 if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
609 *parent = old;
610 return;
611 }
612
613 trace.func = self_addr;
614
615 /* Only trace if the calling function expects to */
616 if (!ftrace_graph_entry(&trace)) {
617 current->curr_ret_stack--;
618 *parent = old;
619 }
620}
621#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index a1c4cfd25ded..54e68c11ae15 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -108,18 +108,21 @@ __start:
108 * because OF may have I/O devices mapped into that area 108 * because OF may have I/O devices mapped into that area
109 * (particularly on CHRP). 109 * (particularly on CHRP).
110 */ 110 */
111#ifdef CONFIG_PPC_MULTIPLATFORM
112 cmpwi 0,r5,0 111 cmpwi 0,r5,0
113 beq 1f 112 beq 1f
114 113
114#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
115 /* find out where we are now */ 115 /* find out where we are now */
116 bcl 20,31,$+4 116 bcl 20,31,$+4
1170: mflr r8 /* r8 = runtime addr here */ 1170: mflr r8 /* r8 = runtime addr here */
118 addis r8,r8,(_stext - 0b)@ha 118 addis r8,r8,(_stext - 0b)@ha
119 addi r8,r8,(_stext - 0b)@l /* current runtime base addr */ 119 addi r8,r8,(_stext - 0b)@l /* current runtime base addr */
120 bl prom_init 120 bl prom_init
121#endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */
122
123 /* We never return. We also hit that trap if trying to boot
124 * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
121 trap 125 trap
122#endif
123 126
124/* 127/*
125 * Check for BootX signature when supporting PowerMac and branch to 128 * Check for BootX signature when supporting PowerMac and branch to
@@ -472,12 +475,11 @@ SystemCall:
472 . = 0x1000 475 . = 0x1000
473InstructionTLBMiss: 476InstructionTLBMiss:
474/* 477/*
475 * r0: stored ctr 478 * r0: scratch
476 * r1: linux style pte ( later becomes ppc hardware pte ) 479 * r1: linux style pte ( later becomes ppc hardware pte )
477 * r2: ptr to linux-style pte 480 * r2: ptr to linux-style pte
478 * r3: scratch 481 * r3: scratch
479 */ 482 */
480 mfctr r0
481 /* Get PTE (linux-style) and check access */ 483 /* Get PTE (linux-style) and check access */
482 mfspr r3,SPRN_IMISS 484 mfspr r3,SPRN_IMISS
483 lis r1,PAGE_OFFSET@h /* check if kernel address */ 485 lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -496,25 +498,27 @@ InstructionTLBMiss:
496 rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 498 rlwinm. r2,r2,0,0,19 /* extract address of pte page */
497 beq- InstructionAddressInvalid /* return if no mapping */ 499 beq- InstructionAddressInvalid /* return if no mapping */
498 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 500 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
499 lwz r3,0(r2) /* get linux-style pte */ 501 lwz r0,0(r2) /* get linux-style pte */
500 andc. r1,r1,r3 /* check access & ~permission */ 502 andc. r1,r1,r0 /* check access & ~permission */
501 bne- InstructionAddressInvalid /* return if access not permitted */ 503 bne- InstructionAddressInvalid /* return if access not permitted */
502 ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ 504 ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
503 /* 505 /*
504 * NOTE! We are assuming this is not an SMP system, otherwise 506 * NOTE! We are assuming this is not an SMP system, otherwise
505 * we would need to update the pte atomically with lwarx/stwcx. 507 * we would need to update the pte atomically with lwarx/stwcx.
506 */ 508 */
507 stw r3,0(r2) /* update PTE (accessed bit) */ 509 stw r0,0(r2) /* update PTE (accessed bit) */
508 /* Convert linux-style PTE to low word of PPC-style PTE */ 510 /* Convert linux-style PTE to low word of PPC-style PTE */
509 rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ 511 rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */
510 rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ 512 rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
511 and r1,r1,r2 /* writable if _RW and _DIRTY */ 513 and r1,r1,r2 /* writable if _RW and _DIRTY */
512 rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ 514 rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
513 rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ 515 rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */
514 ori r1,r1,0xe14 /* clear out reserved bits and M */ 516 ori r1,r1,0xe04 /* clear out reserved bits */
515 andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ 517 andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
518BEGIN_FTR_SECTION
519 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
520END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
516 mtspr SPRN_RPA,r1 521 mtspr SPRN_RPA,r1
517 mfspr r3,SPRN_IMISS
518 tlbli r3 522 tlbli r3
519 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ 523 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
520 mtcrf 0x80,r3 524 mtcrf 0x80,r3
@@ -525,7 +529,6 @@ InstructionAddressInvalid:
525 529
526 addis r1,r1,0x2000 530 addis r1,r1,0x2000
527 mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */ 531 mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
528 mtctr r0 /* Restore CTR */
529 andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ 532 andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
530 or r2,r2,r1 533 or r2,r2,r1
531 mtspr SPRN_SRR1,r2 534 mtspr SPRN_SRR1,r2
@@ -546,12 +549,11 @@ InstructionAddressInvalid:
546 . = 0x1100 549 . = 0x1100
547DataLoadTLBMiss: 550DataLoadTLBMiss:
548/* 551/*
549 * r0: stored ctr 552 * r0: scratch
550 * r1: linux style pte ( later becomes ppc hardware pte ) 553 * r1: linux style pte ( later becomes ppc hardware pte )
551 * r2: ptr to linux-style pte 554 * r2: ptr to linux-style pte
552 * r3: scratch 555 * r3: scratch
553 */ 556 */
554 mfctr r0
555 /* Get PTE (linux-style) and check access */ 557 /* Get PTE (linux-style) and check access */
556 mfspr r3,SPRN_DMISS 558 mfspr r3,SPRN_DMISS
557 lis r1,PAGE_OFFSET@h /* check if kernel address */ 559 lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -570,35 +572,48 @@ DataLoadTLBMiss:
570 rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 572 rlwinm. r2,r2,0,0,19 /* extract address of pte page */
571 beq- DataAddressInvalid /* return if no mapping */ 573 beq- DataAddressInvalid /* return if no mapping */
572 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 574 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
573 lwz r3,0(r2) /* get linux-style pte */ 575 lwz r0,0(r2) /* get linux-style pte */
574 andc. r1,r1,r3 /* check access & ~permission */ 576 andc. r1,r1,r0 /* check access & ~permission */
575 bne- DataAddressInvalid /* return if access not permitted */ 577 bne- DataAddressInvalid /* return if access not permitted */
576 ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ 578 ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
577 /* 579 /*
578 * NOTE! We are assuming this is not an SMP system, otherwise 580 * NOTE! We are assuming this is not an SMP system, otherwise
579 * we would need to update the pte atomically with lwarx/stwcx. 581 * we would need to update the pte atomically with lwarx/stwcx.
580 */ 582 */
581 stw r3,0(r2) /* update PTE (accessed bit) */ 583 stw r0,0(r2) /* update PTE (accessed bit) */
582 /* Convert linux-style PTE to low word of PPC-style PTE */ 584 /* Convert linux-style PTE to low word of PPC-style PTE */
583 rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ 585 rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */
584 rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ 586 rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
585 and r1,r1,r2 /* writable if _RW and _DIRTY */ 587 and r1,r1,r2 /* writable if _RW and _DIRTY */
586 rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ 588 rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
587 rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ 589 rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */
588 ori r1,r1,0xe14 /* clear out reserved bits and M */ 590 ori r1,r1,0xe04 /* clear out reserved bits */
589 andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ 591 andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
592BEGIN_FTR_SECTION
593 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
594END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
590 mtspr SPRN_RPA,r1 595 mtspr SPRN_RPA,r1
591 mfspr r3,SPRN_DMISS 596 mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
597 mtcrf 0x80,r2
598BEGIN_MMU_FTR_SECTION
599 li r0,1
600 mfspr r1,SPRN_SPRG4
601 rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
602 slw r0,r0,r2
603 xor r1,r0,r1
604 srw r0,r1,r2
605 mtspr SPRN_SPRG4,r1
606 mfspr r2,SPRN_SRR1
607 rlwimi r2,r0,31-14,14,14
608 mtspr SPRN_SRR1,r2
609END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
592 tlbld r3 610 tlbld r3
593 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
594 mtcrf 0x80,r3
595 rfi 611 rfi
596DataAddressInvalid: 612DataAddressInvalid:
597 mfspr r3,SPRN_SRR1 613 mfspr r3,SPRN_SRR1
598 rlwinm r1,r3,9,6,6 /* Get load/store bit */ 614 rlwinm r1,r3,9,6,6 /* Get load/store bit */
599 addis r1,r1,0x2000 615 addis r1,r1,0x2000
600 mtspr SPRN_DSISR,r1 616 mtspr SPRN_DSISR,r1
601 mtctr r0 /* Restore CTR */
602 andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ 617 andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
603 mtspr SPRN_SRR1,r2 618 mtspr SPRN_SRR1,r2
604 mfspr r1,SPRN_DMISS /* Get failing address */ 619 mfspr r1,SPRN_DMISS /* Get failing address */
@@ -618,12 +633,11 @@ DataAddressInvalid:
618 . = 0x1200 633 . = 0x1200
619DataStoreTLBMiss: 634DataStoreTLBMiss:
620/* 635/*
621 * r0: stored ctr 636 * r0: scratch
622 * r1: linux style pte ( later becomes ppc hardware pte ) 637 * r1: linux style pte ( later becomes ppc hardware pte )
623 * r2: ptr to linux-style pte 638 * r2: ptr to linux-style pte
624 * r3: scratch 639 * r3: scratch
625 */ 640 */
626 mfctr r0
627 /* Get PTE (linux-style) and check access */ 641 /* Get PTE (linux-style) and check access */
628 mfspr r3,SPRN_DMISS 642 mfspr r3,SPRN_DMISS
629 lis r1,PAGE_OFFSET@h /* check if kernel address */ 643 lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -642,24 +656,38 @@ DataStoreTLBMiss:
642 rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 656 rlwinm. r2,r2,0,0,19 /* extract address of pte page */
643 beq- DataAddressInvalid /* return if no mapping */ 657 beq- DataAddressInvalid /* return if no mapping */
644 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 658 rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
645 lwz r3,0(r2) /* get linux-style pte */ 659 lwz r0,0(r2) /* get linux-style pte */
646 andc. r1,r1,r3 /* check access & ~permission */ 660 andc. r1,r1,r0 /* check access & ~permission */
647 bne- DataAddressInvalid /* return if access not permitted */ 661 bne- DataAddressInvalid /* return if access not permitted */
648 ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY 662 ori r0,r0,_PAGE_ACCESSED|_PAGE_DIRTY
649 /* 663 /*
650 * NOTE! We are assuming this is not an SMP system, otherwise 664 * NOTE! We are assuming this is not an SMP system, otherwise
651 * we would need to update the pte atomically with lwarx/stwcx. 665 * we would need to update the pte atomically with lwarx/stwcx.
652 */ 666 */
653 stw r3,0(r2) /* update PTE (accessed/dirty bits) */ 667 stw r0,0(r2) /* update PTE (accessed/dirty bits) */
654 /* Convert linux-style PTE to low word of PPC-style PTE */ 668 /* Convert linux-style PTE to low word of PPC-style PTE */
655 rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ 669 rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
656 li r1,0xe15 /* clear out reserved bits and M */ 670 li r1,0xe05 /* clear out reserved bits & PP lsb */
657 andc r1,r3,r1 /* PP = user? 2: 0 */ 671 andc r1,r0,r1 /* PP = user? 2: 0 */
672BEGIN_FTR_SECTION
673 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
674END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
658 mtspr SPRN_RPA,r1 675 mtspr SPRN_RPA,r1
659 mfspr r3,SPRN_DMISS 676 mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
677 mtcrf 0x80,r2
678BEGIN_MMU_FTR_SECTION
679 li r0,1
680 mfspr r1,SPRN_SPRG4
681 rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
682 slw r0,r0,r2
683 xor r1,r0,r1
684 srw r0,r1,r2
685 mtspr SPRN_SPRG4,r1
686 mfspr r2,SPRN_SRR1
687 rlwimi r2,r0,31-14,14,14
688 mtspr SPRN_SRR1,r2
689END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
660 tlbld r3 690 tlbld r3
661 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
662 mtcrf 0x80,r3
663 rfi 691 rfi
664 692
665#ifndef CONFIG_ALTIVEC 693#ifndef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index ebaedafc8e67..50ef505b8fb6 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1360,6 +1360,7 @@ _GLOBAL(__start_initialization_multiplatform)
1360 b .__after_prom_start 1360 b .__after_prom_start
1361 1361
1362_INIT_STATIC(__boot_from_prom) 1362_INIT_STATIC(__boot_from_prom)
1363#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
1363 /* Save parameters */ 1364 /* Save parameters */
1364 mr r31,r3 1365 mr r31,r3
1365 mr r30,r4 1366 mr r30,r4
@@ -1390,7 +1391,10 @@ _INIT_STATIC(__boot_from_prom)
1390 /* Do all of the interaction with OF client interface */ 1391 /* Do all of the interaction with OF client interface */
1391 mr r8,r26 1392 mr r8,r26
1392 bl .prom_init 1393 bl .prom_init
1393 /* We never return */ 1394#endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */
1395
1396 /* We never return. We also hit that trap if trying to boot
1397 * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
1394 trap 1398 trap
1395 1399
1396_STATIC(__after_prom_start) 1400_STATIC(__after_prom_start)
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index fce2df988504..95f39f1e68d4 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -10,6 +10,15 @@
10 mtspr SPRN_IVOR##vector_number,r26; \ 10 mtspr SPRN_IVOR##vector_number,r26; \
11 sync 11 sync
12 12
13#if (THREAD_SHIFT < 15)
14#define ALLOC_STACK_FRAME(reg, val) \
15 addi reg,reg,val
16#else
17#define ALLOC_STACK_FRAME(reg, val) \
18 addis reg,reg,val@ha; \
19 addi reg,reg,val@l
20#endif
21
13#define NORMAL_EXCEPTION_PROLOG \ 22#define NORMAL_EXCEPTION_PROLOG \
14 mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ 23 mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
15 mtspr SPRN_SPRG1,r11; \ 24 mtspr SPRN_SPRG1,r11; \
@@ -20,7 +29,7 @@
20 beq 1f; \ 29 beq 1f; \
21 mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\ 30 mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
22 lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ 31 lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
23 addi r1,r1,THREAD_SIZE; \ 32 ALLOC_STACK_FRAME(r1, THREAD_SIZE); \
241: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ 331: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
25 mr r11,r1; \ 34 mr r11,r1; \
26 stw r10,_CCR(r11); /* save various registers */\ 35 stw r10,_CCR(r11); /* save various registers */\
@@ -70,10 +79,10 @@
70 79
71/* only on e500mc/e200 */ 80/* only on e500mc/e200 */
72#define DEBUG_STACK_BASE dbgirq_ctx 81#define DEBUG_STACK_BASE dbgirq_ctx
73#ifdef CONFIG_PPC_E500MC 82#ifdef CONFIG_E200
74#define DEBUG_SPRG SPRN_SPRG9
75#else
76#define DEBUG_SPRG SPRN_SPRG6W 83#define DEBUG_SPRG SPRN_SPRG6W
84#else
85#define DEBUG_SPRG SPRN_SPRG9
77#endif 86#endif
78 87
79#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE) 88#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
@@ -279,7 +288,7 @@ label:
279 lwz r11,GPR11(r8); \ 288 lwz r11,GPR11(r8); \
280 mfspr r8,DEBUG_SPRG; \ 289 mfspr r8,DEBUG_SPRG; \
281 \ 290 \
282 RFDI; \ 291 PPC_RFDI; \
283 b .; \ 292 b .; \
284 \ 293 \
285 /* continue normal handling for a debug exception... */ \ 294 /* continue normal handling for a debug exception... */ \
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 36ffb3504a4f..4c22620d009b 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -103,10 +103,15 @@ invstr: mflr r6 /* Make it accessible */
103 or r7,r7,r4 103 or r7,r7,r4
104 mtspr SPRN_MAS6,r7 104 mtspr SPRN_MAS6,r7
105 tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ 105 tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
106#ifndef CONFIG_E200
107 mfspr r7,SPRN_MAS1 106 mfspr r7,SPRN_MAS1
108 andis. r7,r7,MAS1_VALID@h 107 andis. r7,r7,MAS1_VALID@h
109 bne match_TLB 108 bne match_TLB
109
110 mfspr r7,SPRN_MMUCFG
111 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
112 cmpwi r7,3
113 bne match_TLB /* skip if NPIDS != 3 */
114
110 mfspr r7,SPRN_PID1 115 mfspr r7,SPRN_PID1
111 slwi r7,r7,16 116 slwi r7,r7,16
112 or r7,r7,r4 117 or r7,r7,r4
@@ -120,7 +125,7 @@ invstr: mflr r6 /* Make it accessible */
120 or r7,r7,r4 125 or r7,r7,r4
121 mtspr SPRN_MAS6,r7 126 mtspr SPRN_MAS6,r7
122 tlbsx 0,r6 /* Fall through, we had to match */ 127 tlbsx 0,r6 /* Fall through, we had to match */
123#endif 128
124match_TLB: 129match_TLB:
125 mfspr r7,SPRN_MAS0 130 mfspr r7,SPRN_MAS0
126 rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ 131 rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
@@ -168,7 +173,7 @@ skpinv: addi r6,r6,1 /* Increment */
168 173
169 /* grab and fixup the RPN */ 174 /* grab and fixup the RPN */
170 mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ 175 mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */
171 rlwinm r6,r6,25,27,30 176 rlwinm r6,r6,25,27,31
172 li r8,-1 177 li r8,-1
173 addi r6,r6,10 178 addi r6,r6,10
174 slw r6,r8,r6 /* convert to mask */ 179 slw r6,r8,r6 /* convert to mask */
@@ -194,7 +199,7 @@ skpinv: addi r6,r6,1 /* Increment */
194 xori r6,r4,1 /* Setup TMP mapping in the other Address space */ 199 xori r6,r4,1 /* Setup TMP mapping in the other Address space */
195 slwi r6,r6,12 200 slwi r6,r6,12
196 oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h 201 oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
197 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l 202 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
198 mtspr SPRN_MAS1,r6 203 mtspr SPRN_MAS1,r6
199 mfspr r6,SPRN_MAS2 204 mfspr r6,SPRN_MAS2
200 li r7,0 /* temp EPN = 0 */ 205 li r7,0 /* temp EPN = 0 */
@@ -215,14 +220,19 @@ skpinv: addi r6,r6,1 /* Increment */
215 220
216/* 4. Clear out PIDs & Search info */ 221/* 4. Clear out PIDs & Search info */
217 li r6,0 222 li r6,0
223 mtspr SPRN_MAS6,r6
218 mtspr SPRN_PID0,r6 224 mtspr SPRN_PID0,r6
219#ifndef CONFIG_E200 225
226 mfspr r7,SPRN_MMUCFG
227 rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
228 cmpwi r7,3
229 bne 2f /* skip if NPIDS != 3 */
230
220 mtspr SPRN_PID1,r6 231 mtspr SPRN_PID1,r6
221 mtspr SPRN_PID2,r6 232 mtspr SPRN_PID2,r6
222#endif
223 mtspr SPRN_MAS6,r6
224 233
225/* 5. Invalidate mapping we started in */ 234/* 5. Invalidate mapping we started in */
2352:
226 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ 236 lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
227 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ 237 rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
228 mtspr SPRN_MAS0,r7 238 mtspr SPRN_MAS0,r7
@@ -247,10 +257,10 @@ skpinv: addi r6,r6,1 /* Increment */
247 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ 257 lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
248 mtspr SPRN_MAS0,r6 258 mtspr SPRN_MAS0,r6
249 lis r6,(MAS1_VALID|MAS1_IPROT)@h 259 lis r6,(MAS1_VALID|MAS1_IPROT)@h
250 ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l 260 ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
251 mtspr SPRN_MAS1,r6 261 mtspr SPRN_MAS1,r6
252 lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h 262 lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
253 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l 263 ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
254 mtspr SPRN_MAS2,r6 264 mtspr SPRN_MAS2,r6
255 mtspr SPRN_MAS3,r8 265 mtspr SPRN_MAS3,r8
256 tlbwe 266 tlbwe
@@ -298,26 +308,14 @@ skpinv: addi r6,r6,1 /* Increment */
298 SET_IVOR(12, WatchdogTimer); 308 SET_IVOR(12, WatchdogTimer);
299 SET_IVOR(13, DataTLBError); 309 SET_IVOR(13, DataTLBError);
300 SET_IVOR(14, InstructionTLBError); 310 SET_IVOR(14, InstructionTLBError);
301 SET_IVOR(15, DebugDebug);
302#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
303 SET_IVOR(15, DebugCrit); 311 SET_IVOR(15, DebugCrit);
304#endif
305 SET_IVOR(32, SPEUnavailable);
306 SET_IVOR(33, SPEFloatingPointData);
307 SET_IVOR(34, SPEFloatingPointRound);
308#ifndef CONFIG_E200
309 SET_IVOR(35, PerformanceMonitor);
310#endif
311#ifdef CONFIG_PPC_E500MC
312 SET_IVOR(36, Doorbell);
313#endif
314 312
315 /* Establish the interrupt vector base */ 313 /* Establish the interrupt vector base */
316 lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ 314 lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
317 mtspr SPRN_IVPR,r4 315 mtspr SPRN_IVPR,r4
318 316
319 /* Setup the defaults for TLB entries */ 317 /* Setup the defaults for TLB entries */
320 li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l 318 li r2,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
321#ifdef CONFIG_E200 319#ifdef CONFIG_E200
322 oris r2,r2,MAS4_TLBSELD(1)@h 320 oris r2,r2,MAS4_TLBSELD(1)@h
323#endif 321#endif
@@ -329,12 +327,6 @@ skpinv: addi r6,r6,1 /* Increment */
329 oris r2,r2,HID0_DOZE@h 327 oris r2,r2,HID0_DOZE@h
330 mtspr SPRN_HID0, r2 328 mtspr SPRN_HID0, r2
331#endif 329#endif
332#ifdef CONFIG_E200
333 /* enable dedicated debug exception handling resources (Debug APU) */
334 mfspr r2,SPRN_HID0
335 ori r2,r2,HID0_DAPUEN@l
336 mtspr SPRN_HID0,r2
337#endif
338 330
339#if !defined(CONFIG_BDI_SWITCH) 331#if !defined(CONFIG_BDI_SWITCH)
340 /* 332 /*
@@ -706,15 +698,13 @@ interrupt_base:
706 /* Performance Monitor */ 698 /* Performance Monitor */
707 EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) 699 EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
708 700
709#ifdef CONFIG_PPC_E500MC 701 EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD)
710 EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD) 702
711#endif 703 CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception)
712 704
713 /* Debug Interrupt */ 705 /* Debug Interrupt */
714 DEBUG_DEBUG_EXCEPTION 706 DEBUG_DEBUG_EXCEPTION
715#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
716 DEBUG_CRIT_EXCEPTION 707 DEBUG_CRIT_EXCEPTION
717#endif
718 708
719/* 709/*
720 * Local functions 710 * Local functions
@@ -897,6 +887,47 @@ KernelSPE:
897 * Global functions 887 * Global functions
898 */ 888 */
899 889
890/* Adjust or setup IVORs for e200 */
891_GLOBAL(__setup_e200_ivors)
892 li r3,DebugDebug@l
893 mtspr SPRN_IVOR15,r3
894 li r3,SPEUnavailable@l
895 mtspr SPRN_IVOR32,r3
896 li r3,SPEFloatingPointData@l
897 mtspr SPRN_IVOR33,r3
898 li r3,SPEFloatingPointRound@l
899 mtspr SPRN_IVOR34,r3
900 sync
901 blr
902
903/* Adjust or setup IVORs for e500v1/v2 */
904_GLOBAL(__setup_e500_ivors)
905 li r3,DebugCrit@l
906 mtspr SPRN_IVOR15,r3
907 li r3,SPEUnavailable@l
908 mtspr SPRN_IVOR32,r3
909 li r3,SPEFloatingPointData@l
910 mtspr SPRN_IVOR33,r3
911 li r3,SPEFloatingPointRound@l
912 mtspr SPRN_IVOR34,r3
913 li r3,PerformanceMonitor@l
914 mtspr SPRN_IVOR35,r3
915 sync
916 blr
917
918/* Adjust or setup IVORs for e500mc */
919_GLOBAL(__setup_e500mc_ivors)
920 li r3,DebugDebug@l
921 mtspr SPRN_IVOR15,r3
922 li r3,PerformanceMonitor@l
923 mtspr SPRN_IVOR35,r3
924 li r3,Doorbell@l
925 mtspr SPRN_IVOR36,r3
926 li r3,CriticalDoorbell@l
927 mtspr SPRN_IVOR37,r3
928 sync
929 blr
930
900/* 931/*
901 * extern void loadcam_entry(unsigned int index) 932 * extern void loadcam_entry(unsigned int index)
902 * 933 *
@@ -1089,7 +1120,7 @@ __secondary_start:
1089 mtspr SPRN_SPRG3,r4 1120 mtspr SPRN_SPRG3,r4
1090 1121
1091 /* Setup the defaults for TLB entries */ 1122 /* Setup the defaults for TLB entries */
1092 li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l 1123 li r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
1093 mtspr SPRN_MAS4,r4 1124 mtspr SPRN_MAS4,r4
1094 1125
1095 /* Jump to start_secondary */ 1126 /* Jump to start_secondary */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 7f8e6a92c5a1..0d2e37c57738 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -181,7 +181,7 @@ int show_interrupts(struct seq_file *p, void *v)
181{ 181{
182 int i = *(loff_t *)v, j; 182 int i = *(loff_t *)v, j;
183 struct irqaction *action; 183 struct irqaction *action;
184 irq_desc_t *desc; 184 struct irq_desc *desc;
185 unsigned long flags; 185 unsigned long flags;
186 186
187 if (i == 0) { 187 if (i == 0) {
@@ -200,7 +200,7 @@ int show_interrupts(struct seq_file *p, void *v)
200 seq_printf(p, "%3d: ", i); 200 seq_printf(p, "%3d: ", i);
201#ifdef CONFIG_SMP 201#ifdef CONFIG_SMP
202 for_each_online_cpu(j) 202 for_each_online_cpu(j)
203 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 203 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
204#else 204#else
205 seq_printf(p, "%10u ", kstat_irqs(i)); 205 seq_printf(p, "%10u ", kstat_irqs(i));
206#endif /* CONFIG_SMP */ 206#endif /* CONFIG_SMP */
@@ -1048,7 +1048,7 @@ arch_initcall(irq_late_init);
1048static int virq_debug_show(struct seq_file *m, void *private) 1048static int virq_debug_show(struct seq_file *m, void *private)
1049{ 1049{
1050 unsigned long flags; 1050 unsigned long flags;
1051 irq_desc_t *desc; 1051 struct irq_desc *desc;
1052 const char *p; 1052 const char *p;
1053 char none[] = "none"; 1053 char none[] = "none";
1054 int i; 1054 int i;
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 8992b031a7b6..8fbb12508bf3 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -329,7 +329,7 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
329 restore r2. */ 329 restore r2. */
330static int restore_r2(u32 *instruction, struct module *me) 330static int restore_r2(u32 *instruction, struct module *me)
331{ 331{
332 if (*instruction != PPC_NOP_INSTR) { 332 if (*instruction != PPC_INST_NOP) {
333 printk("%s: Expect noop after relocate, got %08x\n", 333 printk("%s: Expect noop after relocate, got %08x\n",
334 me->name, *instruction); 334 me->name, *instruction);
335 return 0; 335 return 0;
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 3bb7d3dd28be..8bbc12d20f5c 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/msi.h> 11#include <linux/msi.h>
12#include <linux/pci.h>
12 13
13#include <asm/machdep.h> 14#include <asm/machdep.h>
14 15
@@ -19,6 +20,10 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
19 return -ENOSYS; 20 return -ENOSYS;
20 } 21 }
21 22
23 /* PowerPC doesn't support multiple MSI yet */
24 if (type == PCI_CAP_ID_MSI && nvec > 1)
25 return 1;
26
22 if (ppc_md.msi_check_device) { 27 if (ppc_md.msi_check_device) {
23 pr_debug("msi: Using platform check routine.\n"); 28 pr_debug("msi: Using platform check routine.\n");
24 return ppc_md.msi_check_device(dev, nvec, type); 29 return ppc_md.msi_check_device(dev, nvec, type);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 0f4181272311..9c69e7e145c5 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -38,6 +38,7 @@
38#include <asm/eeh.h> 38#include <asm/eeh.h>
39 39
40static DEFINE_SPINLOCK(hose_spinlock); 40static DEFINE_SPINLOCK(hose_spinlock);
41LIST_HEAD(hose_list);
41 42
42/* XXX kill that some day ... */ 43/* XXX kill that some day ... */
43static int global_phb_number; /* Global phb counter */ 44static int global_phb_number; /* Global phb counter */
@@ -49,7 +50,7 @@ resource_size_t isa_mem_base;
49unsigned int ppc_pci_flags = 0; 50unsigned int ppc_pci_flags = 0;
50 51
51 52
52static struct dma_mapping_ops *pci_dma_ops; 53static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops;
53 54
54void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) 55void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
55{ 56{
@@ -113,19 +114,24 @@ void pcibios_free_controller(struct pci_controller *phb)
113 kfree(phb); 114 kfree(phb);
114} 115}
115 116
117static resource_size_t pcibios_io_size(const struct pci_controller *hose)
118{
119#ifdef CONFIG_PPC64
120 return hose->pci_io_size;
121#else
122 return hose->io_resource.end - hose->io_resource.start + 1;
123#endif
124}
125
116int pcibios_vaddr_is_ioport(void __iomem *address) 126int pcibios_vaddr_is_ioport(void __iomem *address)
117{ 127{
118 int ret = 0; 128 int ret = 0;
119 struct pci_controller *hose; 129 struct pci_controller *hose;
120 unsigned long size; 130 resource_size_t size;
121 131
122 spin_lock(&hose_spinlock); 132 spin_lock(&hose_spinlock);
123 list_for_each_entry(hose, &hose_list, list_node) { 133 list_for_each_entry(hose, &hose_list, list_node) {
124#ifdef CONFIG_PPC64 134 size = pcibios_io_size(hose);
125 size = hose->pci_io_size;
126#else
127 size = hose->io_resource.end - hose->io_resource.start + 1;
128#endif
129 if (address >= hose->io_base_virt && 135 if (address >= hose->io_base_virt &&
130 address < (hose->io_base_virt + size)) { 136 address < (hose->io_base_virt + size)) {
131 ret = 1; 137 ret = 1;
@@ -136,6 +142,29 @@ int pcibios_vaddr_is_ioport(void __iomem *address)
136 return ret; 142 return ret;
137} 143}
138 144
145unsigned long pci_address_to_pio(phys_addr_t address)
146{
147 struct pci_controller *hose;
148 resource_size_t size;
149 unsigned long ret = ~0;
150
151 spin_lock(&hose_spinlock);
152 list_for_each_entry(hose, &hose_list, list_node) {
153 size = pcibios_io_size(hose);
154 if (address >= hose->io_base_phys &&
155 address < (hose->io_base_phys + size)) {
156 unsigned long base =
157 (unsigned long)hose->io_base_virt - _IO_BASE;
158 ret = base + (address - hose->io_base_phys);
159 break;
160 }
161 }
162 spin_unlock(&hose_spinlock);
163
164 return ret;
165}
166EXPORT_SYMBOL_GPL(pci_address_to_pio);
167
139/* 168/*
140 * Return the domain number for this bus. 169 * Return the domain number for this bus.
141 */ 170 */
@@ -1453,7 +1482,7 @@ void __init pcibios_resource_survey(void)
1453 * we proceed to assigning things that were left unassigned 1482 * we proceed to assigning things that were left unassigned
1454 */ 1483 */
1455 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { 1484 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
1456 pr_debug("PCI: Assigning unassigned resouces...\n"); 1485 pr_debug("PCI: Assigning unassigned resources...\n");
1457 pci_assign_unassigned_resources(); 1486 pci_assign_unassigned_resources();
1458 } 1487 }
1459 1488
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 132cd80afa21..d473634e39e3 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -20,6 +20,7 @@
20#include <asm/prom.h> 20#include <asm/prom.h>
21#include <asm/sections.h> 21#include <asm/sections.h>
22#include <asm/pci-bridge.h> 22#include <asm/pci-bridge.h>
23#include <asm/ppc-pci.h>
23#include <asm/byteorder.h> 24#include <asm/byteorder.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/machdep.h> 26#include <asm/machdep.h>
@@ -43,8 +44,6 @@ static u8* pci_to_OF_bus_map;
43 */ 44 */
44static int pci_assign_all_buses; 45static int pci_assign_all_buses;
45 46
46LIST_HEAD(hose_list);
47
48static int pci_bus_count; 47static int pci_bus_count;
49 48
50/* This will remain NULL for now, until isa-bridge.c is made common 49/* This will remain NULL for now, until isa-bridge.c is made common
@@ -219,16 +218,23 @@ scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void
219static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, 218static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
220 unsigned int devfn) 219 unsigned int devfn)
221{ 220{
222 struct device_node *np; 221 struct device_node *np, *cnp;
223 const u32 *reg; 222 const u32 *reg;
224 unsigned int psize; 223 unsigned int psize;
225 224
226 for_each_child_of_node(parent, np) { 225 for_each_child_of_node(parent, np) {
227 reg = of_get_property(np, "reg", &psize); 226 reg = of_get_property(np, "reg", &psize);
228 if (reg == NULL || psize < 4) 227 if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
229 continue;
230 if (((reg[0] >> 8) & 0xff) == devfn)
231 return np; 228 return np;
229
230 /* Note: some OFs create a parent node "multifunc-device" as
231 * a fake root for all functions of a multi-function device,
232 * we go down them as well. */
233 if (!strcmp(np->name, "multifunc-device")) {
234 cnp = scan_OF_for_pci_dev(np, devfn);
235 if (cnp)
236 return cnp;
237 }
232 } 238 }
233 return NULL; 239 return NULL;
234} 240}
@@ -491,24 +497,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
491 return result; 497 return result;
492} 498}
493 499
494unsigned long pci_address_to_pio(phys_addr_t address)
495{
496 struct pci_controller *hose, *tmp;
497
498 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
499 unsigned int size = hose->io_resource.end -
500 hose->io_resource.start + 1;
501 if (address >= hose->io_base_phys &&
502 address < (hose->io_base_phys + size)) {
503 unsigned long base =
504 (unsigned long)hose->io_base_virt - _IO_BASE;
505 return base + (address - hose->io_base_phys);
506 }
507 }
508 return (unsigned int)-1;
509}
510EXPORT_SYMBOL(pci_address_to_pio);
511
512/* 500/*
513 * Null PCI config access functions, for the case when we can't 501 * Null PCI config access functions, for the case when we can't
514 * find a hose. 502 * find a hose.
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ea8eda8c87cf..be574fc0d92f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,8 +43,6 @@ unsigned long pci_probe_only = 1;
43unsigned long pci_io_base = ISA_IO_BASE; 43unsigned long pci_io_base = ISA_IO_BASE;
44EXPORT_SYMBOL(pci_io_base); 44EXPORT_SYMBOL(pci_io_base);
45 45
46LIST_HEAD(hose_list);
47
48static void fixup_broken_pcnet32(struct pci_dev* dev) 46static void fixup_broken_pcnet32(struct pci_dev* dev)
49{ 47{
50 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 48 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
@@ -524,23 +522,6 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
524} 522}
525EXPORT_SYMBOL_GPL(pcibios_map_io_space); 523EXPORT_SYMBOL_GPL(pcibios_map_io_space);
526 524
527unsigned long pci_address_to_pio(phys_addr_t address)
528{
529 struct pci_controller *hose, *tmp;
530
531 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
532 if (address >= hose->io_base_phys &&
533 address < (hose->io_base_phys + hose->pci_io_size)) {
534 unsigned long base =
535 (unsigned long)hose->io_base_virt - _IO_BASE;
536 return base + (address - hose->io_base_phys);
537 }
538 }
539 return (unsigned int)-1;
540}
541EXPORT_SYMBOL_GPL(pci_address_to_pio);
542
543
544#define IOBASE_BRIDGE_NUMBER 0 525#define IOBASE_BRIDGE_NUMBER 0
545#define IOBASE_MEMORY 1 526#define IOBASE_MEMORY 1
546#define IOBASE_IO 2 527#define IOBASE_IO 2
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index fb7049c054c0..7b44a33f03c2 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -33,7 +33,10 @@
33#include <linux/mqueue.h> 33#include <linux/mqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/utsname.h> 35#include <linux/utsname.h>
36#include <linux/ftrace.h>
36#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/personality.h>
39#include <linux/random.h>
37 40
38#include <asm/pgtable.h> 41#include <asm/pgtable.h>
39#include <asm/uaccess.h> 42#include <asm/uaccess.h>
@@ -595,7 +598,7 @@ void prepare_to_copy(struct task_struct *tsk)
595/* 598/*
596 * Copy a thread.. 599 * Copy a thread..
597 */ 600 */
598int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, 601int copy_thread(unsigned long clone_flags, unsigned long usp,
599 unsigned long unused, struct task_struct *p, 602 unsigned long unused, struct task_struct *p,
600 struct pt_regs *regs) 603 struct pt_regs *regs)
601{ 604{
@@ -1008,6 +1011,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1008 unsigned long sp, ip, lr, newsp; 1011 unsigned long sp, ip, lr, newsp;
1009 int count = 0; 1012 int count = 0;
1010 int firstframe = 1; 1013 int firstframe = 1;
1014#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1015 int curr_frame = current->curr_ret_stack;
1016 extern void return_to_handler(void);
1017 unsigned long addr = (unsigned long)return_to_handler;
1018#ifdef CONFIG_PPC64
1019 addr = *(unsigned long*)addr;
1020#endif
1021#endif
1011 1022
1012 sp = (unsigned long) stack; 1023 sp = (unsigned long) stack;
1013 if (tsk == NULL) 1024 if (tsk == NULL)
@@ -1030,6 +1041,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1030 ip = stack[STACK_FRAME_LR_SAVE]; 1041 ip = stack[STACK_FRAME_LR_SAVE];
1031 if (!firstframe || ip != lr) { 1042 if (!firstframe || ip != lr) {
1032 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); 1043 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
1044#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1045 if (ip == addr && curr_frame >= 0) {
1046 printk(" (%pS)",
1047 (void *)current->ret_stack[curr_frame].ret);
1048 curr_frame--;
1049 }
1050#endif
1033 if (firstframe) 1051 if (firstframe)
1034 printk(" (unreliable)"); 1052 printk(" (unreliable)");
1035 printk("\n"); 1053 printk("\n");
@@ -1122,3 +1140,43 @@ void thread_info_cache_init(void)
1122} 1140}
1123 1141
1124#endif /* THREAD_SHIFT < PAGE_SHIFT */ 1142#endif /* THREAD_SHIFT < PAGE_SHIFT */
1143
1144unsigned long arch_align_stack(unsigned long sp)
1145{
1146 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1147 sp -= get_random_int() & ~PAGE_MASK;
1148 return sp & ~0xf;
1149}
1150
1151static inline unsigned long brk_rnd(void)
1152{
1153 unsigned long rnd = 0;
1154
1155 /* 8MB for 32bit, 1GB for 64bit */
1156 if (is_32bit_task())
1157 rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
1158 else
1159 rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
1160
1161 return rnd << PAGE_SHIFT;
1162}
1163
1164unsigned long arch_randomize_brk(struct mm_struct *mm)
1165{
1166 unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
1167
1168 if (ret < mm->brk)
1169 return mm->brk;
1170
1171 return ret;
1172}
1173
1174unsigned long randomize_et_dyn(unsigned long base)
1175{
1176 unsigned long ret = PAGE_ALIGN(base + brk_rnd());
1177
1178 if (ret < base)
1179 return base;
1180
1181 return ret;
1182}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f00f83109ab3..5ec6a9e23933 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1075,11 +1075,6 @@ static void __init early_reserve_mem(void)
1075 DBG("reserving: %llx -> %llx\n", base, size); 1075 DBG("reserving: %llx -> %llx\n", base, size);
1076 lmb_reserve(base, size); 1076 lmb_reserve(base, size);
1077 } 1077 }
1078
1079#if 0
1080 DBG("memory reserved, lmbs :\n");
1081 lmb_dump_all();
1082#endif
1083} 1078}
1084 1079
1085#ifdef CONFIG_PHYP_DUMP 1080#ifdef CONFIG_PHYP_DUMP
@@ -1221,6 +1216,7 @@ void __init early_init_devtree(void *params)
1221 lmb_enforce_memory_limit(limit); 1216 lmb_enforce_memory_limit(limit);
1222 1217
1223 lmb_analyze(); 1218 lmb_analyze();
1219 lmb_dump_all();
1224 1220
1225 DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); 1221 DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
1226 1222
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7f1b33d5e30d..2e026c0407d4 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2283,6 +2283,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2283 */ 2283 */
2284 prom_init_stdout(); 2284 prom_init_stdout();
2285 2285
2286 prom_printf("Preparing to boot %s", RELOC(linux_banner));
2287
2286 /* 2288 /*
2287 * Get default machine type. At this point, we do not differentiate 2289 * Get default machine type. At this point, we do not differentiate
2288 * between pSeries SMP and pSeries LPAR 2290 * between pSeries SMP and pSeries LPAR
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index ea3a2ec03ffa..1ac136b128f0 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
20_end enter_prom memcpy memset reloc_offset __secondary_hold 20_end enter_prom memcpy memset reloc_offset __secondary_hold
21__secondary_hold_acknowledge __secondary_hold_spinloop __start 21__secondary_hold_acknowledge __secondary_hold_spinloop __start
22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
23reloc_got2 kernstart_addr memstart_addr" 23reloc_got2 kernstart_addr memstart_addr linux_banner"
24 24
25NM="$1" 25NM="$1"
26OBJ="$2" 26OBJ="$2"
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index fdfe14c4bdef..ee4c7609b649 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL(rtas);
46 46
47struct rtas_suspend_me_data { 47struct rtas_suspend_me_data {
48 atomic_t working; /* number of cpus accessing this struct */ 48 atomic_t working; /* number of cpus accessing this struct */
49 atomic_t done;
49 int token; /* ibm,suspend-me */ 50 int token; /* ibm,suspend-me */
50 int error; 51 int error;
51 struct completion *complete; /* wait on this until working == 0 */ 52 struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
689#ifdef CONFIG_PPC_PSERIES 690#ifdef CONFIG_PPC_PSERIES
690static void rtas_percpu_suspend_me(void *info) 691static void rtas_percpu_suspend_me(void *info)
691{ 692{
692 long rc; 693 long rc = H_SUCCESS;
693 unsigned long msr_save; 694 unsigned long msr_save;
694 int cpu; 695 int cpu;
695 struct rtas_suspend_me_data *data = 696 struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void *info)
701 msr_save = mfmsr(); 702 msr_save = mfmsr();
702 mtmsr(msr_save & ~(MSR_EE)); 703 mtmsr(msr_save & ~(MSR_EE));
703 704
704 rc = plpar_hcall_norets(H_JOIN); 705 while (rc == H_SUCCESS && !atomic_read(&data->done))
706 rc = plpar_hcall_norets(H_JOIN);
705 707
706 mtmsr(msr_save); 708 mtmsr(msr_save);
707 709
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void *info)
724 smp_processor_id(), rc); 726 smp_processor_id(), rc);
725 data->error = rc; 727 data->error = rc;
726 } 728 }
729
730 atomic_set(&data->done, 1);
731
727 /* This cpu did the suspend or got an error; in either case, 732 /* This cpu did the suspend or got an error; in either case,
728 * we need to prod all other other cpus out of join state. 733 * we need to prod all other other cpus out of join state.
729 * Extra prods are harmless. 734 * Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
766 } 771 }
767 772
768 atomic_set(&data.working, 0); 773 atomic_set(&data.working, 0);
774 atomic_set(&data.done, 0);
769 data.token = rtas_token("ibm,suspend-me"); 775 data.token = rtas_token("ibm,suspend-me");
770 data.error = 0; 776 data.error = 0;
771 data.complete = &done; 777 data.complete = &done;
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 149cb112cd1a..13011a96a977 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -669,7 +669,6 @@ static void remove_flash_pde(struct proc_dir_entry *dp)
669{ 669{
670 if (dp) { 670 if (dp) {
671 kfree(dp->data); 671 kfree(dp->data);
672 dp->owner = NULL;
673 remove_proc_entry(dp->name, dp->parent); 672 remove_proc_entry(dp->name, dp->parent);
674 } 673 }
675} 674}
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 705fc4bf3800..9774f9fed96e 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -35,6 +35,8 @@
35#include <linux/debugfs.h> 35#include <linux/debugfs.h>
36#include <linux/percpu.h> 36#include <linux/percpu.h>
37#include <linux/lmb.h> 37#include <linux/lmb.h>
38#include <linux/of_platform.h>
39#include <linux/platform_device.h>
38#include <asm/io.h> 40#include <asm/io.h>
39#include <asm/prom.h> 41#include <asm/prom.h>
40#include <asm/processor.h> 42#include <asm/processor.h>
@@ -669,3 +671,37 @@ static int powerpc_debugfs_init(void)
669} 671}
670arch_initcall(powerpc_debugfs_init); 672arch_initcall(powerpc_debugfs_init);
671#endif 673#endif
674
675static int ppc_dflt_bus_notify(struct notifier_block *nb,
676 unsigned long action, void *data)
677{
678 struct device *dev = data;
679
680 /* We are only intereted in device addition */
681 if (action != BUS_NOTIFY_ADD_DEVICE)
682 return 0;
683
684 set_dma_ops(dev, &dma_direct_ops);
685
686 return NOTIFY_DONE;
687}
688
689static struct notifier_block ppc_dflt_plat_bus_notifier = {
690 .notifier_call = ppc_dflt_bus_notify,
691 .priority = INT_MAX,
692};
693
694static struct notifier_block ppc_dflt_of_bus_notifier = {
695 .notifier_call = ppc_dflt_bus_notify,
696 .priority = INT_MAX,
697};
698
699static int __init setup_bus_notifier(void)
700{
701 bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier);
702 bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier);
703
704 return 0;
705}
706
707arch_initcall(setup_bus_notifier);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2d34196bba8c..c410c606955d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -202,8 +202,6 @@ void __init early_setup(unsigned long dt_ptr)
202 202
203 /* Fix up paca fields required for the boot cpu */ 203 /* Fix up paca fields required for the boot cpu */
204 get_paca()->cpu_start = 1; 204 get_paca()->cpu_start = 1;
205 get_paca()->stab_real = __pa((u64)&initial_stab);
206 get_paca()->stab_addr = (u64)&initial_stab;
207 205
208 /* Probe the machine type */ 206 /* Probe the machine type */
209 probe_machine(); 207 probe_machine();
@@ -212,20 +210,8 @@ void __init early_setup(unsigned long dt_ptr)
212 210
213 DBG("Found, Initializing memory management...\n"); 211 DBG("Found, Initializing memory management...\n");
214 212
215 /* 213 /* Initialize the hash table or TLB handling */
216 * Initialize the MMU Hash table and create the linear mapping 214 early_init_mmu();
217 * of memory. Has to be done before stab/slb initialization as
218 * this is currently where the page size encoding is obtained
219 */
220 htab_initialize();
221
222 /*
223 * Initialize stab / SLB management except on iSeries
224 */
225 if (cpu_has_feature(CPU_FTR_SLB))
226 slb_initialize();
227 else if (!firmware_has_feature(FW_FEATURE_ISERIES))
228 stab_initialize(get_paca()->stab_real);
229 215
230 DBG(" <- early_setup()\n"); 216 DBG(" <- early_setup()\n");
231} 217}
@@ -233,22 +219,11 @@ void __init early_setup(unsigned long dt_ptr)
233#ifdef CONFIG_SMP 219#ifdef CONFIG_SMP
234void early_setup_secondary(void) 220void early_setup_secondary(void)
235{ 221{
236 struct paca_struct *lpaca = get_paca();
237
238 /* Mark interrupts enabled in PACA */ 222 /* Mark interrupts enabled in PACA */
239 lpaca->soft_enabled = 0; 223 get_paca()->soft_enabled = 0;
240 224
241 /* Initialize hash table for that CPU */ 225 /* Initialize the hash table or TLB handling */
242 htab_initialize_secondary(); 226 early_init_mmu_secondary();
243
244 /* Initialize STAB/SLB. We use a virtual address as it works
245 * in real mode on pSeries and we want a virutal address on
246 * iSeries anyway
247 */
248 if (cpu_has_feature(CPU_FTR_SLB))
249 slb_initialize();
250 else
251 stab_initialize(lpaca->stab_addr);
252} 227}
253 228
254#endif /* CONFIG_SMP */ 229#endif /* CONFIG_SMP */
@@ -578,13 +553,6 @@ void ppc64_boot_msg(unsigned int src, const char *msg)
578 printk("[boot]%04x %s\n", src, msg); 553 printk("[boot]%04x %s\n", src, msg);
579} 554}
580 555
581/* Print a termination message (print only -- does not stop the kernel) */
582void ppc64_terminate_msg(unsigned int src, const char *msg)
583{
584 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
585 printk("[terminate]%04x %s\n", src, msg);
586}
587
588void cpu_die(void) 556void cpu_die(void)
589{ 557{
590 if (ppc_md.cpu_die) 558 if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a54405ebd7b0..00b5078da9a3 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -26,12 +26,12 @@ int show_unhandled_signals = 0;
26 * Allocate space for the signal frame 26 * Allocate space for the signal frame
27 */ 27 */
28void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 28void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
29 size_t frame_size) 29 size_t frame_size, int is_32)
30{ 30{
31 unsigned long oldsp, newsp; 31 unsigned long oldsp, newsp;
32 32
33 /* Default to using normal stack */ 33 /* Default to using normal stack */
34 oldsp = regs->gpr[1]; 34 oldsp = get_clean_sp(regs, is_32);
35 35
36 /* Check for alt stack */ 36 /* Check for alt stack */
37 if ((ka->sa.sa_flags & SA_ONSTACK) && 37 if ((ka->sa.sa_flags & SA_ONSTACK) &&
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index b427bf8e1d8f..6c0ddfc0603e 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -15,7 +15,7 @@
15extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags); 15extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
16 16
17extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 17extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
18 size_t frame_size); 18 size_t frame_size, int is_32);
19extern void restore_sigmask(sigset_t *set); 19extern void restore_sigmask(sigset_t *set);
20 20
21extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, 21extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
@@ -39,22 +39,12 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task,
39 39
40#ifdef CONFIG_PPC64 40#ifdef CONFIG_PPC64
41 41
42static inline int is_32bit_task(void)
43{
44 return test_thread_flag(TIF_32BIT);
45}
46
47extern int handle_rt_signal64(int signr, struct k_sigaction *ka, 42extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
48 siginfo_t *info, sigset_t *set, 43 siginfo_t *info, sigset_t *set,
49 struct pt_regs *regs); 44 struct pt_regs *regs);
50 45
51#else /* CONFIG_PPC64 */ 46#else /* CONFIG_PPC64 */
52 47
53static inline int is_32bit_task(void)
54{
55 return 1;
56}
57
58static inline int handle_rt_signal64(int signr, struct k_sigaction *ka, 48static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
59 siginfo_t *info, sigset_t *set, 49 siginfo_t *info, sigset_t *set,
60 struct pt_regs *regs) 50 struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index b13abf305996..d670429a1608 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
836 836
837 /* Set up Signal Frame */ 837 /* Set up Signal Frame */
838 /* Put a Real Time Context onto stack */ 838 /* Put a Real Time Context onto stack */
839 rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf)); 839 rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1);
840 addr = rt_sf; 840 addr = rt_sf;
841 if (unlikely(rt_sf == NULL)) 841 if (unlikely(rt_sf == NULL))
842 goto badframe; 842 goto badframe;
@@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1182 unsigned long newsp = 0; 1182 unsigned long newsp = 0;
1183 1183
1184 /* Set up Signal Frame */ 1184 /* Set up Signal Frame */
1185 frame = get_sigframe(ka, regs, sizeof(*frame)); 1185 frame = get_sigframe(ka, regs, sizeof(*frame), 1);
1186 if (unlikely(frame == NULL)) 1186 if (unlikely(frame == NULL))
1187 goto badframe; 1187 goto badframe;
1188 sc = (struct sigcontext __user *) &frame->sctx; 1188 sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index e132891d3cea..2fe6fc64b614 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
402 unsigned long newsp = 0; 402 unsigned long newsp = 0;
403 long err = 0; 403 long err = 0;
404 404
405 frame = get_sigframe(ka, regs, sizeof(*frame)); 405 frame = get_sigframe(ka, regs, sizeof(*frame), 0);
406 if (unlikely(frame == NULL)) 406 if (unlikely(frame == NULL))
407 goto badframe; 407 goto badframe;
408 408
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 4a2ee08af6a7..f41aec85aa49 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -134,44 +134,23 @@ void ppc_enable_pmcs(void)
134} 134}
135EXPORT_SYMBOL(ppc_enable_pmcs); 135EXPORT_SYMBOL(ppc_enable_pmcs);
136 136
137#if defined(CONFIG_6xx) || defined(CONFIG_PPC64)
138/* XXX convert to rusty's on_one_cpu */
139static unsigned long run_on_cpu(unsigned long cpu,
140 unsigned long (*func)(unsigned long),
141 unsigned long arg)
142{
143 cpumask_t old_affinity = current->cpus_allowed;
144 unsigned long ret;
145
146 /* should return -EINVAL to userspace */
147 if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
148 return 0;
149
150 ret = func(arg);
151
152 set_cpus_allowed(current, old_affinity);
153
154 return ret;
155}
156#endif
157
158#define SYSFS_PMCSETUP(NAME, ADDRESS) \ 137#define SYSFS_PMCSETUP(NAME, ADDRESS) \
159static unsigned long read_##NAME(unsigned long junk) \ 138static void read_##NAME(void *val) \
160{ \ 139{ \
161 return mfspr(ADDRESS); \ 140 *(unsigned long *)val = mfspr(ADDRESS); \
162} \ 141} \
163static unsigned long write_##NAME(unsigned long val) \ 142static void write_##NAME(void *val) \
164{ \ 143{ \
165 ppc_enable_pmcs(); \ 144 ppc_enable_pmcs(); \
166 mtspr(ADDRESS, val); \ 145 mtspr(ADDRESS, *(unsigned long *)val); \
167 return 0; \
168} \ 146} \
169static ssize_t show_##NAME(struct sys_device *dev, \ 147static ssize_t show_##NAME(struct sys_device *dev, \
170 struct sysdev_attribute *attr, \ 148 struct sysdev_attribute *attr, \
171 char *buf) \ 149 char *buf) \
172{ \ 150{ \
173 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 151 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
174 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ 152 unsigned long val; \
153 smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \
175 return sprintf(buf, "%lx\n", val); \ 154 return sprintf(buf, "%lx\n", val); \
176} \ 155} \
177static ssize_t __used \ 156static ssize_t __used \
@@ -183,7 +162,7 @@ static ssize_t __used \
183 int ret = sscanf(buf, "%lx", &val); \ 162 int ret = sscanf(buf, "%lx", &val); \
184 if (ret != 1) \ 163 if (ret != 1) \
185 return -EINVAL; \ 164 return -EINVAL; \
186 run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ 165 smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \
187 return count; \ 166 return count; \
188} 167}
189 168
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c9564031a2a9..926ea864e34f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1127,3 +1127,19 @@ void div128_by_32(u64 dividend_high, u64 dividend_low,
1127 dr->result_low = ((u64)y << 32) + z; 1127 dr->result_low = ((u64)y << 32) + z;
1128 1128
1129} 1129}
1130
1131static int __init rtc_init(void)
1132{
1133 struct platform_device *pdev;
1134
1135 if (!ppc_md.get_rtc_time)
1136 return -ENODEV;
1137
1138 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
1139 if (IS_ERR(pdev))
1140 return PTR_ERR(pdev);
1141
1142 return 0;
1143}
1144
1145module_init(rtc_init);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 5457e9575685..678fbff0d206 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -52,6 +52,10 @@
52#include <asm/processor.h> 52#include <asm/processor.h>
53#endif 53#endif
54#include <asm/kexec.h> 54#include <asm/kexec.h>
55#include <asm/ppc-opcode.h>
56#ifdef CONFIG_FSL_BOOKE
57#include <asm/dbell.h>
58#endif
55 59
56#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 60#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
57int (*__debugger)(struct pt_regs *regs); 61int (*__debugger)(struct pt_regs *regs);
@@ -637,29 +641,6 @@ static void parse_fpe(struct pt_regs *regs)
637 * bits is faster and easier. 641 * bits is faster and easier.
638 * 642 *
639 */ 643 */
640#define INST_MFSPR_PVR 0x7c1f42a6
641#define INST_MFSPR_PVR_MASK 0xfc1fffff
642
643#define INST_DCBA 0x7c0005ec
644#define INST_DCBA_MASK 0xfc0007fe
645
646#define INST_MCRXR 0x7c000400
647#define INST_MCRXR_MASK 0xfc0007fe
648
649#define INST_STRING 0x7c00042a
650#define INST_STRING_MASK 0xfc0007fe
651#define INST_STRING_GEN_MASK 0xfc00067e
652#define INST_LSWI 0x7c0004aa
653#define INST_LSWX 0x7c00042a
654#define INST_STSWI 0x7c0005aa
655#define INST_STSWX 0x7c00052a
656
657#define INST_POPCNTB 0x7c0000f4
658#define INST_POPCNTB_MASK 0xfc0007fe
659
660#define INST_ISEL 0x7c00001e
661#define INST_ISEL_MASK 0xfc00003e
662
663static int emulate_string_inst(struct pt_regs *regs, u32 instword) 644static int emulate_string_inst(struct pt_regs *regs, u32 instword)
664{ 645{
665 u8 rT = (instword >> 21) & 0x1f; 646 u8 rT = (instword >> 21) & 0x1f;
@@ -670,20 +651,20 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
670 int pos = 0; 651 int pos = 0;
671 652
672 /* Early out if we are an invalid form of lswx */ 653 /* Early out if we are an invalid form of lswx */
673 if ((instword & INST_STRING_MASK) == INST_LSWX) 654 if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX)
674 if ((rT == rA) || (rT == NB_RB)) 655 if ((rT == rA) || (rT == NB_RB))
675 return -EINVAL; 656 return -EINVAL;
676 657
677 EA = (rA == 0) ? 0 : regs->gpr[rA]; 658 EA = (rA == 0) ? 0 : regs->gpr[rA];
678 659
679 switch (instword & INST_STRING_MASK) { 660 switch (instword & PPC_INST_STRING_MASK) {
680 case INST_LSWX: 661 case PPC_INST_LSWX:
681 case INST_STSWX: 662 case PPC_INST_STSWX:
682 EA += NB_RB; 663 EA += NB_RB;
683 num_bytes = regs->xer & 0x7f; 664 num_bytes = regs->xer & 0x7f;
684 break; 665 break;
685 case INST_LSWI: 666 case PPC_INST_LSWI:
686 case INST_STSWI: 667 case PPC_INST_STSWI:
687 num_bytes = (NB_RB == 0) ? 32 : NB_RB; 668 num_bytes = (NB_RB == 0) ? 32 : NB_RB;
688 break; 669 break;
689 default: 670 default:
@@ -695,9 +676,9 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
695 u8 val; 676 u8 val;
696 u32 shift = 8 * (3 - (pos & 0x3)); 677 u32 shift = 8 * (3 - (pos & 0x3));
697 678
698 switch ((instword & INST_STRING_MASK)) { 679 switch ((instword & PPC_INST_STRING_MASK)) {
699 case INST_LSWX: 680 case PPC_INST_LSWX:
700 case INST_LSWI: 681 case PPC_INST_LSWI:
701 if (get_user(val, (u8 __user *)EA)) 682 if (get_user(val, (u8 __user *)EA))
702 return -EFAULT; 683 return -EFAULT;
703 /* first time updating this reg, 684 /* first time updating this reg,
@@ -706,8 +687,8 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
706 regs->gpr[rT] = 0; 687 regs->gpr[rT] = 0;
707 regs->gpr[rT] |= val << shift; 688 regs->gpr[rT] |= val << shift;
708 break; 689 break;
709 case INST_STSWI: 690 case PPC_INST_STSWI:
710 case INST_STSWX: 691 case PPC_INST_STSWX:
711 val = regs->gpr[rT] >> shift; 692 val = regs->gpr[rT] >> shift;
712 if (put_user(val, (u8 __user *)EA)) 693 if (put_user(val, (u8 __user *)EA))
713 return -EFAULT; 694 return -EFAULT;
@@ -775,18 +756,18 @@ static int emulate_instruction(struct pt_regs *regs)
775 return -EFAULT; 756 return -EFAULT;
776 757
777 /* Emulate the mfspr rD, PVR. */ 758 /* Emulate the mfspr rD, PVR. */
778 if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { 759 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
779 rd = (instword >> 21) & 0x1f; 760 rd = (instword >> 21) & 0x1f;
780 regs->gpr[rd] = mfspr(SPRN_PVR); 761 regs->gpr[rd] = mfspr(SPRN_PVR);
781 return 0; 762 return 0;
782 } 763 }
783 764
784 /* Emulating the dcba insn is just a no-op. */ 765 /* Emulating the dcba insn is just a no-op. */
785 if ((instword & INST_DCBA_MASK) == INST_DCBA) 766 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
786 return 0; 767 return 0;
787 768
788 /* Emulate the mcrxr insn. */ 769 /* Emulate the mcrxr insn. */
789 if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { 770 if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
790 int shift = (instword >> 21) & 0x1c; 771 int shift = (instword >> 21) & 0x1c;
791 unsigned long msk = 0xf0000000UL >> shift; 772 unsigned long msk = 0xf0000000UL >> shift;
792 773
@@ -796,16 +777,16 @@ static int emulate_instruction(struct pt_regs *regs)
796 } 777 }
797 778
798 /* Emulate load/store string insn. */ 779 /* Emulate load/store string insn. */
799 if ((instword & INST_STRING_GEN_MASK) == INST_STRING) 780 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
800 return emulate_string_inst(regs, instword); 781 return emulate_string_inst(regs, instword);
801 782
802 /* Emulate the popcntb (Population Count Bytes) instruction. */ 783 /* Emulate the popcntb (Population Count Bytes) instruction. */
803 if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) { 784 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
804 return emulate_popcntb_inst(regs, instword); 785 return emulate_popcntb_inst(regs, instword);
805 } 786 }
806 787
807 /* Emulate isel (Integer Select) instruction */ 788 /* Emulate isel (Integer Select) instruction */
808 if ((instword & INST_ISEL_MASK) == INST_ISEL) { 789 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
809 return emulate_isel(regs, instword); 790 return emulate_isel(regs, instword);
810 } 791 }
811 792
@@ -1144,6 +1125,24 @@ void vsx_assist_exception(struct pt_regs *regs)
1144#endif /* CONFIG_VSX */ 1125#endif /* CONFIG_VSX */
1145 1126
1146#ifdef CONFIG_FSL_BOOKE 1127#ifdef CONFIG_FSL_BOOKE
1128
1129void doorbell_exception(struct pt_regs *regs)
1130{
1131#ifdef CONFIG_SMP
1132 int cpu = smp_processor_id();
1133 int msg;
1134
1135 if (num_online_cpus() < 2)
1136 return;
1137
1138 for (msg = 0; msg < 4; msg++)
1139 if (test_and_clear_bit(msg, &dbell_smp_message[cpu]))
1140 smp_message_recv(msg);
1141#else
1142 printk(KERN_WARNING "Received doorbell on non-smp system\n");
1143#endif
1144}
1145
1147void CacheLockingException(struct pt_regs *regs, unsigned long address, 1146void CacheLockingException(struct pt_regs *regs, unsigned long address,
1148 unsigned long error_code) 1147 unsigned long error_code)
1149{ 1148{
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7d6c9bb8c77f..fc9af47e2128 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -18,6 +18,7 @@
18#include <asm/udbg.h> 18#include <asm/udbg.h>
19 19
20void (*udbg_putc)(char c); 20void (*udbg_putc)(char c);
21void (*udbg_flush)(void);
21int (*udbg_getc)(void); 22int (*udbg_getc)(void);
22int (*udbg_getc_poll)(void); 23int (*udbg_getc_poll)(void);
23 24
@@ -76,6 +77,9 @@ void udbg_puts(const char *s)
76 while ((c = *s++) != '\0') 77 while ((c = *s++) != '\0')
77 udbg_putc(c); 78 udbg_putc(c);
78 } 79 }
80
81 if (udbg_flush)
82 udbg_flush();
79 } 83 }
80#if 0 84#if 0
81 else { 85 else {
@@ -98,6 +102,9 @@ int udbg_write(const char *s, int n)
98 } 102 }
99 } 103 }
100 104
105 if (udbg_flush)
106 udbg_flush();
107
101 return n - remain; 108 return n - remain;
102} 109}
103 110
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 7b7da8cfd5e8..0362a891e54e 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -48,14 +48,21 @@ struct NS16550 {
48 48
49static struct NS16550 __iomem *udbg_comport; 49static struct NS16550 __iomem *udbg_comport;
50 50
51static void udbg_550_putc(char c) 51static void udbg_550_flush(void)
52{ 52{
53 if (udbg_comport) { 53 if (udbg_comport) {
54 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) 54 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
55 /* wait for idle */; 55 /* wait for idle */;
56 out_8(&udbg_comport->thr, c); 56 }
57}
58
59static void udbg_550_putc(char c)
60{
61 if (udbg_comport) {
57 if (c == '\n') 62 if (c == '\n')
58 udbg_550_putc('\r'); 63 udbg_550_putc('\r');
64 udbg_550_flush();
65 out_8(&udbg_comport->thr, c);
59 } 66 }
60} 67}
61 68
@@ -108,6 +115,7 @@ void udbg_init_uart(void __iomem *comport, unsigned int speed,
108 /* Clear & enable FIFOs */ 115 /* Clear & enable FIFOs */
109 out_8(&udbg_comport->fcr ,0x07); 116 out_8(&udbg_comport->fcr ,0x07);
110 udbg_putc = udbg_550_putc; 117 udbg_putc = udbg_550_putc;
118 udbg_flush = udbg_550_flush;
111 udbg_getc = udbg_550_getc; 119 udbg_getc = udbg_550_getc;
112 udbg_getc_poll = udbg_550_getc_poll; 120 udbg_getc_poll = udbg_550_getc_poll;
113 } 121 }
@@ -149,14 +157,21 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
149} 157}
150 158
151#ifdef CONFIG_PPC_MAPLE 159#ifdef CONFIG_PPC_MAPLE
152void udbg_maple_real_putc(char c) 160void udbg_maple_real_flush(void)
153{ 161{
154 if (udbg_comport) { 162 if (udbg_comport) {
155 while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) 163 while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
156 /* wait for idle */; 164 /* wait for idle */;
157 real_writeb(c, &udbg_comport->thr); eieio(); 165 }
166}
167
168void udbg_maple_real_putc(char c)
169{
170 if (udbg_comport) {
158 if (c == '\n') 171 if (c == '\n')
159 udbg_maple_real_putc('\r'); 172 udbg_maple_real_putc('\r');
173 udbg_maple_real_flush();
174 real_writeb(c, &udbg_comport->thr); eieio();
160 } 175 }
161} 176}
162 177
@@ -165,20 +180,28 @@ void __init udbg_init_maple_realmode(void)
165 udbg_comport = (struct NS16550 __iomem *)0xf40003f8; 180 udbg_comport = (struct NS16550 __iomem *)0xf40003f8;
166 181
167 udbg_putc = udbg_maple_real_putc; 182 udbg_putc = udbg_maple_real_putc;
183 udbg_flush = udbg_maple_real_flush;
168 udbg_getc = NULL; 184 udbg_getc = NULL;
169 udbg_getc_poll = NULL; 185 udbg_getc_poll = NULL;
170} 186}
171#endif /* CONFIG_PPC_MAPLE */ 187#endif /* CONFIG_PPC_MAPLE */
172 188
173#ifdef CONFIG_PPC_PASEMI 189#ifdef CONFIG_PPC_PASEMI
174void udbg_pas_real_putc(char c) 190void udbg_pas_real_flush(void)
175{ 191{
176 if (udbg_comport) { 192 if (udbg_comport) {
177 while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) 193 while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
178 /* wait for idle */; 194 /* wait for idle */;
179 real_205_writeb(c, &udbg_comport->thr); eieio(); 195 }
196}
197
198void udbg_pas_real_putc(char c)
199{
200 if (udbg_comport) {
180 if (c == '\n') 201 if (c == '\n')
181 udbg_pas_real_putc('\r'); 202 udbg_pas_real_putc('\r');
203 udbg_pas_real_flush();
204 real_205_writeb(c, &udbg_comport->thr); eieio();
182 } 205 }
183} 206}
184 207
@@ -187,6 +210,7 @@ void udbg_init_pas_realmode(void)
187 udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL; 210 udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL;
188 211
189 udbg_putc = udbg_pas_real_putc; 212 udbg_putc = udbg_pas_real_putc;
213 udbg_flush = udbg_pas_real_flush;
190 udbg_getc = NULL; 214 udbg_getc = NULL;
191 udbg_getc_poll = NULL; 215 udbg_getc_poll = NULL;
192} 216}
@@ -195,14 +219,21 @@ void udbg_init_pas_realmode(void)
195#ifdef CONFIG_PPC_EARLY_DEBUG_44x 219#ifdef CONFIG_PPC_EARLY_DEBUG_44x
196#include <platforms/44x/44x.h> 220#include <platforms/44x/44x.h>
197 221
198static void udbg_44x_as1_putc(char c) 222static int udbg_44x_as1_flush(void)
199{ 223{
200 if (udbg_comport) { 224 if (udbg_comport) {
201 while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) 225 while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
202 /* wait for idle */; 226 /* wait for idle */;
203 as1_writeb(c, &udbg_comport->thr); eieio(); 227 }
228}
229
230static void udbg_44x_as1_putc(char c)
231{
232 if (udbg_comport) {
204 if (c == '\n') 233 if (c == '\n')
205 udbg_44x_as1_putc('\r'); 234 udbg_44x_as1_putc('\r');
235 udbg_44x_as1_flush();
236 as1_writeb(c, &udbg_comport->thr); eieio();
206 } 237 }
207} 238}
208 239
@@ -222,19 +253,27 @@ void __init udbg_init_44x_as1(void)
222 (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; 253 (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
223 254
224 udbg_putc = udbg_44x_as1_putc; 255 udbg_putc = udbg_44x_as1_putc;
256 udbg_flush = udbg_44x_as1_flush;
225 udbg_getc = udbg_44x_as1_getc; 257 udbg_getc = udbg_44x_as1_getc;
226} 258}
227#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ 259#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
228 260
229#ifdef CONFIG_PPC_EARLY_DEBUG_40x 261#ifdef CONFIG_PPC_EARLY_DEBUG_40x
230static void udbg_40x_real_putc(char c) 262static void udbg_40x_real_flush(void)
231{ 263{
232 if (udbg_comport) { 264 if (udbg_comport) {
233 while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) 265 while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
234 /* wait for idle */; 266 /* wait for idle */;
235 real_writeb(c, &udbg_comport->thr); eieio(); 267 }
268}
269
270static void udbg_40x_real_putc(char c)
271{
272 if (udbg_comport) {
236 if (c == '\n') 273 if (c == '\n')
237 udbg_40x_real_putc('\r'); 274 udbg_40x_real_putc('\r');
275 udbg_40x_real_flush();
276 real_writeb(c, &udbg_comport->thr); eieio();
238 } 277 }
239} 278}
240 279
@@ -254,6 +293,7 @@ void __init udbg_init_40x_realmode(void)
254 CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR; 293 CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR;
255 294
256 udbg_putc = udbg_40x_real_putc; 295 udbg_putc = udbg_40x_real_putc;
296 udbg_flush = udbg_40x_real_flush;
257 udbg_getc = udbg_40x_real_getc; 297 udbg_getc = udbg_40x_real_getc;
258 udbg_getc_poll = NULL; 298 udbg_getc_poll = NULL;
259} 299}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index d3694498f3af..819e59f6f7c7 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -482,7 +482,7 @@ static void vio_cmo_balance(struct work_struct *work)
482 cmo->excess.size = cmo->entitled - cmo->reserve.size; 482 cmo->excess.size = cmo->entitled - cmo->reserve.size;
483 cmo->excess.free = cmo->excess.size - need; 483 cmo->excess.free = cmo->excess.size - need;
484 484
485 cancel_delayed_work(container_of(work, struct delayed_work, work)); 485 cancel_delayed_work(to_delayed_work(work));
486 spin_unlock_irqrestore(&vio_cmo.lock, flags); 486 spin_unlock_irqrestore(&vio_cmo.lock, flags);
487} 487}
488 488
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 295ccc5e86b1..b9ef1644a722 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -58,6 +58,7 @@ SECTIONS
58 SCHED_TEXT 58 SCHED_TEXT
59 LOCK_TEXT 59 LOCK_TEXT
60 KPROBES_TEXT 60 KPROBES_TEXT
61 IRQENTRY_TEXT
61 62
62#ifdef CONFIG_PPC32 63#ifdef CONFIG_PPC32
63 *(.got1) 64 *(.got1)
@@ -181,14 +182,7 @@ SECTIONS
181 __initramfs_end = .; 182 __initramfs_end = .;
182 } 183 }
183#endif 184#endif
184 . = ALIGN(PAGE_SIZE); 185 PERCPU(PAGE_SIZE)
185 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
186 __per_cpu_start = .;
187 *(.data.percpu.page_aligned)
188 *(.data.percpu)
189 *(.data.percpu.shared_aligned)
190 __per_cpu_end = .;
191 }
192 186
193 . = ALIGN(8); 187 . = ALIGN(8);
194 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { 188 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {