diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:04:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:04:20 -0500 |
commit | 21eb4fa1700112d1420d72e1de708af671a251c8 (patch) | |
tree | 3afd9f526da50108c27e05ac69826be5e7c2ad6e /arch/powerpc/kernel | |
parent | 0c0e8caf9fd6c9a49fb9fbdba14a8b7b4239adde (diff) | |
parent | d003e7a1a569501cbe9a5ca14748177498c4893a (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (116 commits)
[POWERPC] Add export of vgacon_remap_base
[POWERPC] Remove bogus comment about page_is_ram
[POWERPC] windfarm: don't die on suspend thread signal
[POWERPC] Fix comment in kernel/irq.c
[POWERPC] ppc: Fix booke watchdog initialization
[POWERPC] PPC: Use ARRAY_SIZE macro when appropriate
[POWERPC] Use ARRAY_SIZE macro when appropriate
[POWERPC] Fix ppc64's writing to struct file_operations
[POWERPC] ppc: use syslog macro for the printk log level
[POWERPC] ppc: cs4218_tdm remove extra brace
[POWERPC] Add mpc52xx/lite5200 PCI support
[POWERPC] Only use H_BULK_REMOVE if the firmware supports it
[POWERPC] Fixup error handling when emulating a floating point instruction
[POWERPC] Enable interrupts if we are doing fp math emulation
[POWERPC] Added kprobes support to ppc32
[POWERPC] Make pSeries use the H_BULK_REMOVE hypervisor call
[POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace
[POWERPC] Fix performance monitor exception
[POWERPC] Compile fixes for arch/powerpc dcr code
[POWERPC] Maple: use mmio nvram
...
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_pa6t.S | 44 | ||||
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 21 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 59 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_32.S | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/iomap.c | 20 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/kprobes.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 40 | ||||
-rw-r--r-- | arch/powerpc/kernel/module_32.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/pmc.c | 37 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 18 | ||||
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 141 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 111 | ||||
-rw-r--r-- | arch/powerpc/kernel/udbg.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/udbg_16550.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 6 |
24 files changed, 405 insertions, 190 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index d2ded19e4064..8120d428ebfd 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -17,6 +17,7 @@ obj-y += vdso32/ | |||
17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ |
18 | signal_64.o ptrace32.o \ | 18 | signal_64.o ptrace32.o \ |
19 | paca.o cpu_setup_ppc970.o \ | 19 | paca.o cpu_setup_ppc970.o \ |
20 | cpu_setup_pa6t.o \ | ||
20 | firmware.o sysfs.o nvram_64.o | 21 | firmware.o sysfs.o nvram_64.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 22 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 23 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
diff --git a/arch/powerpc/kernel/cpu_setup_pa6t.S b/arch/powerpc/kernel/cpu_setup_pa6t.S new file mode 100644 index 000000000000..4047be25c4d2 --- /dev/null +++ b/arch/powerpc/kernel/cpu_setup_pa6t.S | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2007 PA Semi, Inc | ||
3 | * | ||
4 | * Maintained by: Olof Johansson <olof@lixom.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <asm/processor.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <asm/cputable.h> | ||
24 | #include <asm/ppc_asm.h> | ||
25 | #include <asm/asm-offsets.h> | ||
26 | #include <asm/cache.h> | ||
27 | |||
28 | /* Right now, restore and setup are the same thing */ | ||
29 | _GLOBAL(__restore_cpu_pa6t) | ||
30 | _GLOBAL(__setup_cpu_pa6t) | ||
31 | /* Do nothing if not running in HV mode */ | ||
32 | mfmsr r0 | ||
33 | rldicl. r0,r0,4,63 | ||
34 | beqlr | ||
35 | |||
36 | mfspr r0,SPRN_HID5 | ||
37 | ori r0,r0,0x30 | ||
38 | mtspr SPRN_HID5,r0 | ||
39 | |||
40 | mfspr r0,SPRN_LPCR | ||
41 | ori r0,r0,0x7000 | ||
42 | mtspr SPRN_LPCR,r0 | ||
43 | |||
44 | blr | ||
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index b742013bb9da..dd17dffbf058 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -43,6 +43,8 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); | |||
43 | #ifdef CONFIG_PPC64 | 43 | #ifdef CONFIG_PPC64 |
44 | extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); | 44 | extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); |
45 | extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); | 45 | extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); |
46 | extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec); | ||
47 | extern void __restore_cpu_pa6t(unsigned long offset, struct cpu_spec* spec); | ||
46 | extern void __restore_cpu_ppc970(void); | 48 | extern void __restore_cpu_ppc970(void); |
47 | #endif /* CONFIG_PPC64 */ | 49 | #endif /* CONFIG_PPC64 */ |
48 | 50 | ||
@@ -86,6 +88,7 @@ static struct cpu_spec cpu_specs[] = { | |||
86 | .icache_bsize = 128, | 88 | .icache_bsize = 128, |
87 | .dcache_bsize = 128, | 89 | .dcache_bsize = 128, |
88 | .num_pmcs = 8, | 90 | .num_pmcs = 8, |
91 | .pmc_type = PPC_PMC_IBM, | ||
89 | .oprofile_cpu_type = "ppc64/power3", | 92 | .oprofile_cpu_type = "ppc64/power3", |
90 | .oprofile_type = PPC_OPROFILE_RS64, | 93 | .oprofile_type = PPC_OPROFILE_RS64, |
91 | .platform = "power3", | 94 | .platform = "power3", |
@@ -99,6 +102,7 @@ static struct cpu_spec cpu_specs[] = { | |||
99 | .icache_bsize = 128, | 102 | .icache_bsize = 128, |
100 | .dcache_bsize = 128, | 103 | .dcache_bsize = 128, |
101 | .num_pmcs = 8, | 104 | .num_pmcs = 8, |
105 | .pmc_type = PPC_PMC_IBM, | ||
102 | .oprofile_cpu_type = "ppc64/power3", | 106 | .oprofile_cpu_type = "ppc64/power3", |
103 | .oprofile_type = PPC_OPROFILE_RS64, | 107 | .oprofile_type = PPC_OPROFILE_RS64, |
104 | .platform = "power3", | 108 | .platform = "power3", |
@@ -112,6 +116,7 @@ static struct cpu_spec cpu_specs[] = { | |||
112 | .icache_bsize = 128, | 116 | .icache_bsize = 128, |
113 | .dcache_bsize = 128, | 117 | .dcache_bsize = 128, |
114 | .num_pmcs = 8, | 118 | .num_pmcs = 8, |
119 | .pmc_type = PPC_PMC_IBM, | ||
115 | .oprofile_cpu_type = "ppc64/rs64", | 120 | .oprofile_cpu_type = "ppc64/rs64", |
116 | .oprofile_type = PPC_OPROFILE_RS64, | 121 | .oprofile_type = PPC_OPROFILE_RS64, |
117 | .platform = "rs64", | 122 | .platform = "rs64", |
@@ -125,6 +130,7 @@ static struct cpu_spec cpu_specs[] = { | |||
125 | .icache_bsize = 128, | 130 | .icache_bsize = 128, |
126 | .dcache_bsize = 128, | 131 | .dcache_bsize = 128, |
127 | .num_pmcs = 8, | 132 | .num_pmcs = 8, |
133 | .pmc_type = PPC_PMC_IBM, | ||
128 | .oprofile_cpu_type = "ppc64/rs64", | 134 | .oprofile_cpu_type = "ppc64/rs64", |
129 | .oprofile_type = PPC_OPROFILE_RS64, | 135 | .oprofile_type = PPC_OPROFILE_RS64, |
130 | .platform = "rs64", | 136 | .platform = "rs64", |
@@ -138,6 +144,7 @@ static struct cpu_spec cpu_specs[] = { | |||
138 | .icache_bsize = 128, | 144 | .icache_bsize = 128, |
139 | .dcache_bsize = 128, | 145 | .dcache_bsize = 128, |
140 | .num_pmcs = 8, | 146 | .num_pmcs = 8, |
147 | .pmc_type = PPC_PMC_IBM, | ||
141 | .oprofile_cpu_type = "ppc64/rs64", | 148 | .oprofile_cpu_type = "ppc64/rs64", |
142 | .oprofile_type = PPC_OPROFILE_RS64, | 149 | .oprofile_type = PPC_OPROFILE_RS64, |
143 | .platform = "rs64", | 150 | .platform = "rs64", |
@@ -151,6 +158,7 @@ static struct cpu_spec cpu_specs[] = { | |||
151 | .icache_bsize = 128, | 158 | .icache_bsize = 128, |
152 | .dcache_bsize = 128, | 159 | .dcache_bsize = 128, |
153 | .num_pmcs = 8, | 160 | .num_pmcs = 8, |
161 | .pmc_type = PPC_PMC_IBM, | ||
154 | .oprofile_cpu_type = "ppc64/rs64", | 162 | .oprofile_cpu_type = "ppc64/rs64", |
155 | .oprofile_type = PPC_OPROFILE_RS64, | 163 | .oprofile_type = PPC_OPROFILE_RS64, |
156 | .platform = "rs64", | 164 | .platform = "rs64", |
@@ -164,6 +172,7 @@ static struct cpu_spec cpu_specs[] = { | |||
164 | .icache_bsize = 128, | 172 | .icache_bsize = 128, |
165 | .dcache_bsize = 128, | 173 | .dcache_bsize = 128, |
166 | .num_pmcs = 8, | 174 | .num_pmcs = 8, |
175 | .pmc_type = PPC_PMC_IBM, | ||
167 | .oprofile_cpu_type = "ppc64/power4", | 176 | .oprofile_cpu_type = "ppc64/power4", |
168 | .oprofile_type = PPC_OPROFILE_POWER4, | 177 | .oprofile_type = PPC_OPROFILE_POWER4, |
169 | .platform = "power4", | 178 | .platform = "power4", |
@@ -177,6 +186,7 @@ static struct cpu_spec cpu_specs[] = { | |||
177 | .icache_bsize = 128, | 186 | .icache_bsize = 128, |
178 | .dcache_bsize = 128, | 187 | .dcache_bsize = 128, |
179 | .num_pmcs = 8, | 188 | .num_pmcs = 8, |
189 | .pmc_type = PPC_PMC_IBM, | ||
180 | .oprofile_cpu_type = "ppc64/power4", | 190 | .oprofile_cpu_type = "ppc64/power4", |
181 | .oprofile_type = PPC_OPROFILE_POWER4, | 191 | .oprofile_type = PPC_OPROFILE_POWER4, |
182 | .platform = "power4", | 192 | .platform = "power4", |
@@ -191,6 +201,7 @@ static struct cpu_spec cpu_specs[] = { | |||
191 | .icache_bsize = 128, | 201 | .icache_bsize = 128, |
192 | .dcache_bsize = 128, | 202 | .dcache_bsize = 128, |
193 | .num_pmcs = 8, | 203 | .num_pmcs = 8, |
204 | .pmc_type = PPC_PMC_IBM, | ||
194 | .cpu_setup = __setup_cpu_ppc970, | 205 | .cpu_setup = __setup_cpu_ppc970, |
195 | .cpu_restore = __restore_cpu_ppc970, | 206 | .cpu_restore = __restore_cpu_ppc970, |
196 | .oprofile_cpu_type = "ppc64/970", | 207 | .oprofile_cpu_type = "ppc64/970", |
@@ -207,6 +218,7 @@ static struct cpu_spec cpu_specs[] = { | |||
207 | .icache_bsize = 128, | 218 | .icache_bsize = 128, |
208 | .dcache_bsize = 128, | 219 | .dcache_bsize = 128, |
209 | .num_pmcs = 8, | 220 | .num_pmcs = 8, |
221 | .pmc_type = PPC_PMC_IBM, | ||
210 | .cpu_setup = __setup_cpu_ppc970, | 222 | .cpu_setup = __setup_cpu_ppc970, |
211 | .cpu_restore = __restore_cpu_ppc970, | 223 | .cpu_restore = __restore_cpu_ppc970, |
212 | .oprofile_cpu_type = "ppc64/970", | 224 | .oprofile_cpu_type = "ppc64/970", |
@@ -239,6 +251,7 @@ static struct cpu_spec cpu_specs[] = { | |||
239 | .icache_bsize = 128, | 251 | .icache_bsize = 128, |
240 | .dcache_bsize = 128, | 252 | .dcache_bsize = 128, |
241 | .num_pmcs = 8, | 253 | .num_pmcs = 8, |
254 | .pmc_type = PPC_PMC_IBM, | ||
242 | .cpu_setup = __setup_cpu_ppc970, | 255 | .cpu_setup = __setup_cpu_ppc970, |
243 | .oprofile_cpu_type = "ppc64/970", | 256 | .oprofile_cpu_type = "ppc64/970", |
244 | .oprofile_type = PPC_OPROFILE_POWER4, | 257 | .oprofile_type = PPC_OPROFILE_POWER4, |
@@ -253,6 +266,7 @@ static struct cpu_spec cpu_specs[] = { | |||
253 | .icache_bsize = 128, | 266 | .icache_bsize = 128, |
254 | .dcache_bsize = 128, | 267 | .dcache_bsize = 128, |
255 | .num_pmcs = 6, | 268 | .num_pmcs = 6, |
269 | .pmc_type = PPC_PMC_IBM, | ||
256 | .oprofile_cpu_type = "ppc64/power5", | 270 | .oprofile_cpu_type = "ppc64/power5", |
257 | .oprofile_type = PPC_OPROFILE_POWER4, | 271 | .oprofile_type = PPC_OPROFILE_POWER4, |
258 | /* SIHV / SIPR bits are implemented on POWER4+ (GQ) | 272 | /* SIHV / SIPR bits are implemented on POWER4+ (GQ) |
@@ -271,6 +285,7 @@ static struct cpu_spec cpu_specs[] = { | |||
271 | .icache_bsize = 128, | 285 | .icache_bsize = 128, |
272 | .dcache_bsize = 128, | 286 | .dcache_bsize = 128, |
273 | .num_pmcs = 6, | 287 | .num_pmcs = 6, |
288 | .pmc_type = PPC_PMC_IBM, | ||
274 | .oprofile_cpu_type = "ppc64/power5+", | 289 | .oprofile_cpu_type = "ppc64/power5+", |
275 | .oprofile_type = PPC_OPROFILE_POWER4, | 290 | .oprofile_type = PPC_OPROFILE_POWER4, |
276 | .oprofile_mmcra_sihv = MMCRA_SIHV, | 291 | .oprofile_mmcra_sihv = MMCRA_SIHV, |
@@ -321,6 +336,7 @@ static struct cpu_spec cpu_specs[] = { | |||
321 | .icache_bsize = 128, | 336 | .icache_bsize = 128, |
322 | .dcache_bsize = 128, | 337 | .dcache_bsize = 128, |
323 | .num_pmcs = 6, | 338 | .num_pmcs = 6, |
339 | .pmc_type = PPC_PMC_IBM, | ||
324 | .oprofile_cpu_type = "ppc64/power6", | 340 | .oprofile_cpu_type = "ppc64/power6", |
325 | .oprofile_type = PPC_OPROFILE_POWER4, | 341 | .oprofile_type = PPC_OPROFILE_POWER4, |
326 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, | 342 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, |
@@ -340,6 +356,7 @@ static struct cpu_spec cpu_specs[] = { | |||
340 | .icache_bsize = 128, | 356 | .icache_bsize = 128, |
341 | .dcache_bsize = 128, | 357 | .dcache_bsize = 128, |
342 | .num_pmcs = 4, | 358 | .num_pmcs = 4, |
359 | .pmc_type = PPC_PMC_IBM, | ||
343 | .oprofile_cpu_type = "ppc64/cell-be", | 360 | .oprofile_cpu_type = "ppc64/cell-be", |
344 | .oprofile_type = PPC_OPROFILE_CELL, | 361 | .oprofile_type = PPC_OPROFILE_CELL, |
345 | .platform = "ppc-cell-be", | 362 | .platform = "ppc-cell-be", |
@@ -353,6 +370,9 @@ static struct cpu_spec cpu_specs[] = { | |||
353 | .icache_bsize = 64, | 370 | .icache_bsize = 64, |
354 | .dcache_bsize = 64, | 371 | .dcache_bsize = 64, |
355 | .num_pmcs = 6, | 372 | .num_pmcs = 6, |
373 | .pmc_type = PPC_PMC_PA6T, | ||
374 | .cpu_setup = __setup_cpu_pa6t, | ||
375 | .cpu_restore = __restore_cpu_pa6t, | ||
356 | .platform = "pa6t", | 376 | .platform = "pa6t", |
357 | }, | 377 | }, |
358 | { /* default match */ | 378 | { /* default match */ |
@@ -364,6 +384,7 @@ static struct cpu_spec cpu_specs[] = { | |||
364 | .icache_bsize = 128, | 384 | .icache_bsize = 128, |
365 | .dcache_bsize = 128, | 385 | .dcache_bsize = 128, |
366 | .num_pmcs = 6, | 386 | .num_pmcs = 6, |
387 | .pmc_type = PPC_PMC_IBM, | ||
367 | .platform = "power4", | 388 | .platform = "power4", |
368 | } | 389 | } |
369 | #endif /* CONFIG_PPC64 */ | 390 | #endif /* CONFIG_PPC64 */ |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2551c0884afc..2b66d53dcc55 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -172,13 +172,18 @@ syscall_error_cont: | |||
172 | stdcx. r0,0,r1 /* to clear the reservation */ | 172 | stdcx. r0,0,r1 /* to clear the reservation */ |
173 | andi. r6,r8,MSR_PR | 173 | andi. r6,r8,MSR_PR |
174 | ld r4,_LINK(r1) | 174 | ld r4,_LINK(r1) |
175 | /* | ||
176 | * Clear RI before restoring r13. If we are returning to | ||
177 | * userspace and we take an exception after restoring r13, | ||
178 | * we end up corrupting the userspace r13 value. | ||
179 | */ | ||
180 | li r12,MSR_RI | ||
181 | andc r11,r10,r12 | ||
182 | mtmsrd r11,1 /* clear MSR.RI */ | ||
175 | beq- 1f | 183 | beq- 1f |
176 | ACCOUNT_CPU_USER_EXIT(r11, r12) | 184 | ACCOUNT_CPU_USER_EXIT(r11, r12) |
177 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ | 185 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ |
178 | 1: ld r2,GPR2(r1) | 186 | 1: ld r2,GPR2(r1) |
179 | li r12,MSR_RI | ||
180 | andc r11,r10,r12 | ||
181 | mtmsrd r11,1 /* clear MSR.RI */ | ||
182 | ld r1,GPR1(r1) | 187 | ld r1,GPR1(r1) |
183 | mtlr r4 | 188 | mtlr r4 |
184 | mtcr r5 | 189 | mtcr r5 |
@@ -488,42 +493,44 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | |||
488 | #endif | 493 | #endif |
489 | stb r5,PACASOFTIRQEN(r13) | 494 | stb r5,PACASOFTIRQEN(r13) |
490 | 495 | ||
496 | /* extract EE bit and use it to restore paca->hard_enabled */ | ||
491 | ld r3,_MSR(r1) | 497 | ld r3,_MSR(r1) |
498 | rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ | ||
499 | stb r4,PACAHARDIRQEN(r13) | ||
500 | |||
501 | ld r4,_CTR(r1) | ||
502 | ld r0,_LINK(r1) | ||
503 | mtctr r4 | ||
504 | mtlr r0 | ||
505 | ld r4,_XER(r1) | ||
506 | mtspr SPRN_XER,r4 | ||
507 | |||
508 | REST_8GPRS(5, r1) | ||
509 | |||
492 | andi. r0,r3,MSR_RI | 510 | andi. r0,r3,MSR_RI |
493 | beq- unrecov_restore | 511 | beq- unrecov_restore |
494 | 512 | ||
495 | /* extract EE bit and use it to restore paca->hard_enabled */ | 513 | stdcx. r0,0,r1 /* to clear the reservation */ |
496 | rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ | ||
497 | stb r4,PACAHARDIRQEN(r13) | ||
498 | 514 | ||
499 | andi. r0,r3,MSR_PR | 515 | /* |
516 | * Clear RI before restoring r13. If we are returning to | ||
517 | * userspace and we take an exception after restoring r13, | ||
518 | * we end up corrupting the userspace r13 value. | ||
519 | */ | ||
520 | mfmsr r4 | ||
521 | andc r4,r4,r0 /* r0 contains MSR_RI here */ | ||
522 | mtmsrd r4,1 | ||
500 | 523 | ||
501 | /* | 524 | /* |
502 | * r13 is our per cpu area, only restore it if we are returning to | 525 | * r13 is our per cpu area, only restore it if we are returning to |
503 | * userspace | 526 | * userspace |
504 | */ | 527 | */ |
528 | andi. r0,r3,MSR_PR | ||
505 | beq 1f | 529 | beq 1f |
506 | ACCOUNT_CPU_USER_EXIT(r3, r4) | 530 | ACCOUNT_CPU_USER_EXIT(r2, r4) |
507 | REST_GPR(13, r1) | 531 | REST_GPR(13, r1) |
508 | 1: | 532 | 1: |
509 | ld r3,_CTR(r1) | 533 | mtspr SPRN_SRR1,r3 |
510 | ld r0,_LINK(r1) | ||
511 | mtctr r3 | ||
512 | mtlr r0 | ||
513 | ld r3,_XER(r1) | ||
514 | mtspr SPRN_XER,r3 | ||
515 | |||
516 | REST_8GPRS(5, r1) | ||
517 | |||
518 | stdcx. r0,0,r1 /* to clear the reservation */ | ||
519 | |||
520 | mfmsr r0 | ||
521 | li r2, MSR_RI | ||
522 | andc r0,r0,r2 | ||
523 | mtmsrd r0,1 | ||
524 | |||
525 | ld r0,_MSR(r1) | ||
526 | mtspr SPRN_SRR1,r0 | ||
527 | 534 | ||
528 | ld r2,_CCR(r1) | 535 | ld r2,_CCR(r1) |
529 | mtcrf 0xFF,r2 | 536 | mtcrf 0xFF,r2 |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 9417cf5b4b7e..c897203198b1 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -344,12 +344,7 @@ i##n: \ | |||
344 | /* System reset */ | 344 | /* System reset */ |
345 | /* core99 pmac starts the seconary here by changing the vector, and | 345 | /* core99 pmac starts the seconary here by changing the vector, and |
346 | putting it back to what it was (unknown_exception) when done. */ | 346 | putting it back to what it was (unknown_exception) when done. */ |
347 | #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) | ||
348 | . = 0x100 | ||
349 | b __secondary_start_gemini | ||
350 | #else | ||
351 | EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) | 347 | EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) |
352 | #endif | ||
353 | 348 | ||
354 | /* Machine check */ | 349 | /* Machine check */ |
355 | /* | 350 | /* |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 71b1fe58e9e4..97cedcd6c9b4 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -613,7 +613,7 @@ system_call_pSeries: | |||
613 | /*** pSeries interrupt support ***/ | 613 | /*** pSeries interrupt support ***/ |
614 | 614 | ||
615 | /* moved from 0xf00 */ | 615 | /* moved from 0xf00 */ |
616 | MASKABLE_EXCEPTION_PSERIES(., performance_monitor) | 616 | STD_EXCEPTION_PSERIES(., performance_monitor) |
617 | 617 | ||
618 | /* | 618 | /* |
619 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 619 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index c68113371050..601ef79a5916 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c | |||
@@ -12,23 +12,23 @@ | |||
12 | * Here comes the ppc64 implementation of the IOMAP | 12 | * Here comes the ppc64 implementation of the IOMAP |
13 | * interfaces. | 13 | * interfaces. |
14 | */ | 14 | */ |
15 | unsigned int fastcall ioread8(void __iomem *addr) | 15 | unsigned int ioread8(void __iomem *addr) |
16 | { | 16 | { |
17 | return readb(addr); | 17 | return readb(addr); |
18 | } | 18 | } |
19 | unsigned int fastcall ioread16(void __iomem *addr) | 19 | unsigned int ioread16(void __iomem *addr) |
20 | { | 20 | { |
21 | return readw(addr); | 21 | return readw(addr); |
22 | } | 22 | } |
23 | unsigned int fastcall ioread16be(void __iomem *addr) | 23 | unsigned int ioread16be(void __iomem *addr) |
24 | { | 24 | { |
25 | return in_be16(addr); | 25 | return in_be16(addr); |
26 | } | 26 | } |
27 | unsigned int fastcall ioread32(void __iomem *addr) | 27 | unsigned int ioread32(void __iomem *addr) |
28 | { | 28 | { |
29 | return readl(addr); | 29 | return readl(addr); |
30 | } | 30 | } |
31 | unsigned int fastcall ioread32be(void __iomem *addr) | 31 | unsigned int ioread32be(void __iomem *addr) |
32 | { | 32 | { |
33 | return in_be32(addr); | 33 | return in_be32(addr); |
34 | } | 34 | } |
@@ -38,23 +38,23 @@ EXPORT_SYMBOL(ioread16be); | |||
38 | EXPORT_SYMBOL(ioread32); | 38 | EXPORT_SYMBOL(ioread32); |
39 | EXPORT_SYMBOL(ioread32be); | 39 | EXPORT_SYMBOL(ioread32be); |
40 | 40 | ||
41 | void fastcall iowrite8(u8 val, void __iomem *addr) | 41 | void iowrite8(u8 val, void __iomem *addr) |
42 | { | 42 | { |
43 | writeb(val, addr); | 43 | writeb(val, addr); |
44 | } | 44 | } |
45 | void fastcall iowrite16(u16 val, void __iomem *addr) | 45 | void iowrite16(u16 val, void __iomem *addr) |
46 | { | 46 | { |
47 | writew(val, addr); | 47 | writew(val, addr); |
48 | } | 48 | } |
49 | void fastcall iowrite16be(u16 val, void __iomem *addr) | 49 | void iowrite16be(u16 val, void __iomem *addr) |
50 | { | 50 | { |
51 | out_be16(addr, val); | 51 | out_be16(addr, val); |
52 | } | 52 | } |
53 | void fastcall iowrite32(u32 val, void __iomem *addr) | 53 | void iowrite32(u32 val, void __iomem *addr) |
54 | { | 54 | { |
55 | writel(val, addr); | 55 | writel(val, addr); |
56 | } | 56 | } |
57 | void fastcall iowrite32be(u32 val, void __iomem *addr) | 57 | void iowrite32be(u32 val, void __iomem *addr) |
58 | { | 58 | { |
59 | out_be32(addr, val); | 59 | out_be32(addr, val); |
60 | } | 60 | } |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 0bd8c7665834..919fbf568495 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -281,10 +281,10 @@ void do_IRQ(struct pt_regs *regs) | |||
281 | 281 | ||
282 | /* | 282 | /* |
283 | * Every platform is required to implement ppc_md.get_irq. | 283 | * Every platform is required to implement ppc_md.get_irq. |
284 | * This function will either return an irq number or -1 to | 284 | * This function will either return an irq number or NO_IRQ to |
285 | * indicate there are no more pending. | 285 | * indicate there are no more pending. |
286 | * The value -2 is for buggy hardware and means that this IRQ | 286 | * The value NO_IRQ_IGNORE is for buggy hardware and means that this |
287 | * has already been handled. -- Tom | 287 | * IRQ has already been handled. -- Tom |
288 | */ | 288 | */ |
289 | irq = ppc_md.get_irq(); | 289 | irq = ppc_md.get_irq(); |
290 | 290 | ||
@@ -604,6 +604,8 @@ unsigned int irq_create_mapping(struct irq_host *host, | |||
604 | */ | 604 | */ |
605 | virq = irq_find_mapping(host, hwirq); | 605 | virq = irq_find_mapping(host, hwirq); |
606 | if (virq != IRQ_NONE) { | 606 | if (virq != IRQ_NONE) { |
607 | if (host->ops->remap) | ||
608 | host->ops->remap(host, virq, hwirq); | ||
607 | pr_debug("irq: -> existing mapping on virq %d\n", virq); | 609 | pr_debug("irq: -> existing mapping on virq %d\n", virq); |
608 | return virq; | 610 | return virq; |
609 | } | 611 | } |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 4657563f8813..dd2886f97e98 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
46 | if ((unsigned long)p->addr & 0x03) { | 46 | if ((unsigned long)p->addr & 0x03) { |
47 | printk("Attempt to register kprobe at an unaligned address\n"); | 47 | printk("Attempt to register kprobe at an unaligned address\n"); |
48 | ret = -EINVAL; | 48 | ret = -EINVAL; |
49 | } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { | 49 | } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) { |
50 | printk("Cannot register a kprobe on rfid or mtmsrd\n"); | 50 | printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n"); |
51 | ret = -EINVAL; | 51 | ret = -EINVAL; |
52 | } | 52 | } |
53 | 53 | ||
@@ -483,8 +483,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
483 | memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); | 483 | memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); |
484 | 484 | ||
485 | /* setup return addr to the jprobe handler routine */ | 485 | /* setup return addr to the jprobe handler routine */ |
486 | #ifdef CONFIG_PPC64 | ||
486 | regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); | 487 | regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); |
487 | regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); | 488 | regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); |
489 | #else | ||
490 | regs->nip = (unsigned long)jp->entry; | ||
491 | #endif | ||
488 | 492 | ||
489 | return 1; | 493 | return 1; |
490 | } | 494 | } |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 41c05dcd68f4..0de5a08cf9b0 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -439,6 +439,10 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, | |||
439 | 439 | ||
440 | ssize_t retval = -ENOMEM; | 440 | ssize_t retval = -ENOMEM; |
441 | 441 | ||
442 | if (!firmware_has_feature(FW_FEATURE_SPLPAR) || | ||
443 | firmware_has_feature(FW_FEATURE_ISERIES)) | ||
444 | return -EINVAL; | ||
445 | |||
442 | kbuf = kmalloc(count, GFP_KERNEL); | 446 | kbuf = kmalloc(count, GFP_KERNEL); |
443 | if (!kbuf) | 447 | if (!kbuf) |
444 | goto out; | 448 | goto out; |
@@ -517,7 +521,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) | |||
517 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | 521 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, |
518 | size_t count, loff_t * off) | 522 | size_t count, loff_t * off) |
519 | { | 523 | { |
520 | return count; | 524 | return -EINVAL; |
521 | } | 525 | } |
522 | 526 | ||
523 | #endif /* CONFIG_PPC_PSERIES */ | 527 | #endif /* CONFIG_PPC_PSERIES */ |
@@ -570,6 +574,7 @@ static int lparcfg_open(struct inode *inode, struct file *file) | |||
570 | struct file_operations lparcfg_fops = { | 574 | struct file_operations lparcfg_fops = { |
571 | .owner = THIS_MODULE, | 575 | .owner = THIS_MODULE, |
572 | .read = seq_read, | 576 | .read = seq_read, |
577 | .write = lparcfg_write, | ||
573 | .open = lparcfg_open, | 578 | .open = lparcfg_open, |
574 | .release = single_release, | 579 | .release = single_release, |
575 | }; | 580 | }; |
@@ -581,10 +586,8 @@ int __init lparcfg_init(void) | |||
581 | 586 | ||
582 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 587 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
583 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && | 588 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && |
584 | !firmware_has_feature(FW_FEATURE_ISERIES)) { | 589 | !firmware_has_feature(FW_FEATURE_ISERIES)) |
585 | lparcfg_fops.write = lparcfg_write; | ||
586 | mode |= S_IWUSR; | 590 | mode |= S_IWUSR; |
587 | } | ||
588 | 591 | ||
589 | ent = create_proc_entry("ppc64/lparcfg", mode, NULL); | 592 | ent = create_proc_entry("ppc64/lparcfg", mode, NULL); |
590 | if (ent) { | 593 | if (ent) { |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 21fd2c662a99..519861da0423 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -311,6 +311,46 @@ _GLOBAL(real_writeb) | |||
311 | blr | 311 | blr |
312 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ | 312 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ |
313 | 313 | ||
314 | #ifdef CONFIG_PPC_PASEMI | ||
315 | |||
316 | /* No support in all binutils for these yet, so use defines */ | ||
317 | #define LBZCIX(RT,RA,RB) .long (0x7c0006aa|(RT<<21)|(RA<<16)|(RB << 11)) | ||
318 | #define STBCIX(RS,RA,RB) .long (0x7c0007aa|(RS<<21)|(RA<<16)|(RB << 11)) | ||
319 | |||
320 | |||
321 | _GLOBAL(real_205_readb) | ||
322 | mfmsr r7 | ||
323 | ori r0,r7,MSR_DR | ||
324 | xori r0,r0,MSR_DR | ||
325 | sync | ||
326 | mtmsrd r0 | ||
327 | sync | ||
328 | isync | ||
329 | LBZCIX(r3,0,r3) | ||
330 | isync | ||
331 | mtmsrd r7 | ||
332 | sync | ||
333 | isync | ||
334 | blr | ||
335 | |||
336 | _GLOBAL(real_205_writeb) | ||
337 | mfmsr r7 | ||
338 | ori r0,r7,MSR_DR | ||
339 | xori r0,r0,MSR_DR | ||
340 | sync | ||
341 | mtmsrd r0 | ||
342 | sync | ||
343 | isync | ||
344 | STBCIX(r3,0,r4) | ||
345 | isync | ||
346 | mtmsrd r7 | ||
347 | sync | ||
348 | isync | ||
349 | blr | ||
350 | |||
351 | #endif /* CONFIG_PPC_PASEMI */ | ||
352 | |||
353 | |||
314 | #ifdef CONFIG_CPU_FREQ_PMAC64 | 354 | #ifdef CONFIG_CPU_FREQ_PMAC64 |
315 | /* | 355 | /* |
316 | * SCOM access functions for 970 (FX only for now) | 356 | * SCOM access functions for 970 (FX only for now) |
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 8339fd609de0..07a89a398639 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c | |||
@@ -224,7 +224,12 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
224 | /* Low half of the symbol */ | 224 | /* Low half of the symbol */ |
225 | *(uint16_t *)location = value; | 225 | *(uint16_t *)location = value; |
226 | break; | 226 | break; |
227 | 227 | ||
228 | case R_PPC_ADDR16_HI: | ||
229 | /* Higher half of the symbol */ | ||
230 | *(uint16_t *)location = (value >> 16); | ||
231 | break; | ||
232 | |||
228 | case R_PPC_ADDR16_HA: | 233 | case R_PPC_ADDR16_HA: |
229 | /* Sign-adjusted lower 16 bits: PPC ELF ABI says: | 234 | /* Sign-adjusted lower 16 bits: PPC ELF ABI says: |
230 | (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. | 235 | (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. |
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index c54f3639c5ad..d8ef2e100505 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -1450,7 +1450,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1450 | return -1; | 1450 | return -1; |
1451 | } | 1451 | } |
1452 | pci_dev->irq = virq; | 1452 | pci_dev->irq = virq; |
1453 | pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); | ||
1454 | 1453 | ||
1455 | return 0; | 1454 | return 0; |
1456 | } | 1455 | } |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2b52b087aaa8..7e97d71a5f8f 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -1323,7 +1323,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1323 | DBG(" -> mapped to linux irq %d\n", virq); | 1323 | DBG(" -> mapped to linux irq %d\n", virq); |
1324 | 1324 | ||
1325 | pci_dev->irq = virq; | 1325 | pci_dev->irq = virq; |
1326 | pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); | ||
1327 | 1326 | ||
1328 | return 0; | 1327 | return 0; |
1329 | } | 1328 | } |
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index 3d8f6f44641e..24d7b7c99bb9 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c | |||
@@ -17,40 +17,25 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
20 | #include <asm/cputable.h> | ||
20 | #include <asm/pmc.h> | 21 | #include <asm/pmc.h> |
21 | 22 | ||
22 | #if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) | 23 | #ifndef MMCR0_PMA0 |
23 | static void dummy_perf(struct pt_regs *regs) | 24 | #define MMCR0_PMA0 0 |
24 | { | ||
25 | unsigned int pmgc0 = mfpmr(PMRN_PMGC0); | ||
26 | |||
27 | pmgc0 &= ~PMGC0_PMIE; | ||
28 | mtpmr(PMRN_PMGC0, pmgc0); | ||
29 | } | ||
30 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) | ||
31 | |||
32 | #ifndef MMCR0_PMAO | ||
33 | #define MMCR0_PMAO 0 | ||
34 | #endif | 25 | #endif |
35 | 26 | ||
36 | /* Ensure exceptions are disabled */ | ||
37 | static void dummy_perf(struct pt_regs *regs) | 27 | static void dummy_perf(struct pt_regs *regs) |
38 | { | 28 | { |
39 | unsigned int mmcr0 = mfspr(SPRN_MMCR0); | 29 | #if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) |
40 | 30 | mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); | |
41 | mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO); | 31 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) |
42 | mtspr(SPRN_MMCR0, mmcr0); | 32 | if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) |
43 | } | 33 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0)); |
44 | #else | 34 | #else |
45 | /* Ensure exceptions are disabled */ | 35 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); |
46 | static void dummy_perf(struct pt_regs *regs) | ||
47 | { | ||
48 | unsigned int mmcr0 = mfspr(SPRN_MMCR0); | ||
49 | |||
50 | mmcr0 &= ~(MMCR0_PMXE); | ||
51 | mtspr(SPRN_MMCR0, mmcr0); | ||
52 | } | ||
53 | #endif | 36 | #endif |
37 | } | ||
38 | |||
54 | 39 | ||
55 | static DEFINE_SPINLOCK(pmc_owner_lock); | 40 | static DEFINE_SPINLOCK(pmc_owner_lock); |
56 | static void *pmc_owner_caller; /* mostly for debugging */ | 41 | static void *pmc_owner_caller; /* mostly for debugging */ |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 95776b6af4e2..ecee596d28f6 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/btext.h> | 44 | #include <asm/btext.h> |
45 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
46 | #include <asm/signal.h> | 46 | #include <asm/signal.h> |
47 | #include <asm/dcr.h> | ||
47 | 48 | ||
48 | #ifdef CONFIG_8xx | 49 | #ifdef CONFIG_8xx |
49 | #include <asm/commproc.h> | 50 | #include <asm/commproc.h> |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 1fc732a552db..3be52d693eca 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1221,8 +1221,7 @@ struct device_node *of_find_node_by_name(struct device_node *from, | |||
1221 | if (np->name != NULL && strcasecmp(np->name, name) == 0 | 1221 | if (np->name != NULL && strcasecmp(np->name, name) == 0 |
1222 | && of_node_get(np)) | 1222 | && of_node_get(np)) |
1223 | break; | 1223 | break; |
1224 | if (from) | 1224 | of_node_put(from); |
1225 | of_node_put(from); | ||
1226 | read_unlock(&devtree_lock); | 1225 | read_unlock(&devtree_lock); |
1227 | return np; | 1226 | return np; |
1228 | } | 1227 | } |
@@ -1250,8 +1249,7 @@ struct device_node *of_find_node_by_type(struct device_node *from, | |||
1250 | if (np->type != 0 && strcasecmp(np->type, type) == 0 | 1249 | if (np->type != 0 && strcasecmp(np->type, type) == 0 |
1251 | && of_node_get(np)) | 1250 | && of_node_get(np)) |
1252 | break; | 1251 | break; |
1253 | if (from) | 1252 | of_node_put(from); |
1254 | of_node_put(from); | ||
1255 | read_unlock(&devtree_lock); | 1253 | read_unlock(&devtree_lock); |
1256 | return np; | 1254 | return np; |
1257 | } | 1255 | } |
@@ -1285,8 +1283,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
1285 | if (device_is_compatible(np, compatible) && of_node_get(np)) | 1283 | if (device_is_compatible(np, compatible) && of_node_get(np)) |
1286 | break; | 1284 | break; |
1287 | } | 1285 | } |
1288 | if (from) | 1286 | of_node_put(from); |
1289 | of_node_put(from); | ||
1290 | read_unlock(&devtree_lock); | 1287 | read_unlock(&devtree_lock); |
1291 | return np; | 1288 | return np; |
1292 | } | 1289 | } |
@@ -1329,8 +1326,7 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
1329 | for (np = allnodes; np != 0; np = np->allnext) | 1326 | for (np = allnodes; np != 0; np = np->allnext) |
1330 | if (np->linux_phandle == handle) | 1327 | if (np->linux_phandle == handle) |
1331 | break; | 1328 | break; |
1332 | if (np) | 1329 | of_node_get(np); |
1333 | of_node_get(np); | ||
1334 | read_unlock(&devtree_lock); | 1330 | read_unlock(&devtree_lock); |
1335 | return np; | 1331 | return np; |
1336 | } | 1332 | } |
@@ -1353,8 +1349,7 @@ struct device_node *of_find_all_nodes(struct device_node *prev) | |||
1353 | for (; np != 0; np = np->allnext) | 1349 | for (; np != 0; np = np->allnext) |
1354 | if (of_node_get(np)) | 1350 | if (of_node_get(np)) |
1355 | break; | 1351 | break; |
1356 | if (prev) | 1352 | of_node_put(prev); |
1357 | of_node_put(prev); | ||
1358 | read_unlock(&devtree_lock); | 1353 | read_unlock(&devtree_lock); |
1359 | return np; | 1354 | return np; |
1360 | } | 1355 | } |
@@ -1399,8 +1394,7 @@ struct device_node *of_get_next_child(const struct device_node *node, | |||
1399 | for (; next != 0; next = next->sibling) | 1394 | for (; next != 0; next = next->sibling) |
1400 | if (of_node_get(next)) | 1395 | if (of_node_get(next)) |
1401 | break; | 1396 | break; |
1402 | if (prev) | 1397 | of_node_put(prev); |
1403 | of_node_put(prev); | ||
1404 | read_unlock(&devtree_lock); | 1398 | read_unlock(&devtree_lock); |
1405 | return next; | 1399 | return next; |
1406 | } | 1400 | } |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 975102a020d9..cc44c7b975aa 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -532,16 +532,22 @@ void do_syscall_trace_enter(struct pt_regs *regs) | |||
532 | && (current->ptrace & PT_PTRACED)) | 532 | && (current->ptrace & PT_PTRACED)) |
533 | do_syscall_trace(); | 533 | do_syscall_trace(); |
534 | 534 | ||
535 | if (unlikely(current->audit_context)) | 535 | if (unlikely(current->audit_context)) { |
536 | audit_syscall_entry( | 536 | #ifdef CONFIG_PPC64 |
537 | #ifdef CONFIG_PPC32 | 537 | if (!test_thread_flag(TIF_32BIT)) |
538 | AUDIT_ARCH_PPC, | 538 | audit_syscall_entry(AUDIT_ARCH_PPC64, |
539 | #else | 539 | regs->gpr[0], |
540 | test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, | 540 | regs->gpr[3], regs->gpr[4], |
541 | regs->gpr[5], regs->gpr[6]); | ||
542 | else | ||
541 | #endif | 543 | #endif |
542 | regs->gpr[0], | 544 | audit_syscall_entry(AUDIT_ARCH_PPC, |
543 | regs->gpr[3], regs->gpr[4], | 545 | regs->gpr[0], |
544 | regs->gpr[5], regs->gpr[6]); | 546 | regs->gpr[3] & 0xffffffff, |
547 | regs->gpr[4] & 0xffffffff, | ||
548 | regs->gpr[5] & 0xffffffff, | ||
549 | regs->gpr[6] & 0xffffffff); | ||
550 | } | ||
545 | } | 551 | } |
546 | 552 | ||
547 | void do_syscall_trace_leave(struct pt_regs *regs) | 553 | void do_syscall_trace_leave(struct pt_regs *regs) |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 61c65d19ef06..6a19fa40dcee 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -65,6 +65,7 @@ int have_of = 1; | |||
65 | 65 | ||
66 | #ifdef CONFIG_VGA_CONSOLE | 66 | #ifdef CONFIG_VGA_CONSOLE |
67 | unsigned long vgacon_remap_base; | 67 | unsigned long vgacon_remap_base; |
68 | EXPORT_SYMBOL(vgacon_remap_base); | ||
68 | #endif | 69 | #endif |
69 | 70 | ||
70 | /* | 71 | /* |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 400ab2b946e7..d57818aea081 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -169,6 +169,11 @@ static ssize_t __attribute_used__ \ | |||
169 | return count; \ | 169 | return count; \ |
170 | } | 170 | } |
171 | 171 | ||
172 | |||
173 | /* Let's define all possible registers, we'll only hook up the ones | ||
174 | * that are implemented on the current processor | ||
175 | */ | ||
176 | |||
172 | SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); | 177 | SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); |
173 | SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); | 178 | SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); |
174 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); | 179 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); |
@@ -184,55 +189,87 @@ SYSFS_PMCSETUP(purr, SPRN_PURR); | |||
184 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); | 189 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); |
185 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); | 190 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); |
186 | 191 | ||
187 | static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); | 192 | SYSFS_PMCSETUP(pa6t_pmc0, PA6T_SPRN_PMC0); |
188 | static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); | 193 | SYSFS_PMCSETUP(pa6t_pmc1, PA6T_SPRN_PMC1); |
194 | SYSFS_PMCSETUP(pa6t_pmc2, PA6T_SPRN_PMC2); | ||
195 | SYSFS_PMCSETUP(pa6t_pmc3, PA6T_SPRN_PMC3); | ||
196 | SYSFS_PMCSETUP(pa6t_pmc4, PA6T_SPRN_PMC4); | ||
197 | SYSFS_PMCSETUP(pa6t_pmc5, PA6T_SPRN_PMC5); | ||
198 | |||
199 | |||
189 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); | 200 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); |
190 | static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1); | ||
191 | static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2); | ||
192 | static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3); | ||
193 | static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4); | ||
194 | static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5); | ||
195 | static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); | ||
196 | static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); | ||
197 | static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); | ||
198 | static SYSDEV_ATTR(purr, 0600, show_purr, NULL); | ||
199 | static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); | 201 | static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); |
200 | static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); | 202 | static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); |
203 | static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); | ||
204 | |||
205 | static struct sysdev_attribute ibm_common_attrs[] = { | ||
206 | _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), | ||
207 | _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), | ||
208 | }; | ||
209 | |||
210 | static struct sysdev_attribute ibm_pmc_attrs[] = { | ||
211 | _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1), | ||
212 | _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2), | ||
213 | _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3), | ||
214 | _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4), | ||
215 | _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5), | ||
216 | _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6), | ||
217 | _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7), | ||
218 | _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8), | ||
219 | }; | ||
220 | |||
221 | static struct sysdev_attribute pa6t_attrs[] = { | ||
222 | _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), | ||
223 | _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), | ||
224 | _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0), | ||
225 | _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1), | ||
226 | _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2), | ||
227 | _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3), | ||
228 | _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4), | ||
229 | _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5), | ||
230 | }; | ||
231 | |||
201 | 232 | ||
202 | static void register_cpu_online(unsigned int cpu) | 233 | static void register_cpu_online(unsigned int cpu) |
203 | { | 234 | { |
204 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 235 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
205 | struct sys_device *s = &c->sysdev; | 236 | struct sys_device *s = &c->sysdev; |
237 | struct sysdev_attribute *attrs, *pmc_attrs; | ||
238 | int i, nattrs; | ||
206 | 239 | ||
207 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && | 240 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && |
208 | cpu_has_feature(CPU_FTR_SMT)) | 241 | cpu_has_feature(CPU_FTR_SMT)) |
209 | sysdev_create_file(s, &attr_smt_snooze_delay); | 242 | sysdev_create_file(s, &attr_smt_snooze_delay); |
210 | 243 | ||
211 | /* PMC stuff */ | 244 | /* PMC stuff */ |
245 | switch (cur_cpu_spec->pmc_type) { | ||
246 | case PPC_PMC_IBM: | ||
247 | attrs = ibm_common_attrs; | ||
248 | nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); | ||
249 | pmc_attrs = ibm_pmc_attrs; | ||
250 | break; | ||
251 | case PPC_PMC_PA6T: | ||
252 | /* PA Semi starts counting at PMC0 */ | ||
253 | attrs = pa6t_attrs; | ||
254 | nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); | ||
255 | pmc_attrs = NULL; | ||
256 | break; | ||
257 | default: | ||
258 | attrs = NULL; | ||
259 | nattrs = 0; | ||
260 | pmc_attrs = NULL; | ||
261 | } | ||
262 | |||
263 | for (i = 0; i < nattrs; i++) | ||
264 | sysdev_create_file(s, &attrs[i]); | ||
212 | 265 | ||
213 | sysdev_create_file(s, &attr_mmcr0); | 266 | if (pmc_attrs) |
214 | sysdev_create_file(s, &attr_mmcr1); | 267 | for (i = 0; i < cur_cpu_spec->num_pmcs; i++) |
268 | sysdev_create_file(s, &pmc_attrs[i]); | ||
215 | 269 | ||
216 | if (cpu_has_feature(CPU_FTR_MMCRA)) | 270 | if (cpu_has_feature(CPU_FTR_MMCRA)) |
217 | sysdev_create_file(s, &attr_mmcra); | 271 | sysdev_create_file(s, &attr_mmcra); |
218 | 272 | ||
219 | if (cur_cpu_spec->num_pmcs >= 1) | ||
220 | sysdev_create_file(s, &attr_pmc1); | ||
221 | if (cur_cpu_spec->num_pmcs >= 2) | ||
222 | sysdev_create_file(s, &attr_pmc2); | ||
223 | if (cur_cpu_spec->num_pmcs >= 3) | ||
224 | sysdev_create_file(s, &attr_pmc3); | ||
225 | if (cur_cpu_spec->num_pmcs >= 4) | ||
226 | sysdev_create_file(s, &attr_pmc4); | ||
227 | if (cur_cpu_spec->num_pmcs >= 5) | ||
228 | sysdev_create_file(s, &attr_pmc5); | ||
229 | if (cur_cpu_spec->num_pmcs >= 6) | ||
230 | sysdev_create_file(s, &attr_pmc6); | ||
231 | if (cur_cpu_spec->num_pmcs >= 7) | ||
232 | sysdev_create_file(s, &attr_pmc7); | ||
233 | if (cur_cpu_spec->num_pmcs >= 8) | ||
234 | sysdev_create_file(s, &attr_pmc8); | ||
235 | |||
236 | if (cpu_has_feature(CPU_FTR_PURR)) | 273 | if (cpu_has_feature(CPU_FTR_PURR)) |
237 | sysdev_create_file(s, &attr_purr); | 274 | sysdev_create_file(s, &attr_purr); |
238 | 275 | ||
@@ -248,6 +285,8 @@ static void unregister_cpu_online(unsigned int cpu) | |||
248 | { | 285 | { |
249 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 286 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
250 | struct sys_device *s = &c->sysdev; | 287 | struct sys_device *s = &c->sysdev; |
288 | struct sysdev_attribute *attrs, *pmc_attrs; | ||
289 | int i, nattrs; | ||
251 | 290 | ||
252 | BUG_ON(!c->hotpluggable); | 291 | BUG_ON(!c->hotpluggable); |
253 | 292 | ||
@@ -256,30 +295,34 @@ static void unregister_cpu_online(unsigned int cpu) | |||
256 | sysdev_remove_file(s, &attr_smt_snooze_delay); | 295 | sysdev_remove_file(s, &attr_smt_snooze_delay); |
257 | 296 | ||
258 | /* PMC stuff */ | 297 | /* PMC stuff */ |
298 | switch (cur_cpu_spec->pmc_type) { | ||
299 | case PPC_PMC_IBM: | ||
300 | attrs = ibm_common_attrs; | ||
301 | nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); | ||
302 | pmc_attrs = ibm_pmc_attrs; | ||
303 | break; | ||
304 | case PPC_PMC_PA6T: | ||
305 | /* PA Semi starts counting at PMC0 */ | ||
306 | attrs = pa6t_attrs; | ||
307 | nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); | ||
308 | pmc_attrs = NULL; | ||
309 | break; | ||
310 | default: | ||
311 | attrs = NULL; | ||
312 | nattrs = 0; | ||
313 | pmc_attrs = NULL; | ||
314 | } | ||
259 | 315 | ||
260 | sysdev_remove_file(s, &attr_mmcr0); | 316 | for (i = 0; i < nattrs; i++) |
261 | sysdev_remove_file(s, &attr_mmcr1); | 317 | sysdev_remove_file(s, &attrs[i]); |
318 | |||
319 | if (pmc_attrs) | ||
320 | for (i = 0; i < cur_cpu_spec->num_pmcs; i++) | ||
321 | sysdev_remove_file(s, &pmc_attrs[i]); | ||
262 | 322 | ||
263 | if (cpu_has_feature(CPU_FTR_MMCRA)) | 323 | if (cpu_has_feature(CPU_FTR_MMCRA)) |
264 | sysdev_remove_file(s, &attr_mmcra); | 324 | sysdev_remove_file(s, &attr_mmcra); |
265 | 325 | ||
266 | if (cur_cpu_spec->num_pmcs >= 1) | ||
267 | sysdev_remove_file(s, &attr_pmc1); | ||
268 | if (cur_cpu_spec->num_pmcs >= 2) | ||
269 | sysdev_remove_file(s, &attr_pmc2); | ||
270 | if (cur_cpu_spec->num_pmcs >= 3) | ||
271 | sysdev_remove_file(s, &attr_pmc3); | ||
272 | if (cur_cpu_spec->num_pmcs >= 4) | ||
273 | sysdev_remove_file(s, &attr_pmc4); | ||
274 | if (cur_cpu_spec->num_pmcs >= 5) | ||
275 | sysdev_remove_file(s, &attr_pmc5); | ||
276 | if (cur_cpu_spec->num_pmcs >= 6) | ||
277 | sysdev_remove_file(s, &attr_pmc6); | ||
278 | if (cur_cpu_spec->num_pmcs >= 7) | ||
279 | sysdev_remove_file(s, &attr_pmc7); | ||
280 | if (cur_cpu_spec->num_pmcs >= 8) | ||
281 | sysdev_remove_file(s, &attr_pmc8); | ||
282 | |||
283 | if (cpu_has_feature(CPU_FTR_PURR)) | 326 | if (cpu_has_feature(CPU_FTR_PURR)) |
284 | sysdev_remove_file(s, &attr_purr); | 327 | sysdev_remove_file(s, &attr_purr); |
285 | 328 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 535f50665647..dcc6f159fd94 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -174,7 +174,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | |||
174 | * generate the same exception over and over again and we get | 174 | * generate the same exception over and over again and we get |
175 | * nowhere. Better to kill it and let the kernel panic. | 175 | * nowhere. Better to kill it and let the kernel panic. |
176 | */ | 176 | */ |
177 | if (current->pid == 1) { | 177 | if (is_init(current)) { |
178 | __sighandler_t handler; | 178 | __sighandler_t handler; |
179 | 179 | ||
180 | spin_lock_irq(¤t->sighand->siglock); | 180 | spin_lock_irq(¤t->sighand->siglock); |
@@ -535,34 +535,40 @@ static void emulate_single_step(struct pt_regs *regs) | |||
535 | } | 535 | } |
536 | } | 536 | } |
537 | 537 | ||
538 | static void parse_fpe(struct pt_regs *regs) | 538 | static inline int __parse_fpscr(unsigned long fpscr) |
539 | { | 539 | { |
540 | int code = 0; | 540 | int ret = 0; |
541 | unsigned long fpscr; | ||
542 | |||
543 | flush_fp_to_thread(current); | ||
544 | |||
545 | fpscr = current->thread.fpscr.val; | ||
546 | 541 | ||
547 | /* Invalid operation */ | 542 | /* Invalid operation */ |
548 | if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) | 543 | if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) |
549 | code = FPE_FLTINV; | 544 | ret = FPE_FLTINV; |
550 | 545 | ||
551 | /* Overflow */ | 546 | /* Overflow */ |
552 | else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) | 547 | else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX)) |
553 | code = FPE_FLTOVF; | 548 | ret = FPE_FLTOVF; |
554 | 549 | ||
555 | /* Underflow */ | 550 | /* Underflow */ |
556 | else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) | 551 | else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX)) |
557 | code = FPE_FLTUND; | 552 | ret = FPE_FLTUND; |
558 | 553 | ||
559 | /* Divide by zero */ | 554 | /* Divide by zero */ |
560 | else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) | 555 | else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX)) |
561 | code = FPE_FLTDIV; | 556 | ret = FPE_FLTDIV; |
562 | 557 | ||
563 | /* Inexact result */ | 558 | /* Inexact result */ |
564 | else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) | 559 | else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX)) |
565 | code = FPE_FLTRES; | 560 | ret = FPE_FLTRES; |
561 | |||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | static void parse_fpe(struct pt_regs *regs) | ||
566 | { | ||
567 | int code = 0; | ||
568 | |||
569 | flush_fp_to_thread(current); | ||
570 | |||
571 | code = __parse_fpscr(current->thread.fpscr.val); | ||
566 | 572 | ||
567 | _exception(SIGFPE, regs, code, regs->nip); | 573 | _exception(SIGFPE, regs, code, regs->nip); |
568 | } | 574 | } |
@@ -739,20 +745,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
739 | extern int do_mathemu(struct pt_regs *regs); | 745 | extern int do_mathemu(struct pt_regs *regs); |
740 | 746 | ||
741 | /* We can now get here via a FP Unavailable exception if the core | 747 | /* We can now get here via a FP Unavailable exception if the core |
742 | * has no FPU, in that case no reason flags will be set */ | 748 | * has no FPU, in that case the reason flags will be 0 */ |
743 | #ifdef CONFIG_MATH_EMULATION | ||
744 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, | ||
745 | * but there seems to be a hardware bug on the 405GP (RevD) | ||
746 | * that means ESR is sometimes set incorrectly - either to | ||
747 | * ESR_DST (!?) or 0. In the process of chasing this with the | ||
748 | * hardware people - not sure if it can happen on any illegal | ||
749 | * instruction or only on FP instructions, whether there is a | ||
750 | * pattern to occurences etc. -dgibson 31/Mar/2003 */ | ||
751 | if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) { | ||
752 | emulate_single_step(regs); | ||
753 | return; | ||
754 | } | ||
755 | #endif /* CONFIG_MATH_EMULATION */ | ||
756 | 749 | ||
757 | if (reason & REASON_FP) { | 750 | if (reason & REASON_FP) { |
758 | /* IEEE FP exception */ | 751 | /* IEEE FP exception */ |
@@ -778,6 +771,31 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
778 | 771 | ||
779 | local_irq_enable(); | 772 | local_irq_enable(); |
780 | 773 | ||
774 | #ifdef CONFIG_MATH_EMULATION | ||
775 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, | ||
776 | * but there seems to be a hardware bug on the 405GP (RevD) | ||
777 | * that means ESR is sometimes set incorrectly - either to | ||
778 | * ESR_DST (!?) or 0. In the process of chasing this with the | ||
779 | * hardware people - not sure if it can happen on any illegal | ||
780 | * instruction or only on FP instructions, whether there is a | ||
781 | * pattern to occurences etc. -dgibson 31/Mar/2003 */ | ||
782 | switch (do_mathemu(regs)) { | ||
783 | case 0: | ||
784 | emulate_single_step(regs); | ||
785 | return; | ||
786 | case 1: { | ||
787 | int code = 0; | ||
788 | code = __parse_fpscr(current->thread.fpscr.val); | ||
789 | _exception(SIGFPE, regs, code, regs->nip); | ||
790 | return; | ||
791 | } | ||
792 | case -EFAULT: | ||
793 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | ||
794 | return; | ||
795 | } | ||
796 | /* fall through on any other errors */ | ||
797 | #endif /* CONFIG_MATH_EMULATION */ | ||
798 | |||
781 | /* Try to emulate it if we should. */ | 799 | /* Try to emulate it if we should. */ |
782 | if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { | 800 | if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { |
783 | switch (emulate_instruction(regs)) { | 801 | switch (emulate_instruction(regs)) { |
@@ -891,18 +909,39 @@ void SoftwareEmulation(struct pt_regs *regs) | |||
891 | 909 | ||
892 | #ifdef CONFIG_MATH_EMULATION | 910 | #ifdef CONFIG_MATH_EMULATION |
893 | errcode = do_mathemu(regs); | 911 | errcode = do_mathemu(regs); |
912 | |||
913 | switch (errcode) { | ||
914 | case 0: | ||
915 | emulate_single_step(regs); | ||
916 | return; | ||
917 | case 1: { | ||
918 | int code = 0; | ||
919 | code = __parse_fpscr(current->thread.fpscr.val); | ||
920 | _exception(SIGFPE, regs, code, regs->nip); | ||
921 | return; | ||
922 | } | ||
923 | case -EFAULT: | ||
924 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | ||
925 | return; | ||
926 | default: | ||
927 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | ||
928 | return; | ||
929 | } | ||
930 | |||
894 | #else | 931 | #else |
895 | errcode = Soft_emulate_8xx(regs); | 932 | errcode = Soft_emulate_8xx(regs); |
896 | #endif | 933 | switch (errcode) { |
897 | if (errcode) { | 934 | case 0: |
898 | if (errcode > 0) | ||
899 | _exception(SIGFPE, regs, 0, 0); | ||
900 | else if (errcode == -EFAULT) | ||
901 | _exception(SIGSEGV, regs, 0, 0); | ||
902 | else | ||
903 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | ||
904 | } else | ||
905 | emulate_single_step(regs); | 935 | emulate_single_step(regs); |
936 | return; | ||
937 | case 1: | ||
938 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | ||
939 | return; | ||
940 | case -EFAULT: | ||
941 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | ||
942 | return; | ||
943 | } | ||
944 | #endif | ||
906 | } | 945 | } |
907 | #endif /* CONFIG_8xx */ | 946 | #endif /* CONFIG_8xx */ |
908 | 947 | ||
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 5730906b23d5..8f5afdbad0d5 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -45,6 +45,10 @@ void __init udbg_early_init(void) | |||
45 | #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES) | 45 | #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES) |
46 | /* For iSeries - hit Ctrl-x Ctrl-x to see the output */ | 46 | /* For iSeries - hit Ctrl-x Ctrl-x to see the output */ |
47 | udbg_init_iseries(); | 47 | udbg_init_iseries(); |
48 | #elif defined(CONFIG_PPC_EARLY_DEBUG_BEAT) | ||
49 | udbg_init_debug_beat(); | ||
50 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE) | ||
51 | udbg_init_pas_realmode(); | ||
48 | #endif | 52 | #endif |
49 | } | 53 | } |
50 | 54 | ||
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 2d17f2b8eda7..e738f93b42fe 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c | |||
@@ -14,6 +14,8 @@ | |||
14 | 14 | ||
15 | extern u8 real_readb(volatile u8 __iomem *addr); | 15 | extern u8 real_readb(volatile u8 __iomem *addr); |
16 | extern void real_writeb(u8 data, volatile u8 __iomem *addr); | 16 | extern void real_writeb(u8 data, volatile u8 __iomem *addr); |
17 | extern u8 real_205_readb(volatile u8 __iomem *addr); | ||
18 | extern void real_205_writeb(u8 data, volatile u8 __iomem *addr); | ||
17 | 19 | ||
18 | struct NS16550 { | 20 | struct NS16550 { |
19 | /* this struct must be packed */ | 21 | /* this struct must be packed */ |
@@ -167,3 +169,25 @@ void __init udbg_init_maple_realmode(void) | |||
167 | udbg_getc_poll = NULL; | 169 | udbg_getc_poll = NULL; |
168 | } | 170 | } |
169 | #endif /* CONFIG_PPC_MAPLE */ | 171 | #endif /* CONFIG_PPC_MAPLE */ |
172 | |||
173 | #ifdef CONFIG_PPC_PASEMI | ||
174 | void udbg_pas_real_putc(char c) | ||
175 | { | ||
176 | if (udbg_comport) { | ||
177 | while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) | ||
178 | /* wait for idle */; | ||
179 | real_205_writeb(c, &udbg_comport->thr); eieio(); | ||
180 | if (c == '\n') | ||
181 | udbg_pas_real_putc('\r'); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | void udbg_init_pas_realmode(void) | ||
186 | { | ||
187 | udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8; | ||
188 | |||
189 | udbg_putc = udbg_pas_real_putc; | ||
190 | udbg_getc = NULL; | ||
191 | udbg_getc_poll = NULL; | ||
192 | } | ||
193 | #endif /* CONFIG_PPC_MAPLE */ | ||
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index a80f8f1d2e5d..2968ffeafdb6 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -199,10 +199,8 @@ EXPORT_SYMBOL(vio_unregister_driver); | |||
199 | /* vio_dev refcount hit 0 */ | 199 | /* vio_dev refcount hit 0 */ |
200 | static void __devinit vio_dev_release(struct device *dev) | 200 | static void __devinit vio_dev_release(struct device *dev) |
201 | { | 201 | { |
202 | if (dev->archdata.of_node) { | 202 | /* XXX should free TCE table */ |
203 | /* XXX should free TCE table */ | 203 | of_node_put(dev->archdata.of_node); |
204 | of_node_put(dev->archdata.of_node); | ||
205 | } | ||
206 | kfree(to_vio_dev(dev)); | 204 | kfree(to_vio_dev(dev)); |
207 | } | 205 | } |
208 | 206 | ||