aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-07-08 11:52:42 -0400
committerTony Luck <tony.luck@intel.com>2005-07-08 11:52:42 -0400
commit88c3cdfdde3cf87e1831265ea4246430bef34fc9 (patch)
treecaea510ffb2f81a5ea13b00ecb8a4146ad462048 /arch/ppc64/kernel
parent2b2c3750330325ae5071582b5c4dbdf1c8bc1e51 (diff)
parenta92b7b80579fe68fe229892815c750f6652eb6a9 (diff)
Auto merge with /home/aegl/GIT/linus
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r--arch/ppc64/kernel/cputable.c365
-rw-r--r--arch/ppc64/kernel/head.S10
-rw-r--r--arch/ppc64/kernel/hvconsole.c51
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c94
-rw-r--r--arch/ppc64/kernel/idle.c283
-rw-r--r--arch/ppc64/kernel/maple_setup.c3
-rw-r--r--arch/ppc64/kernel/misc.S6
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c156
-rw-r--r--arch/ppc64/kernel/pmac_setup.c5
-rw-r--r--arch/ppc64/kernel/setup.c8
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c54
-rw-r--r--arch/ppc64/kernel/sysfs.c14
-rw-r--r--arch/ppc64/kernel/vdso32/vdso32.lds.S4
13 files changed, 525 insertions, 528 deletions
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
index 1d162c7c59df..8d4c46f6f0b6 100644
--- a/arch/ppc64/kernel/cputable.c
+++ b/arch/ppc64/kernel/cputable.c
@@ -49,160 +49,219 @@ extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
49#endif 49#endif
50 50
51struct cpu_spec cpu_specs[] = { 51struct cpu_spec cpu_specs[] = {
52 { /* Power3 */ 52 { /* Power3 */
53 0xffff0000, 0x00400000, "POWER3 (630)", 53 .pvr_mask = 0xffff0000,
54 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 54 .pvr_value = 0x00400000,
55 CPU_FTR_IABR | CPU_FTR_PMC8, 55 .cpu_name = "POWER3 (630)",
56 COMMON_USER_PPC64, 56 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
57 128, 128, 57 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
58 __setup_cpu_power3, 58 CPU_FTR_PMC8,
59 COMMON_PPC64_FW 59 .cpu_user_features = COMMON_USER_PPC64,
60 }, 60 .icache_bsize = 128,
61 { /* Power3+ */ 61 .dcache_bsize = 128,
62 0xffff0000, 0x00410000, "POWER3 (630+)", 62 .cpu_setup = __setup_cpu_power3,
63 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 63 .firmware_features = COMMON_PPC64_FW,
64 CPU_FTR_IABR | CPU_FTR_PMC8, 64 },
65 COMMON_USER_PPC64, 65 { /* Power3+ */
66 128, 128, 66 .pvr_mask = 0xffff0000,
67 __setup_cpu_power3, 67 .pvr_value = 0x00410000,
68 COMMON_PPC64_FW 68 .cpu_name = "POWER3 (630+)",
69 }, 69 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
70 { /* Northstar */ 70 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
71 0xffff0000, 0x00330000, "RS64-II (northstar)", 71 CPU_FTR_PMC8,
72 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 72 .cpu_user_features = COMMON_USER_PPC64,
73 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 73 .icache_bsize = 128,
74 COMMON_USER_PPC64, 74 .dcache_bsize = 128,
75 128, 128, 75 .cpu_setup = __setup_cpu_power3,
76 __setup_cpu_power3, 76 .firmware_features = COMMON_PPC64_FW,
77 COMMON_PPC64_FW 77 },
78 }, 78 { /* Northstar */
79 { /* Pulsar */ 79 .pvr_mask = 0xffff0000,
80 0xffff0000, 0x00340000, "RS64-III (pulsar)", 80 .pvr_value = 0x00330000,
81 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 81 .cpu_name = "RS64-II (northstar)",
82 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 82 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
83 COMMON_USER_PPC64, 83 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
84 128, 128, 84 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
85 __setup_cpu_power3, 85 .cpu_user_features = COMMON_USER_PPC64,
86 COMMON_PPC64_FW 86 .icache_bsize = 128,
87 }, 87 .dcache_bsize = 128,
88 { /* I-star */ 88 .cpu_setup = __setup_cpu_power3,
89 0xffff0000, 0x00360000, "RS64-III (icestar)", 89 .firmware_features = COMMON_PPC64_FW,
90 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 90 },
91 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 91 { /* Pulsar */
92 COMMON_USER_PPC64, 92 .pvr_mask = 0xffff0000,
93 128, 128, 93 .pvr_value = 0x00340000,
94 __setup_cpu_power3, 94 .cpu_name = "RS64-III (pulsar)",
95 COMMON_PPC64_FW 95 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
96 }, 96 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
97 { /* S-star */ 97 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
98 0xffff0000, 0x00370000, "RS64-IV (sstar)", 98 .cpu_user_features = COMMON_USER_PPC64,
99 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 99 .icache_bsize = 128,
100 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 100 .dcache_bsize = 128,
101 COMMON_USER_PPC64, 101 .cpu_setup = __setup_cpu_power3,
102 128, 128, 102 .firmware_features = COMMON_PPC64_FW,
103 __setup_cpu_power3, 103 },
104 COMMON_PPC64_FW 104 { /* I-star */
105 }, 105 .pvr_mask = 0xffff0000,
106 { /* Power4 */ 106 .pvr_value = 0x00360000,
107 0xffff0000, 0x00350000, "POWER4 (gp)", 107 .cpu_name = "RS64-III (icestar)",
108 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 108 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
109 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 109 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
110 COMMON_USER_PPC64, 110 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
111 128, 128, 111 .cpu_user_features = COMMON_USER_PPC64,
112 __setup_cpu_power4, 112 .icache_bsize = 128,
113 COMMON_PPC64_FW 113 .dcache_bsize = 128,
114 }, 114 .cpu_setup = __setup_cpu_power3,
115 { /* Power4+ */ 115 .firmware_features = COMMON_PPC64_FW,
116 0xffff0000, 0x00380000, "POWER4+ (gq)", 116 },
117 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 117 { /* S-star */
118 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 118 .pvr_mask = 0xffff0000,
119 COMMON_USER_PPC64, 119 .pvr_value = 0x00370000,
120 128, 128, 120 .cpu_name = "RS64-IV (sstar)",
121 __setup_cpu_power4, 121 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
122 COMMON_PPC64_FW 122 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
123 }, 123 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
124 { /* PPC970 */ 124 .cpu_user_features = COMMON_USER_PPC64,
125 0xffff0000, 0x00390000, "PPC970", 125 .icache_bsize = 128,
126 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 126 .dcache_bsize = 128,
127 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 127 .cpu_setup = __setup_cpu_power3,
128 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 128 .firmware_features = COMMON_PPC64_FW,
129 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 129 },
130 128, 128, 130 { /* Power4 */
131 __setup_cpu_ppc970, 131 .pvr_mask = 0xffff0000,
132 COMMON_PPC64_FW 132 .pvr_value = 0x00350000,
133 }, 133 .cpu_name = "POWER4 (gp)",
134 { /* PPC970FX */ 134 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
135 0xffff0000, 0x003c0000, "PPC970FX", 135 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
136 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 136 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
137 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 137 .cpu_user_features = COMMON_USER_PPC64,
138 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 138 .icache_bsize = 128,
139 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 139 .dcache_bsize = 128,
140 128, 128, 140 .cpu_setup = __setup_cpu_power4,
141 __setup_cpu_ppc970, 141 .firmware_features = COMMON_PPC64_FW,
142 COMMON_PPC64_FW 142 },
143 }, 143 { /* Power4+ */
144 { /* Power5 */ 144 .pvr_mask = 0xffff0000,
145 0xffff0000, 0x003a0000, "POWER5 (gr)", 145 .pvr_value = 0x00380000,
146 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 146 .cpu_name = "POWER4+ (gq)",
147 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | 147 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
148 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | 148 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
149 CPU_FTR_MMCRA_SIHV, 149 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
150 COMMON_USER_PPC64, 150 .cpu_user_features = COMMON_USER_PPC64,
151 128, 128, 151 .icache_bsize = 128,
152 __setup_cpu_power4, 152 .dcache_bsize = 128,
153 COMMON_PPC64_FW 153 .cpu_setup = __setup_cpu_power4,
154 }, 154 .firmware_features = COMMON_PPC64_FW,
155 { /* Power5 */ 155 },
156 0xffff0000, 0x003b0000, "POWER5 (gs)", 156 { /* PPC970 */
157 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 157 .pvr_mask = 0xffff0000,
158 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | 158 .pvr_value = 0x00390000,
159 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | 159 .cpu_name = "PPC970",
160 CPU_FTR_MMCRA_SIHV, 160 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
161 COMMON_USER_PPC64, 161 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
162 128, 128, 162 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
163 __setup_cpu_power4, 163 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
164 COMMON_PPC64_FW 164 .cpu_user_features = COMMON_USER_PPC64 |
165 }, 165 PPC_FEATURE_HAS_ALTIVEC_COMP,
166 { /* BE DD1.x */ 166 .icache_bsize = 128,
167 0xffff0000, 0x00700000, "Broadband Engine", 167 .dcache_bsize = 128,
168 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 168 .cpu_setup = __setup_cpu_ppc970,
169 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 169 .firmware_features = COMMON_PPC64_FW,
170 CPU_FTR_SMT, 170 },
171 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 171 { /* PPC970FX */
172 128, 128, 172 .pvr_mask = 0xffff0000,
173 __setup_cpu_be, 173 .pvr_value = 0x003c0000,
174 COMMON_PPC64_FW 174 .cpu_name = "PPC970FX",
175 }, 175 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
176 { /* default match */ 176 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
177 0x00000000, 0x00000000, "POWER4 (compatible)", 177 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
178 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 178 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
179 CPU_FTR_PPCAS_ARCH_V2, 179 .cpu_user_features = COMMON_USER_PPC64 |
180 COMMON_USER_PPC64, 180 PPC_FEATURE_HAS_ALTIVEC_COMP,
181 128, 128, 181 .icache_bsize = 128,
182 __setup_cpu_power4, 182 .dcache_bsize = 128,
183 COMMON_PPC64_FW 183 .cpu_setup = __setup_cpu_ppc970,
184 } 184 .firmware_features = COMMON_PPC64_FW,
185 },
186 { /* Power5 */
187 .pvr_mask = 0xffff0000,
188 .pvr_value = 0x003a0000,
189 .cpu_name = "POWER5 (gr)",
190 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
191 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
192 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
193 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
194 CPU_FTR_MMCRA_SIHV,
195 .cpu_user_features = COMMON_USER_PPC64,
196 .icache_bsize = 128,
197 .dcache_bsize = 128,
198 .cpu_setup = __setup_cpu_power4,
199 .firmware_features = COMMON_PPC64_FW,
200 },
201 { /* Power5 */
202 .pvr_mask = 0xffff0000,
203 .pvr_value = 0x003b0000,
204 .cpu_name = "POWER5 (gs)",
205 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
206 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
207 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
208 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
209 CPU_FTR_MMCRA_SIHV,
210 .cpu_user_features = COMMON_USER_PPC64,
211 .icache_bsize = 128,
212 .dcache_bsize = 128,
213 .cpu_setup = __setup_cpu_power4,
214 .firmware_features = COMMON_PPC64_FW,
215 },
216 { /* BE DD1.x */
217 .pvr_mask = 0xffff0000,
218 .pvr_value = 0x00700000,
219 .cpu_name = "Broadband Engine",
220 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
221 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
222 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
223 CPU_FTR_SMT,
224 .cpu_user_features = COMMON_USER_PPC64 |
225 PPC_FEATURE_HAS_ALTIVEC_COMP,
226 .icache_bsize = 128,
227 .dcache_bsize = 128,
228 .cpu_setup = __setup_cpu_be,
229 .firmware_features = COMMON_PPC64_FW,
230 },
231 { /* default match */
232 .pvr_mask = 0x00000000,
233 .pvr_value = 0x00000000,
234 .cpu_name = "POWER4 (compatible)",
235 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
236 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
237 CPU_FTR_PPCAS_ARCH_V2,
238 .cpu_user_features = COMMON_USER_PPC64,
239 .icache_bsize = 128,
240 .dcache_bsize = 128,
241 .cpu_setup = __setup_cpu_power4,
242 .firmware_features = COMMON_PPC64_FW,
243 }
185}; 244};
186 245
187firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { 246firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
188 {FW_FEATURE_PFT, "hcall-pft"}, 247 {FW_FEATURE_PFT, "hcall-pft"},
189 {FW_FEATURE_TCE, "hcall-tce"}, 248 {FW_FEATURE_TCE, "hcall-tce"},
190 {FW_FEATURE_SPRG0, "hcall-sprg0"}, 249 {FW_FEATURE_SPRG0, "hcall-sprg0"},
191 {FW_FEATURE_DABR, "hcall-dabr"}, 250 {FW_FEATURE_DABR, "hcall-dabr"},
192 {FW_FEATURE_COPY, "hcall-copy"}, 251 {FW_FEATURE_COPY, "hcall-copy"},
193 {FW_FEATURE_ASR, "hcall-asr"}, 252 {FW_FEATURE_ASR, "hcall-asr"},
194 {FW_FEATURE_DEBUG, "hcall-debug"}, 253 {FW_FEATURE_DEBUG, "hcall-debug"},
195 {FW_FEATURE_PERF, "hcall-perf"}, 254 {FW_FEATURE_PERF, "hcall-perf"},
196 {FW_FEATURE_DUMP, "hcall-dump"}, 255 {FW_FEATURE_DUMP, "hcall-dump"},
197 {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, 256 {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
198 {FW_FEATURE_MIGRATE, "hcall-migrate"}, 257 {FW_FEATURE_MIGRATE, "hcall-migrate"},
199 {FW_FEATURE_PERFMON, "hcall-perfmon"}, 258 {FW_FEATURE_PERFMON, "hcall-perfmon"},
200 {FW_FEATURE_CRQ, "hcall-crq"}, 259 {FW_FEATURE_CRQ, "hcall-crq"},
201 {FW_FEATURE_VIO, "hcall-vio"}, 260 {FW_FEATURE_VIO, "hcall-vio"},
202 {FW_FEATURE_RDMA, "hcall-rdma"}, 261 {FW_FEATURE_RDMA, "hcall-rdma"},
203 {FW_FEATURE_LLAN, "hcall-lLAN"}, 262 {FW_FEATURE_LLAN, "hcall-lLAN"},
204 {FW_FEATURE_BULK, "hcall-bulk"}, 263 {FW_FEATURE_BULK, "hcall-bulk"},
205 {FW_FEATURE_XDABR, "hcall-xdabr"}, 264 {FW_FEATURE_XDABR, "hcall-xdabr"},
206 {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, 265 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
207 {FW_FEATURE_SPLPAR, "hcall-splpar"}, 266 {FW_FEATURE_SPLPAR, "hcall-splpar"},
208}; 267};
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 675c2708588f..93ebcac0d5a2 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -308,6 +308,7 @@ exception_marker:
308label##_pSeries: \ 308label##_pSeries: \
309 HMT_MEDIUM; \ 309 HMT_MEDIUM; \
310 mtspr SPRG1,r13; /* save r13 */ \ 310 mtspr SPRG1,r13; /* save r13 */ \
311 RUNLATCH_ON(r13); \
311 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 312 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
312 313
313#define STD_EXCEPTION_ISERIES(n, label, area) \ 314#define STD_EXCEPTION_ISERIES(n, label, area) \
@@ -315,6 +316,7 @@ label##_pSeries: \
315label##_iSeries: \ 316label##_iSeries: \
316 HMT_MEDIUM; \ 317 HMT_MEDIUM; \
317 mtspr SPRG1,r13; /* save r13 */ \ 318 mtspr SPRG1,r13; /* save r13 */ \
319 RUNLATCH_ON(r13); \
318 EXCEPTION_PROLOG_ISERIES_1(area); \ 320 EXCEPTION_PROLOG_ISERIES_1(area); \
319 EXCEPTION_PROLOG_ISERIES_2; \ 321 EXCEPTION_PROLOG_ISERIES_2; \
320 b label##_common 322 b label##_common
@@ -324,6 +326,7 @@ label##_iSeries: \
324label##_iSeries: \ 326label##_iSeries: \
325 HMT_MEDIUM; \ 327 HMT_MEDIUM; \
326 mtspr SPRG1,r13; /* save r13 */ \ 328 mtspr SPRG1,r13; /* save r13 */ \
329 RUNLATCH_ON(r13); \
327 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ 330 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
328 lbz r10,PACAPROCENABLED(r13); \ 331 lbz r10,PACAPROCENABLED(r13); \
329 cmpwi 0,r10,0; \ 332 cmpwi 0,r10,0; \
@@ -393,6 +396,7 @@ __start_interrupts:
393_machine_check_pSeries: 396_machine_check_pSeries:
394 HMT_MEDIUM 397 HMT_MEDIUM
395 mtspr SPRG1,r13 /* save r13 */ 398 mtspr SPRG1,r13 /* save r13 */
399 RUNLATCH_ON(r13)
396 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 400 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
397 401
398 . = 0x300 402 . = 0x300
@@ -419,6 +423,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
419data_access_slb_pSeries: 423data_access_slb_pSeries:
420 HMT_MEDIUM 424 HMT_MEDIUM
421 mtspr SPRG1,r13 425 mtspr SPRG1,r13
426 RUNLATCH_ON(r13)
422 mfspr r13,SPRG3 /* get paca address into r13 */ 427 mfspr r13,SPRG3 /* get paca address into r13 */
423 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ 428 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
424 std r10,PACA_EXSLB+EX_R10(r13) 429 std r10,PACA_EXSLB+EX_R10(r13)
@@ -439,6 +444,7 @@ data_access_slb_pSeries:
439instruction_access_slb_pSeries: 444instruction_access_slb_pSeries:
440 HMT_MEDIUM 445 HMT_MEDIUM
441 mtspr SPRG1,r13 446 mtspr SPRG1,r13
447 RUNLATCH_ON(r13)
442 mfspr r13,SPRG3 /* get paca address into r13 */ 448 mfspr r13,SPRG3 /* get paca address into r13 */
443 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ 449 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
444 std r10,PACA_EXSLB+EX_R10(r13) 450 std r10,PACA_EXSLB+EX_R10(r13)
@@ -464,6 +470,7 @@ instruction_access_slb_pSeries:
464 .globl system_call_pSeries 470 .globl system_call_pSeries
465system_call_pSeries: 471system_call_pSeries:
466 HMT_MEDIUM 472 HMT_MEDIUM
473 RUNLATCH_ON(r9)
467 mr r9,r13 474 mr r9,r13
468 mfmsr r10 475 mfmsr r10
469 mfspr r13,SPRG3 476 mfspr r13,SPRG3
@@ -707,11 +714,13 @@ fwnmi_data_area:
707system_reset_fwnmi: 714system_reset_fwnmi:
708 HMT_MEDIUM 715 HMT_MEDIUM
709 mtspr SPRG1,r13 /* save r13 */ 716 mtspr SPRG1,r13 /* save r13 */
717 RUNLATCH_ON(r13)
710 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 718 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
711 .globl machine_check_fwnmi 719 .globl machine_check_fwnmi
712machine_check_fwnmi: 720machine_check_fwnmi:
713 HMT_MEDIUM 721 HMT_MEDIUM
714 mtspr SPRG1,r13 /* save r13 */ 722 mtspr SPRG1,r13 /* save r13 */
723 RUNLATCH_ON(r13)
715 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 724 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
716 725
717 /* 726 /*
@@ -848,6 +857,7 @@ unrecov_fer:
848 .align 7 857 .align 7
849 .globl data_access_common 858 .globl data_access_common
850data_access_common: 859data_access_common:
860 RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
851 mfspr r10,DAR 861 mfspr r10,DAR
852 std r10,PACA_EXGEN+EX_DAR(r13) 862 std r10,PACA_EXGEN+EX_DAR(r13)
853 mfspr r10,DSISR 863 mfspr r10,DSISR
diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/ppc64/kernel/hvconsole.c
index c72fb8ffe974..138e128a3886 100644
--- a/arch/ppc64/kernel/hvconsole.c
+++ b/arch/ppc64/kernel/hvconsole.c
@@ -27,7 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <asm/hvcall.h> 28#include <asm/hvcall.h>
29#include <asm/hvconsole.h> 29#include <asm/hvconsole.h>
30#include <asm/prom.h>
31 30
32/** 31/**
33 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper 32 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
@@ -42,29 +41,14 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count)
42 unsigned long got; 41 unsigned long got;
43 42
44 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, 43 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
45 (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) { 44 (unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
46 /*
47 * Work around a HV bug where it gives us a null
48 * after every \r. -- paulus
49 */
50 if (got > 0) {
51 int i;
52 for (i = 1; i < got; ++i) {
53 if (buf[i] == 0 && buf[i-1] == '\r') {
54 --got;
55 if (i < got)
56 memmove(&buf[i], &buf[i+1],
57 got - i);
58 }
59 }
60 }
61 return got; 45 return got;
62 }
63 return 0; 46 return 0;
64} 47}
65 48
66EXPORT_SYMBOL(hvc_get_chars); 49EXPORT_SYMBOL(hvc_get_chars);
67 50
51
68/** 52/**
69 * hvc_put_chars: send characters to firmware for denoted vterm adapter 53 * hvc_put_chars: send characters to firmware for denoted vterm adapter
70 * @vtermno: The vtermno or unit_address of the adapter from which the data 54 * @vtermno: The vtermno or unit_address of the adapter from which the data
@@ -88,34 +72,3 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
88} 72}
89 73
90EXPORT_SYMBOL(hvc_put_chars); 74EXPORT_SYMBOL(hvc_put_chars);
91
92/*
93 * We hope/assume that the first vty found corresponds to the first console
94 * device.
95 */
96int hvc_find_vtys(void)
97{
98 struct device_node *vty;
99 int num_found = 0;
100
101 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
102 vty = of_find_node_by_name(vty, "vty")) {
103 uint32_t *vtermno;
104
105 /* We have statically defined space for only a certain number of
106 * console adapters. */
107 if (num_found >= MAX_NR_HVC_CONSOLES)
108 break;
109
110 vtermno = (uint32_t *)get_property(vty, "reg", NULL);
111 if (!vtermno)
112 continue;
113
114 if (device_is_compatible(vty, "hvterm1")) {
115 hvc_instantiate(*vtermno, num_found);
116 ++num_found;
117 }
118 }
119
120 return num_found;
121}
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index b3f770f6d402..077c82fc9f3a 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -834,6 +834,92 @@ static int __init iSeries_src_init(void)
834 834
835late_initcall(iSeries_src_init); 835late_initcall(iSeries_src_init);
836 836
837static inline void process_iSeries_events(void)
838{
839 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
840}
841
842static void yield_shared_processor(void)
843{
844 unsigned long tb;
845
846 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
847 HvCall_MaskLpEvent |
848 HvCall_MaskLpProd |
849 HvCall_MaskTimeout);
850
851 tb = get_tb();
852 /* Compute future tb value when yield should expire */
853 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
854
855 /*
856 * The decrementer stops during the yield. Force a fake decrementer
857 * here and let the timer_interrupt code sort out the actual time.
858 */
859 get_paca()->lppaca.int_dword.fields.decr_int = 1;
860 process_iSeries_events();
861}
862
863static int iseries_shared_idle(void)
864{
865 while (1) {
866 while (!need_resched() && !hvlpevent_is_pending()) {
867 local_irq_disable();
868 ppc64_runlatch_off();
869
870 /* Recheck with irqs off */
871 if (!need_resched() && !hvlpevent_is_pending())
872 yield_shared_processor();
873
874 HMT_medium();
875 local_irq_enable();
876 }
877
878 ppc64_runlatch_on();
879
880 if (hvlpevent_is_pending())
881 process_iSeries_events();
882
883 schedule();
884 }
885
886 return 0;
887}
888
889static int iseries_dedicated_idle(void)
890{
891 long oldval;
892
893 while (1) {
894 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
895
896 if (!oldval) {
897 set_thread_flag(TIF_POLLING_NRFLAG);
898
899 while (!need_resched()) {
900 ppc64_runlatch_off();
901 HMT_low();
902
903 if (hvlpevent_is_pending()) {
904 HMT_medium();
905 ppc64_runlatch_on();
906 process_iSeries_events();
907 }
908 }
909
910 HMT_medium();
911 clear_thread_flag(TIF_POLLING_NRFLAG);
912 } else {
913 set_need_resched();
914 }
915
916 ppc64_runlatch_on();
917 schedule();
918 }
919
920 return 0;
921}
922
837#ifndef CONFIG_PCI 923#ifndef CONFIG_PCI
838void __init iSeries_init_IRQ(void) { } 924void __init iSeries_init_IRQ(void) { }
839#endif 925#endif
@@ -859,5 +945,13 @@ void __init iSeries_early_setup(void)
859 ppc_md.get_rtc_time = iSeries_get_rtc_time; 945 ppc_md.get_rtc_time = iSeries_get_rtc_time;
860 ppc_md.calibrate_decr = iSeries_calibrate_decr; 946 ppc_md.calibrate_decr = iSeries_calibrate_decr;
861 ppc_md.progress = iSeries_progress; 947 ppc_md.progress = iSeries_progress;
948
949 if (get_paca()->lppaca.shared_proc) {
950 ppc_md.idle_loop = iseries_shared_idle;
951 printk(KERN_INFO "Using shared processor idle loop\n");
952 } else {
953 ppc_md.idle_loop = iseries_dedicated_idle;
954 printk(KERN_INFO "Using dedicated idle loop\n");
955 }
862} 956}
863 957
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 08952c7e6216..954395d42636 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -20,109 +20,18 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <linux/module.h>
24#include <linux/sysctl.h> 23#include <linux/sysctl.h>
25#include <linux/smp.h>
26 24
27#include <asm/system.h> 25#include <asm/system.h>
28#include <asm/processor.h> 26#include <asm/processor.h>
29#include <asm/mmu.h>
30#include <asm/cputable.h> 27#include <asm/cputable.h>
31#include <asm/time.h> 28#include <asm/time.h>
32#include <asm/iSeries/HvCall.h>
33#include <asm/iSeries/ItLpQueue.h>
34#include <asm/plpar_wrappers.h>
35#include <asm/systemcfg.h> 29#include <asm/systemcfg.h>
30#include <asm/machdep.h>
36 31
37extern void power4_idle(void); 32extern void power4_idle(void);
38 33
39static int (*idle_loop)(void); 34int default_idle(void)
40
41#ifdef CONFIG_PPC_ISERIES
42static unsigned long maxYieldTime = 0;
43static unsigned long minYieldTime = 0xffffffffffffffffUL;
44
45static inline void process_iSeries_events(void)
46{
47 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
48}
49
50static void yield_shared_processor(void)
51{
52 unsigned long tb;
53 unsigned long yieldTime;
54
55 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
56 HvCall_MaskLpEvent |
57 HvCall_MaskLpProd |
58 HvCall_MaskTimeout);
59
60 tb = get_tb();
61 /* Compute future tb value when yield should expire */
62 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
63
64 yieldTime = get_tb() - tb;
65 if (yieldTime > maxYieldTime)
66 maxYieldTime = yieldTime;
67
68 if (yieldTime < minYieldTime)
69 minYieldTime = yieldTime;
70
71 /*
72 * The decrementer stops during the yield. Force a fake decrementer
73 * here and let the timer_interrupt code sort out the actual time.
74 */
75 get_paca()->lppaca.int_dword.fields.decr_int = 1;
76 process_iSeries_events();
77}
78
79static int iSeries_idle(void)
80{
81 struct paca_struct *lpaca;
82 long oldval;
83
84 /* ensure iSeries run light will be out when idle */
85 ppc64_runlatch_off();
86
87 lpaca = get_paca();
88
89 while (1) {
90 if (lpaca->lppaca.shared_proc) {
91 if (hvlpevent_is_pending())
92 process_iSeries_events();
93 if (!need_resched())
94 yield_shared_processor();
95 } else {
96 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
97
98 if (!oldval) {
99 set_thread_flag(TIF_POLLING_NRFLAG);
100
101 while (!need_resched()) {
102 HMT_medium();
103 if (hvlpevent_is_pending())
104 process_iSeries_events();
105 HMT_low();
106 }
107
108 HMT_medium();
109 clear_thread_flag(TIF_POLLING_NRFLAG);
110 } else {
111 set_need_resched();
112 }
113 }
114
115 ppc64_runlatch_on();
116 schedule();
117 ppc64_runlatch_off();
118 }
119
120 return 0;
121}
122
123#else
124
125static int default_idle(void)
126{ 35{
127 long oldval; 36 long oldval;
128 unsigned int cpu = smp_processor_id(); 37 unsigned int cpu = smp_processor_id();
@@ -134,7 +43,8 @@ static int default_idle(void)
134 set_thread_flag(TIF_POLLING_NRFLAG); 43 set_thread_flag(TIF_POLLING_NRFLAG);
135 44
136 while (!need_resched() && !cpu_is_offline(cpu)) { 45 while (!need_resched() && !cpu_is_offline(cpu)) {
137 barrier(); 46 ppc64_runlatch_off();
47
138 /* 48 /*
139 * Go into low thread priority and possibly 49 * Go into low thread priority and possibly
140 * low power mode. 50 * low power mode.
@@ -149,6 +59,7 @@ static int default_idle(void)
149 set_need_resched(); 59 set_need_resched();
150 } 60 }
151 61
62 ppc64_runlatch_on();
152 schedule(); 63 schedule();
153 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 64 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
154 cpu_die(); 65 cpu_die();
@@ -157,127 +68,19 @@ static int default_idle(void)
157 return 0; 68 return 0;
158} 69}
159 70
160#ifdef CONFIG_PPC_PSERIES 71int native_idle(void)
161
162DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
163
164int dedicated_idle(void)
165{ 72{
166 long oldval;
167 struct paca_struct *lpaca = get_paca(), *ppaca;
168 unsigned long start_snooze;
169 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
170 unsigned int cpu = smp_processor_id();
171
172 ppaca = &paca[cpu ^ 1];
173
174 while (1) { 73 while (1) {
175 /* 74 ppc64_runlatch_off();
176 * Indicate to the HV that we are idle. Now would be
177 * a good time to find other work to dispatch.
178 */
179 lpaca->lppaca.idle = 1;
180
181 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
182 if (!oldval) {
183 set_thread_flag(TIF_POLLING_NRFLAG);
184 start_snooze = __get_tb() +
185 *smt_snooze_delay * tb_ticks_per_usec;
186 while (!need_resched() && !cpu_is_offline(cpu)) {
187 /*
188 * Go into low thread priority and possibly
189 * low power mode.
190 */
191 HMT_low();
192 HMT_very_low();
193
194 if (*smt_snooze_delay == 0 ||
195 __get_tb() < start_snooze)
196 continue;
197
198 HMT_medium();
199
200 if (!(ppaca->lppaca.idle)) {
201 local_irq_disable();
202
203 /*
204 * We are about to sleep the thread
205 * and so wont be polling any
206 * more.
207 */
208 clear_thread_flag(TIF_POLLING_NRFLAG);
209
210 /*
211 * SMT dynamic mode. Cede will result
212 * in this thread going dormant, if the
213 * partner thread is still doing work.
214 * Thread wakes up if partner goes idle,
215 * an interrupt is presented, or a prod
216 * occurs. Returning from the cede
217 * enables external interrupts.
218 */
219 if (!need_resched())
220 cede_processor();
221 else
222 local_irq_enable();
223 } else {
224 /*
225 * Give the HV an opportunity at the
226 * processor, since we are not doing
227 * any work.
228 */
229 poll_pending();
230 }
231 }
232
233 clear_thread_flag(TIF_POLLING_NRFLAG);
234 } else {
235 set_need_resched();
236 }
237
238 HMT_medium();
239 lpaca->lppaca.idle = 0;
240 schedule();
241 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
242 cpu_die();
243 }
244 return 0;
245}
246
247static int shared_idle(void)
248{
249 struct paca_struct *lpaca = get_paca();
250 unsigned int cpu = smp_processor_id();
251
252 while (1) {
253 /*
254 * Indicate to the HV that we are idle. Now would be
255 * a good time to find other work to dispatch.
256 */
257 lpaca->lppaca.idle = 1;
258 75
259 while (!need_resched() && !cpu_is_offline(cpu)) { 76 if (!need_resched())
260 local_irq_disable(); 77 power4_idle();
261 78
262 /* 79 if (need_resched()) {
263 * Yield the processor to the hypervisor. We return if 80 ppc64_runlatch_on();
264 * an external interrupt occurs (which are driven prior 81 schedule();
265 * to returning here) or if a prod occurs from another
266 * processor. When returning here, external interrupts
267 * are enabled.
268 *
269 * Check need_resched() again with interrupts disabled
270 * to avoid a race.
271 */
272 if (!need_resched())
273 cede_processor();
274 else
275 local_irq_enable();
276 } 82 }
277 83
278 HMT_medium();
279 lpaca->lppaca.idle = 0;
280 schedule();
281 if (cpu_is_offline(smp_processor_id()) && 84 if (cpu_is_offline(smp_processor_id()) &&
282 system_state == SYSTEM_RUNNING) 85 system_state == SYSTEM_RUNNING)
283 cpu_die(); 86 cpu_die();
@@ -286,29 +89,10 @@ static int shared_idle(void)
286 return 0; 89 return 0;
287} 90}
288 91
289#endif /* CONFIG_PPC_PSERIES */
290
291static int native_idle(void)
292{
293 while(1) {
294 /* check CPU type here */
295 if (!need_resched())
296 power4_idle();
297 if (need_resched())
298 schedule();
299
300 if (cpu_is_offline(raw_smp_processor_id()) &&
301 system_state == SYSTEM_RUNNING)
302 cpu_die();
303 }
304 return 0;
305}
306
307#endif /* CONFIG_PPC_ISERIES */
308
309void cpu_idle(void) 92void cpu_idle(void)
310{ 93{
311 idle_loop(); 94 BUG_ON(NULL == ppc_md.idle_loop);
95 ppc_md.idle_loop();
312} 96}
313 97
314int powersave_nap; 98int powersave_nap;
@@ -342,42 +126,3 @@ register_powersave_nap_sysctl(void)
342} 126}
343__initcall(register_powersave_nap_sysctl); 127__initcall(register_powersave_nap_sysctl);
344#endif 128#endif
345
346int idle_setup(void)
347{
348 /*
349 * Move that junk to each platform specific file, eventually define
350 * a pSeries_idle for shared processor stuff
351 */
352#ifdef CONFIG_PPC_ISERIES
353 idle_loop = iSeries_idle;
354 return 1;
355#else
356 idle_loop = default_idle;
357#endif
358#ifdef CONFIG_PPC_PSERIES
359 if (systemcfg->platform & PLATFORM_PSERIES) {
360 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
361 if (get_paca()->lppaca.shared_proc) {
362 printk(KERN_INFO "Using shared processor idle loop\n");
363 idle_loop = shared_idle;
364 } else {
365 printk(KERN_INFO "Using dedicated idle loop\n");
366 idle_loop = dedicated_idle;
367 }
368 } else {
369 printk(KERN_INFO "Using default idle loop\n");
370 idle_loop = default_idle;
371 }
372 }
373#endif /* CONFIG_PPC_PSERIES */
374#ifndef CONFIG_PPC_ISERIES
375 if (systemcfg->platform == PLATFORM_POWERMAC ||
376 systemcfg->platform == PLATFORM_MAPLE) {
377 printk(KERN_INFO "Using native/NAP idle loop\n");
378 idle_loop = native_idle;
379 }
380#endif /* CONFIG_PPC_ISERIES */
381
382 return 1;
383}
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
index da8900b51f40..bb55b5a56910 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/ppc64/kernel/maple_setup.c
@@ -177,6 +177,8 @@ void __init maple_setup_arch(void)
177#ifdef CONFIG_DUMMY_CONSOLE 177#ifdef CONFIG_DUMMY_CONSOLE
178 conswitchp = &dummy_con; 178 conswitchp = &dummy_con;
179#endif 179#endif
180
181 printk(KERN_INFO "Using native/NAP idle loop\n");
180} 182}
181 183
182/* 184/*
@@ -297,4 +299,5 @@ struct machdep_calls __initdata maple_md = {
297 .get_rtc_time = maple_get_rtc_time, 299 .get_rtc_time = maple_get_rtc_time,
298 .calibrate_decr = generic_calibrate_decr, 300 .calibrate_decr = generic_calibrate_decr,
299 .progress = maple_progress, 301 .progress = maple_progress,
302 .idle_loop = native_idle,
300}; 303};
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index f3dea0c5a88c..59f4f9973818 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -1124,9 +1124,11 @@ _GLOBAL(sys_call_table32)
1124 .llong .compat_sys_mq_getsetattr 1124 .llong .compat_sys_mq_getsetattr
1125 .llong .compat_sys_kexec_load 1125 .llong .compat_sys_kexec_load
1126 .llong .sys32_add_key 1126 .llong .sys32_add_key
1127 .llong .sys32_request_key 1127 .llong .sys32_request_key /* 270 */
1128 .llong .compat_sys_keyctl 1128 .llong .compat_sys_keyctl
1129 .llong .compat_sys_waitid 1129 .llong .compat_sys_waitid
1130 .llong .sys32_ioprio_set
1131 .llong .sys32_ioprio_get
1130 1132
1131 .balign 8 1133 .balign 8
1132_GLOBAL(sys_call_table) 1134_GLOBAL(sys_call_table)
@@ -1403,3 +1405,5 @@ _GLOBAL(sys_call_table)
1403 .llong .sys_request_key /* 270 */ 1405 .llong .sys_request_key /* 270 */
1404 .llong .sys_keyctl 1406 .llong .sys_keyctl
1405 .llong .sys_waitid 1407 .llong .sys_waitid
1408 .llong .sys_ioprio_set
1409 .llong .sys_ioprio_get
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index 44d9af72d225..5bec956e44a0 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -19,6 +19,7 @@
19#undef DEBUG 19#undef DEBUG
20 20
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/cpu.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
23#include <linux/sched.h> 24#include <linux/sched.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
@@ -82,6 +83,9 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */
82extern void pSeries_system_reset_exception(struct pt_regs *regs); 83extern void pSeries_system_reset_exception(struct pt_regs *regs);
83extern int pSeries_machine_check_exception(struct pt_regs *regs); 84extern int pSeries_machine_check_exception(struct pt_regs *regs);
84 85
86static int pseries_shared_idle(void);
87static int pseries_dedicated_idle(void);
88
85static volatile void __iomem * chrp_int_ack_special; 89static volatile void __iomem * chrp_int_ack_special;
86struct mpic *pSeries_mpic; 90struct mpic *pSeries_mpic;
87 91
@@ -229,6 +233,20 @@ static void __init pSeries_setup_arch(void)
229 233
230 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) 234 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
231 vpa_init(boot_cpuid); 235 vpa_init(boot_cpuid);
236
237 /* Choose an idle loop */
238 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
239 if (get_paca()->lppaca.shared_proc) {
240 printk(KERN_INFO "Using shared processor idle loop\n");
241 ppc_md.idle_loop = pseries_shared_idle;
242 } else {
243 printk(KERN_INFO "Using dedicated idle loop\n");
244 ppc_md.idle_loop = pseries_dedicated_idle;
245 }
246 } else {
247 printk(KERN_INFO "Using default idle loop\n");
248 ppc_md.idle_loop = default_idle;
249 }
232} 250}
233 251
234static int __init pSeries_init_panel(void) 252static int __init pSeries_init_panel(void)
@@ -418,6 +436,144 @@ static int __init pSeries_probe(int platform)
418 return 1; 436 return 1;
419} 437}
420 438
439DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
440
441static inline void dedicated_idle_sleep(unsigned int cpu)
442{
443 struct paca_struct *ppaca = &paca[cpu ^ 1];
444
445 /* Only sleep if the other thread is not idle */
446 if (!(ppaca->lppaca.idle)) {
447 local_irq_disable();
448
449 /*
450 * We are about to sleep the thread and so wont be polling any
451 * more.
452 */
453 clear_thread_flag(TIF_POLLING_NRFLAG);
454
455 /*
456 * SMT dynamic mode. Cede will result in this thread going
457 * dormant, if the partner thread is still doing work. Thread
458 * wakes up if partner goes idle, an interrupt is presented, or
459 * a prod occurs. Returning from the cede enables external
460 * interrupts.
461 */
462 if (!need_resched())
463 cede_processor();
464 else
465 local_irq_enable();
466 } else {
467 /*
468 * Give the HV an opportunity at the processor, since we are
469 * not doing any work.
470 */
471 poll_pending();
472 }
473}
474
475static int pseries_dedicated_idle(void)
476{
477 long oldval;
478 struct paca_struct *lpaca = get_paca();
479 unsigned int cpu = smp_processor_id();
480 unsigned long start_snooze;
481 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
482
483 while (1) {
484 /*
485 * Indicate to the HV that we are idle. Now would be
486 * a good time to find other work to dispatch.
487 */
488 lpaca->lppaca.idle = 1;
489
490 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
491 if (!oldval) {
492 set_thread_flag(TIF_POLLING_NRFLAG);
493
494 start_snooze = __get_tb() +
495 *smt_snooze_delay * tb_ticks_per_usec;
496
497 while (!need_resched() && !cpu_is_offline(cpu)) {
498 ppc64_runlatch_off();
499
500 /*
501 * Go into low thread priority and possibly
502 * low power mode.
503 */
504 HMT_low();
505 HMT_very_low();
506
507 if (*smt_snooze_delay != 0 &&
508 __get_tb() > start_snooze) {
509 HMT_medium();
510 dedicated_idle_sleep(cpu);
511 }
512
513 }
514
515 HMT_medium();
516 clear_thread_flag(TIF_POLLING_NRFLAG);
517 } else {
518 set_need_resched();
519 }
520
521 lpaca->lppaca.idle = 0;
522 ppc64_runlatch_on();
523
524 schedule();
525
526 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
527 cpu_die();
528 }
529}
530
531static int pseries_shared_idle(void)
532{
533 struct paca_struct *lpaca = get_paca();
534 unsigned int cpu = smp_processor_id();
535
536 while (1) {
537 /*
538 * Indicate to the HV that we are idle. Now would be
539 * a good time to find other work to dispatch.
540 */
541 lpaca->lppaca.idle = 1;
542
543 while (!need_resched() && !cpu_is_offline(cpu)) {
544 local_irq_disable();
545 ppc64_runlatch_off();
546
547 /*
548 * Yield the processor to the hypervisor. We return if
549 * an external interrupt occurs (which are driven prior
550 * to returning here) or if a prod occurs from another
551 * processor. When returning here, external interrupts
552 * are enabled.
553 *
554 * Check need_resched() again with interrupts disabled
555 * to avoid a race.
556 */
557 if (!need_resched())
558 cede_processor();
559 else
560 local_irq_enable();
561
562 HMT_medium();
563 }
564
565 lpaca->lppaca.idle = 0;
566 ppc64_runlatch_on();
567
568 schedule();
569
570 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
571 cpu_die();
572 }
573
574 return 0;
575}
576
421struct machdep_calls __initdata pSeries_md = { 577struct machdep_calls __initdata pSeries_md = {
422 .probe = pSeries_probe, 578 .probe = pSeries_probe,
423 .setup_arch = pSeries_setup_arch, 579 .setup_arch = pSeries_setup_arch,
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
index 6cf03d387b91..3013cdb5f933 100644
--- a/arch/ppc64/kernel/pmac_setup.c
+++ b/arch/ppc64/kernel/pmac_setup.c
@@ -186,6 +186,8 @@ void __init pmac_setup_arch(void)
186#ifdef CONFIG_DUMMY_CONSOLE 186#ifdef CONFIG_DUMMY_CONSOLE
187 conswitchp = &dummy_con; 187 conswitchp = &dummy_con;
188#endif 188#endif
189
190 printk(KERN_INFO "Using native/NAP idle loop\n");
189} 191}
190 192
191#ifdef CONFIG_SCSI 193#ifdef CONFIG_SCSI
@@ -507,5 +509,6 @@ struct machdep_calls __initdata pmac_md = {
507 .calibrate_decr = pmac_calibrate_decr, 509 .calibrate_decr = pmac_calibrate_decr,
508 .feature_call = pmac_do_feature_call, 510 .feature_call = pmac_do_feature_call,
509 .progress = pmac_progress, 511 .progress = pmac_progress,
510 .check_legacy_ioport = pmac_check_legacy_ioport 512 .check_legacy_ioport = pmac_check_legacy_ioport,
513 .idle_loop = native_idle,
511}; 514};
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index d5e4866e9ac2..d1b33f0b26cb 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -96,7 +96,6 @@ extern void udbg_init_maple_realmode(void);
96extern unsigned long klimit; 96extern unsigned long klimit;
97 97
98extern void mm_init_ppc64(void); 98extern void mm_init_ppc64(void);
99extern int idle_setup(void);
100extern void stab_initialize(unsigned long stab); 99extern void stab_initialize(unsigned long stab);
101extern void htab_initialize(void); 100extern void htab_initialize(void);
102extern void early_init_devtree(void *flat_dt); 101extern void early_init_devtree(void *flat_dt);
@@ -1081,8 +1080,11 @@ void __init setup_arch(char **cmdline_p)
1081 1080
1082 ppc_md.setup_arch(); 1081 ppc_md.setup_arch();
1083 1082
1084 /* Select the correct idle loop for the platform. */ 1083 /* Use the default idle loop if the platform hasn't provided one. */
1085 idle_setup(); 1084 if (NULL == ppc_md.idle_loop) {
1085 ppc_md.idle_loop = default_idle;
1086 printk(KERN_INFO "Using default idle loop\n");
1087 }
1086 1088
1087 paging_init(); 1089 paging_init();
1088 ppc64_boot_msg(0x15, "Setup Done"); 1090 ppc64_boot_msg(0x15, "Setup Done");
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 118436e8085a..206619080e66 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -30,47 +30,26 @@
30#include <linux/sem.h> 30#include <linux/sem.h>
31#include <linux/msg.h> 31#include <linux/msg.h>
32#include <linux/shm.h> 32#include <linux/shm.h>
33#include <linux/slab.h>
34#include <linux/uio.h>
35#include <linux/aio.h>
36#include <linux/nfs_fs.h>
37#include <linux/module.h>
38#include <linux/sunrpc/svc.h>
39#include <linux/nfsd/nfsd.h>
40#include <linux/nfsd/cache.h>
41#include <linux/nfsd/xdr.h>
42#include <linux/nfsd/syscall.h>
43#include <linux/poll.h> 33#include <linux/poll.h>
44#include <linux/personality.h> 34#include <linux/personality.h>
45#include <linux/stat.h> 35#include <linux/stat.h>
46#include <linux/filter.h>
47#include <linux/highmem.h>
48#include <linux/highuid.h>
49#include <linux/mman.h> 36#include <linux/mman.h>
50#include <linux/ipv6.h>
51#include <linux/in.h> 37#include <linux/in.h>
52#include <linux/icmpv6.h>
53#include <linux/syscalls.h> 38#include <linux/syscalls.h>
54#include <linux/unistd.h> 39#include <linux/unistd.h>
55#include <linux/sysctl.h> 40#include <linux/sysctl.h>
56#include <linux/binfmts.h> 41#include <linux/binfmts.h>
57#include <linux/dnotify.h>
58#include <linux/security.h> 42#include <linux/security.h>
59#include <linux/compat.h> 43#include <linux/compat.h>
60#include <linux/ptrace.h> 44#include <linux/ptrace.h>
61#include <linux/aio_abi.h>
62#include <linux/elf.h> 45#include <linux/elf.h>
63 46
64#include <net/scm.h>
65#include <net/sock.h>
66
67#include <asm/ptrace.h> 47#include <asm/ptrace.h>
68#include <asm/types.h> 48#include <asm/types.h>
69#include <asm/ipc.h> 49#include <asm/ipc.h>
70#include <asm/uaccess.h> 50#include <asm/uaccess.h>
71#include <asm/unistd.h> 51#include <asm/unistd.h>
72#include <asm/semaphore.h> 52#include <asm/semaphore.h>
73#include <asm/ppcdebug.h>
74#include <asm/time.h> 53#include <asm/time.h>
75#include <asm/mmu_context.h> 54#include <asm/mmu_context.h>
76#include <asm/systemcfg.h> 55#include <asm/systemcfg.h>
@@ -350,8 +329,6 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
350 return ret; 329 return ret;
351} 330}
352 331
353
354/* These are here just in case some old sparc32 binary calls it. */
355asmlinkage long sys32_pause(void) 332asmlinkage long sys32_pause(void)
356{ 333{
357 current->state = TASK_INTERRUPTIBLE; 334 current->state = TASK_INTERRUPTIBLE;
@@ -360,8 +337,6 @@ asmlinkage long sys32_pause(void)
360 return -ERESTARTNOHAND; 337 return -ERESTARTNOHAND;
361} 338}
362 339
363
364
365static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 340static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
366{ 341{
367 long usec; 342 long usec;
@@ -847,16 +822,6 @@ asmlinkage long sys32_getpgid(u32 pid)
847} 822}
848 823
849 824
850/* Note: it is necessary to treat which and who as unsigned ints,
851 * with the corresponding cast to a signed int to insure that the
852 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
853 * and the register representation of a signed int (msr in 64-bit mode) is performed.
854 */
855asmlinkage long sys32_getpriority(u32 which, u32 who)
856{
857 return sys_getpriority((int)which, (int)who);
858}
859
860 825
861/* Note: it is necessary to treat pid as an unsigned int, 826/* Note: it is necessary to treat pid as an unsigned int,
862 * with the corresponding cast to a signed int to insure that the 827 * with the corresponding cast to a signed int to insure that the
@@ -1048,6 +1013,11 @@ asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
1048 return sys_setpgid((int)pid, (int)pgid); 1013 return sys_setpgid((int)pid, (int)pgid);
1049} 1014}
1050 1015
1016long sys32_getpriority(u32 which, u32 who)
1017{
1018 /* sign extend which and who */
1019 return sys_getpriority((int)which, (int)who);
1020}
1051 1021
1052long sys32_setpriority(u32 which, u32 who, u32 niceval) 1022long sys32_setpriority(u32 which, u32 who, u32 niceval)
1053{ 1023{
@@ -1055,6 +1025,18 @@ long sys32_setpriority(u32 which, u32 who, u32 niceval)
1055 return sys_setpriority((int)which, (int)who, (int)niceval); 1025 return sys_setpriority((int)which, (int)who, (int)niceval);
1056} 1026}
1057 1027
1028long sys32_ioprio_get(u32 which, u32 who)
1029{
1030 /* sign extend which and who */
1031 return sys_ioprio_get((int)which, (int)who);
1032}
1033
1034long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
1035{
1036 /* sign extend which, who and ioprio */
1037 return sys_ioprio_set((int)which, (int)who, (int)ioprio);
1038}
1039
1058/* Note: it is necessary to treat newmask as an unsigned int, 1040/* Note: it is necessary to treat newmask as an unsigned int,
1059 * with the corresponding cast to a signed int to insure that the 1041 * with the corresponding cast to a signed int to insure that the
1060 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 1042 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1273,8 +1255,6 @@ long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
1273 (u64)len_high << 32 | len_low, advice); 1255 (u64)len_high << 32 | len_low, advice);
1274} 1256}
1275 1257
1276extern asmlinkage long sys_timer_create(clockid_t, sigevent_t __user *, timer_t __user *);
1277
1278long ppc32_timer_create(clockid_t clock, 1258long ppc32_timer_create(clockid_t clock,
1279 struct compat_sigevent __user *ev32, 1259 struct compat_sigevent __user *ev32,
1280 timer_t __user *timer_id) 1260 timer_t __user *timer_id)
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 2f704a2cafb1..02b8ac4e0168 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -112,7 +112,6 @@ void ppc64_enable_pmcs(void)
112 unsigned long hid0; 112 unsigned long hid0;
113#ifdef CONFIG_PPC_PSERIES 113#ifdef CONFIG_PPC_PSERIES
114 unsigned long set, reset; 114 unsigned long set, reset;
115 int ret;
116#endif /* CONFIG_PPC_PSERIES */ 115#endif /* CONFIG_PPC_PSERIES */
117 116
118 /* Only need to enable them once */ 117 /* Only need to enable them once */
@@ -145,11 +144,7 @@ void ppc64_enable_pmcs(void)
145 case PLATFORM_PSERIES_LPAR: 144 case PLATFORM_PSERIES_LPAR:
146 set = 1UL << 63; 145 set = 1UL << 63;
147 reset = 0; 146 reset = 0;
148 ret = plpar_hcall_norets(H_PERFMON, set, reset); 147 plpar_hcall_norets(H_PERFMON, set, reset);
149 if (ret)
150 printk(KERN_ERR "H_PERFMON call on cpu %u "
151 "returned %d\n",
152 smp_processor_id(), ret);
153 break; 148 break;
154#endif /* CONFIG_PPC_PSERIES */ 149#endif /* CONFIG_PPC_PSERIES */
155 150
@@ -161,13 +156,6 @@ void ppc64_enable_pmcs(void)
161 /* instruct hypervisor to maintain PMCs */ 156 /* instruct hypervisor to maintain PMCs */
162 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) 157 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
163 get_paca()->lppaca.pmcregs_in_use = 1; 158 get_paca()->lppaca.pmcregs_in_use = 1;
164
165 /*
166 * On SMT machines we have to set the run latch in the ctrl register
167 * in order to make PMC6 spin.
168 */
169 if (cpu_has_feature(CPU_FTR_SMT))
170 ppc64_runlatch_on();
171#endif /* CONFIG_PPC_PSERIES */ 159#endif /* CONFIG_PPC_PSERIES */
172} 160}
173 161
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S
index 11290c902ba3..6f87a916a394 100644
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S
@@ -40,9 +40,9 @@ SECTIONS
40 .gcc_except_table : { *(.gcc_except_table) } 40 .gcc_except_table : { *(.gcc_except_table) }
41 .fixup : { *(.fixup) } 41 .fixup : { *(.fixup) }
42 42
43 .got ALIGN(4) : { *(.got.plt) *(.got) }
44
45 .dynamic : { *(.dynamic) } :text :dynamic 43 .dynamic : { *(.dynamic) } :text :dynamic
44 .got : { *(.got) }
45 .plt : { *(.plt) }
46 46
47 _end = .; 47 _end = .;
48 __end = .; 48 __end = .;