aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2006-04-02 00:08:05 -0500
committerDmitry Torokhov <dtor_core@ameritech.net>2006-04-02 00:08:05 -0500
commit95d465fd750897ab32462a6702fbfe1b122cbbc0 (patch)
tree65c38b2f11c51bb6932e44dd6c92f15b0091abfe /arch/powerpc
parent642fde17dceceb56c7ba2762733ac688666ae657 (diff)
parent683aa4012f53b2ada0f430487e05d37b0d94e90a (diff)
Manual merge with Linus.
Conflicts: arch/powerpc/kernel/setup-common.c drivers/input/keyboard/hil_kbd.c drivers/input/mouse/hil_ptr.c
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig48
-rw-r--r--arch/powerpc/Kconfig.debug5
-rw-r--r--arch/powerpc/Makefile11
-rw-r--r--arch/powerpc/boot/crt0.S5
-rw-r--r--arch/powerpc/boot/install.sh2
-rw-r--r--arch/powerpc/boot/main.c4
-rw-r--r--arch/powerpc/configs/cell_defconfig177
-rw-r--r--arch/powerpc/configs/iseries_defconfig96
-rw-r--r--arch/powerpc/configs/maple_defconfig50
-rw-r--r--arch/powerpc/configs/mpc834x_sys_defconfig32
-rw-r--r--arch/powerpc/configs/mpc8540_ads_defconfig728
-rw-r--r--arch/powerpc/configs/pmac32_defconfig77
-rw-r--r--arch/powerpc/configs/ppc64_defconfig2
-rw-r--r--arch/powerpc/kernel/Makefile11
-rw-r--r--arch/powerpc/kernel/asm-offsets.c5
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S474
-rw-r--r--arch/powerpc/kernel/cputable.c12
-rw-r--r--arch/powerpc/kernel/crash_dump.c4
-rw-r--r--arch/powerpc/kernel/entry_32.S8
-rw-r--r--arch/powerpc/kernel/entry_64.S17
-rw-r--r--arch/powerpc/kernel/firmware.c29
-rw-r--r--arch/powerpc/kernel/head_44x.S2
-rw-r--r--arch/powerpc/kernel/head_64.S43
-rw-r--r--arch/powerpc/kernel/head_8xx.S2
-rw-r--r--arch/powerpc/kernel/head_booke.h363
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S6
-rw-r--r--arch/powerpc/kernel/idle.c (renamed from arch/powerpc/kernel/idle_64.c)79
-rw-r--r--arch/powerpc/kernel/idle_6xx.S18
-rw-r--r--arch/powerpc/kernel/idle_power4.S38
-rw-r--r--arch/powerpc/kernel/iomap.c2
-rw-r--r--arch/powerpc/kernel/iommu.c1
-rw-r--r--arch/powerpc/kernel/irq.c39
-rw-r--r--arch/powerpc/kernel/kprobes.c71
-rw-r--r--arch/powerpc/kernel/l2cr_6xx.S471
-rw-r--r--arch/powerpc/kernel/legacy_serial.c42
-rw-r--r--arch/powerpc/kernel/lparcfg.c4
-rw-r--r--arch/powerpc/kernel/module_32.c320
-rw-r--r--arch/powerpc/kernel/nvram_64.c7
-rw-r--r--arch/powerpc/kernel/of_device.c5
-rw-r--r--arch/powerpc/kernel/paca.c21
-rw-r--r--arch/powerpc/kernel/pci_32.c4
-rw-r--r--arch/powerpc/kernel/pci_64.c6
-rw-r--r--arch/powerpc/kernel/pci_iommu.c1
-rw-r--r--arch/powerpc/kernel/perfmon_fsl_booke.c222
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c11
-rw-r--r--arch/powerpc/kernel/proc_ppc64.c3
-rw-r--r--arch/powerpc/kernel/process.c23
-rw-r--r--arch/powerpc/kernel/prom.c158
-rw-r--r--arch/powerpc/kernel/prom_init.c68
-rw-r--r--arch/powerpc/kernel/ptrace-common.h2
-rw-r--r--arch/powerpc/kernel/rtas-proc.c3
-rw-r--r--arch/powerpc/kernel/rtas-rtc.c2
-rw-r--r--arch/powerpc/kernel/rtas.c8
-rw-r--r--arch/powerpc/kernel/rtas_pci.c26
-rw-r--r--arch/powerpc/kernel/setup-common.c75
-rw-r--r--arch/powerpc/kernel/setup_32.c78
-rw-r--r--arch/powerpc/kernel/setup_64.c83
-rw-r--r--arch/powerpc/kernel/signal_32.c1
-rw-r--r--arch/powerpc/kernel/signal_64.c5
-rw-r--r--arch/powerpc/kernel/smp.c6
-rw-r--r--arch/powerpc/kernel/swsusp_32.S349
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c73
-rw-r--r--arch/powerpc/kernel/syscalls.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c12
-rw-r--r--arch/powerpc/kernel/tau_6xx.c271
-rw-r--r--arch/powerpc/kernel/time.c291
-rw-r--r--arch/powerpc/kernel/traps.c51
-rw-r--r--arch/powerpc/kernel/vdso.c11
-rw-r--r--arch/powerpc/kernel/vdso32/sigtramp.S2
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S381
-rw-r--r--arch/powerpc/lib/copypage_64.S2
-rw-r--r--arch/powerpc/lib/copyuser_64.S2
-rw-r--r--arch/powerpc/lib/e2a.c14
-rw-r--r--arch/powerpc/lib/memcpy_64.S2
-rw-r--r--arch/powerpc/lib/rheap.c2
-rw-r--r--arch/powerpc/lib/sstep.c2
-rw-r--r--arch/powerpc/lib/strcase.c4
-rw-r--r--arch/powerpc/math-emu/Makefile13
-rw-r--r--arch/powerpc/math-emu/double.h129
-rw-r--r--arch/powerpc/math-emu/fabs.c18
-rw-r--r--arch/powerpc/math-emu/fadd.c38
-rw-r--r--arch/powerpc/math-emu/fadds.c39
-rw-r--r--arch/powerpc/math-emu/fcmpo.c46
-rw-r--r--arch/powerpc/math-emu/fcmpu.c42
-rw-r--r--arch/powerpc/math-emu/fctiw.c25
-rw-r--r--arch/powerpc/math-emu/fctiwz.c32
-rw-r--r--arch/powerpc/math-emu/fdiv.c53
-rw-r--r--arch/powerpc/math-emu/fdivs.c55
-rw-r--r--arch/powerpc/math-emu/fmadd.c48
-rw-r--r--arch/powerpc/math-emu/fmadds.c49
-rw-r--r--arch/powerpc/math-emu/fmr.c18
-rw-r--r--arch/powerpc/math-emu/fmsub.c51
-rw-r--r--arch/powerpc/math-emu/fmsubs.c52
-rw-r--r--arch/powerpc/math-emu/fmul.c42
-rw-r--r--arch/powerpc/math-emu/fmuls.c43
-rw-r--r--arch/powerpc/math-emu/fnabs.c18
-rw-r--r--arch/powerpc/math-emu/fneg.c18
-rw-r--r--arch/powerpc/math-emu/fnmadd.c51
-rw-r--r--arch/powerpc/math-emu/fnmadds.c52
-rw-r--r--arch/powerpc/math-emu/fnmsub.c54
-rw-r--r--arch/powerpc/math-emu/fnmsubs.c55
-rw-r--r--arch/powerpc/math-emu/fres.c12
-rw-r--r--arch/powerpc/math-emu/frsp.c25
-rw-r--r--arch/powerpc/math-emu/frsqrte.c12
-rw-r--r--arch/powerpc/math-emu/fsel.c38
-rw-r--r--arch/powerpc/math-emu/fsqrt.c37
-rw-r--r--arch/powerpc/math-emu/fsqrts.c38
-rw-r--r--arch/powerpc/math-emu/fsub.c41
-rw-r--r--arch/powerpc/math-emu/fsubs.c42
-rw-r--r--arch/powerpc/math-emu/lfd.c19
-rw-r--r--arch/powerpc/math-emu/lfs.c37
-rw-r--r--arch/powerpc/math-emu/math.c483
-rw-r--r--arch/powerpc/math-emu/mcrfs.c31
-rw-r--r--arch/powerpc/math-emu/mffs.c17
-rw-r--r--arch/powerpc/math-emu/mtfsb0.c18
-rw-r--r--arch/powerpc/math-emu/mtfsb1.c18
-rw-r--r--arch/powerpc/math-emu/mtfsf.c45
-rw-r--r--arch/powerpc/math-emu/mtfsfi.c23
-rw-r--r--arch/powerpc/math-emu/op-1.h245
-rw-r--r--arch/powerpc/math-emu/op-2.h433
-rw-r--r--arch/powerpc/math-emu/op-4.h297
-rw-r--r--arch/powerpc/math-emu/op-common.h688
-rw-r--r--arch/powerpc/math-emu/sfp-machine.h377
-rw-r--r--arch/powerpc/math-emu/single.h66
-rw-r--r--arch/powerpc/math-emu/soft-fp.h104
-rw-r--r--arch/powerpc/math-emu/stfd.c20
-rw-r--r--arch/powerpc/math-emu/stfiwx.c16
-rw-r--r--arch/powerpc/math-emu/stfs.c41
-rw-r--r--arch/powerpc/math-emu/types.c51
-rw-r--r--arch/powerpc/math-emu/udivmodti4.c191
-rw-r--r--arch/powerpc/mm/fault.c32
-rw-r--r--arch/powerpc/mm/hash_low_32.S2
-rw-r--r--arch/powerpc/mm/hash_utils_64.c39
-rw-r--r--arch/powerpc/mm/hugetlbpage.c15
-rw-r--r--arch/powerpc/mm/imalloc.c18
-rw-r--r--arch/powerpc/mm/init_32.c4
-rw-r--r--arch/powerpc/mm/init_64.c52
-rw-r--r--arch/powerpc/mm/lmb.c16
-rw-r--r--arch/powerpc/mm/mem.c15
-rw-r--r--arch/powerpc/mm/mmap.c2
-rw-r--r--arch/powerpc/mm/numa.c162
-rw-r--r--arch/powerpc/mm/pgtable_32.c11
-rw-r--r--arch/powerpc/mm/slb_low.S2
-rw-r--r--arch/powerpc/mm/stab.c6
-rw-r--r--arch/powerpc/mm/tlb_64.c2
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/backtrace.c126
-rw-r--r--arch/powerpc/oprofile/common.c9
-rw-r--r--arch/powerpc/oprofile/op_model_7450.c4
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c4
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c46
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c5
-rw-r--r--arch/powerpc/platforms/83xx/Makefile4
-rw-r--r--arch/powerpc/platforms/83xx/misc.c55
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c89
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.h2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h5
-rw-r--r--arch/powerpc/platforms/83xx/pci.c21
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig75
-rw-r--r--arch/powerpc/platforms/85xx/Makefile6
-rw-r--r--arch/powerpc/platforms/85xx/misc.c31
-rw-r--r--arch/powerpc/platforms/85xx/mpc8540_ads.h36
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx.h18
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c244
-rw-r--r--arch/powerpc/platforms/85xx/pci.c96
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/Kconfig5
-rw-r--r--arch/powerpc/platforms/cell/Makefile10
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c133
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h2
-rw-r--r--arch/powerpc/platforms/cell/iommu.c16
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c4
-rw-r--r--arch/powerpc/platforms/cell/setup.c13
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c108
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c39
-rw-r--r--arch/powerpc/platforms/cell/spu_callbacks.c345
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c47
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c24
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c523
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c57
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c8
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c91
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h28
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c3
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h2
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c79
-rw-r--r--arch/powerpc/platforms/chrp/time.c24
-rw-r--r--arch/powerpc/platforms/iseries/mf.c112
-rw-r--r--arch/powerpc/platforms/iseries/setup.c79
-rw-r--r--arch/powerpc/platforms/maple/setup.c10
-rw-r--r--arch/powerpc/platforms/maple/time.c26
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c6
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c2
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c7
-rw-r--r--arch/powerpc/platforms/powermac/feature.c13
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c3
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c16
-rw-r--r--arch/powerpc/platforms/powermac/pci.c5
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c86
-rw-r--r--arch/powerpc/platforms/powermac/smp.c4
-rw-r--r--arch/powerpc/platforms/powermac/time.c4
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig2
-rw-r--r--arch/powerpc/platforms/pseries/Makefile3
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c16
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c103
-rw-r--r--arch/powerpc/platforms/pseries/firmware.h17
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S2
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c5
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c39
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c15
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c292
-rw-r--r--arch/powerpc/platforms/pseries/smp.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c7
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c2
-rw-r--r--arch/powerpc/sysdev/dcr.S2
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c292
-rw-r--r--arch/powerpc/sysdev/ipic.h2
-rw-r--r--arch/powerpc/xmon/xmon.c30
228 files changed, 11996 insertions, 2144 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a834f9e0bbb3..2cdc35ce8045 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -37,6 +37,10 @@ config RWSEM_XCHGADD_ALGORITHM
37 bool 37 bool
38 default y 38 default y
39 39
40config GENERIC_HWEIGHT
41 bool
42 default y
43
40config GENERIC_CALIBRATE_DELAY 44config GENERIC_CALIBRATE_DELAY
41 bool 45 bool
42 default y 46 default y
@@ -127,6 +131,12 @@ config PPC_83xx
127 select 83xx 131 select 83xx
128 select PPC_FPU 132 select PPC_FPU
129 133
134config PPC_85xx
135 bool "Freescale 85xx"
136 select E500
137 select FSL_SOC
138 select 85xx
139
130config 40x 140config 40x
131 bool "AMCC 40x" 141 bool "AMCC 40x"
132 142
@@ -139,8 +149,6 @@ config 8xx
139config E200 149config E200
140 bool "Freescale e200" 150 bool "Freescale e200"
141 151
142config E500
143 bool "Freescale e500"
144endchoice 152endchoice
145 153
146config POWER4_ONLY 154config POWER4_ONLY
@@ -168,6 +176,13 @@ config 6xx
168config 83xx 176config 83xx
169 bool 177 bool
170 178
179# this is temp to handle compat with arch=ppc
180config 85xx
181 bool
182
183config E500
184 bool
185
171config PPC_FPU 186config PPC_FPU
172 bool 187 bool
173 default y if PPC64 188 default y if PPC64
@@ -217,6 +232,7 @@ config ALTIVEC
217config SPE 232config SPE
218 bool "SPE Support" 233 bool "SPE Support"
219 depends on E200 || E500 234 depends on E200 || E500
235 default y
220 ---help--- 236 ---help---
221 This option enables kernel support for the Signal Processing 237 This option enables kernel support for the Signal Processing
222 Extensions (SPE) to the PowerPC processor. The kernel currently 238 Extensions (SPE) to the PowerPC processor. The kernel currently
@@ -238,6 +254,21 @@ config PPC_STD_MMU_32
238 def_bool y 254 def_bool y
239 depends on PPC_STD_MMU && PPC32 255 depends on PPC_STD_MMU && PPC32
240 256
257config VIRT_CPU_ACCOUNTING
258 bool "Deterministic task and CPU time accounting"
259 depends on PPC64
260 default y
261 help
262 Select this option to enable more accurate task and CPU time
263 accounting. This is done by reading a CPU counter on each
264 kernel entry and exit and on transitions within the kernel
265 between system, softirq and hardirq state, so there is a
266 small performance impact. This also enables accounting of
267 stolen time on logically-partitioned systems running on
268 IBM POWER5-based machines.
269
270 If in doubt, say Y here.
271
241config SMP 272config SMP
242 depends on PPC_STD_MMU 273 depends on PPC_STD_MMU
243 bool "Symmetric multi-processing support" 274 bool "Symmetric multi-processing support"
@@ -460,7 +491,7 @@ config PPC601_SYNC_FIX
460 If in doubt, say Y here. 491 If in doubt, say Y here.
461 492
462config TAU 493config TAU
463 bool "Thermal Management Support" 494 bool "On-chip CPU temperature sensor support"
464 depends on 6xx 495 depends on 6xx
465 help 496 help
466 G3 and G4 processors have an on-chip temperature sensor called the 497 G3 and G4 processors have an on-chip temperature sensor called the
@@ -469,7 +500,7 @@ config TAU
469 on-die temperature in /proc/cpuinfo if the cpu supports it. 500 on-die temperature in /proc/cpuinfo if the cpu supports it.
470 501
471 Unfortunately, on some chip revisions, this sensor is very inaccurate 502 Unfortunately, on some chip revisions, this sensor is very inaccurate
472 and in some cases, does not work at all, so don't assume the cpu 503 and in many cases, does not work at all, so don't assume the cpu
473 temp is actually what /proc/cpuinfo says it is. 504 temp is actually what /proc/cpuinfo says it is.
474 505
475config TAU_INT 506config TAU_INT
@@ -580,7 +611,7 @@ config KEXEC
580 strongly in flux, so no good recommendation can be made. 611 strongly in flux, so no good recommendation can be made.
581 612
582config CRASH_DUMP 613config CRASH_DUMP
583 bool "kernel crash dumps (EXPERIMENTAL)" 614 bool "Build a kdump crash kernel (EXPERIMENTAL)"
584 depends on PPC_MULTIPLATFORM && PPC64 && EXPERIMENTAL 615 depends on PPC_MULTIPLATFORM && PPC64 && EXPERIMENTAL
585 help 616 help
586 Build a kernel suitable for use as a kdump capture kernel. 617 Build a kernel suitable for use as a kdump capture kernel.
@@ -734,13 +765,12 @@ config GENERIC_ISA_DMA
734 765
735config PPC_I8259 766config PPC_I8259
736 bool 767 bool
737 default y if 85xx
738 default n 768 default n
739 769
740config PPC_INDIRECT_PCI 770config PPC_INDIRECT_PCI
741 bool 771 bool
742 depends on PCI 772 depends on PCI
743 default y if 40x || 44x || 85xx 773 default y if 40x || 44x
744 default n 774 default n
745 775
746config EISA 776config EISA
@@ -757,8 +787,8 @@ config MCA
757 bool 787 bool
758 788
759config PCI 789config PCI
760 bool "PCI support" if 40x || CPM2 || PPC_83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) 790 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
761 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !85xx 791 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx
762 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS 792 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
763 default PCI_QSPAN if !4xx && !CPM2 && 8xx 793 default PCI_QSPAN if !4xx && !CPM2 && 8xx
764 help 794 help
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 9254806f7032..8d48e9e7162a 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -110,11 +110,6 @@ config SERIAL_TEXT_DEBUG
110 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ 110 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
111 PPC_GEN550 || PPC_MPC52xx 111 PPC_GEN550 || PPC_MPC52xx
112 112
113config PPC_OCP
114 bool
115 depends on IBM_OCP || XILINX_OCP
116 default y
117
118choice 113choice
119 prompt "Early debugging (dangerous)" 114 prompt "Early debugging (dangerous)"
120 bool 115 bool
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 5500ab55d042..6ec84d37a337 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -129,13 +129,8 @@ core-y += arch/powerpc/kernel/ \
129 arch/powerpc/lib/ \ 129 arch/powerpc/lib/ \
130 arch/powerpc/sysdev/ \ 130 arch/powerpc/sysdev/ \
131 arch/powerpc/platforms/ 131 arch/powerpc/platforms/
132core-$(CONFIG_PPC32) += arch/ppc/kernel/ 132core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
133core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
134core-$(CONFIG_XMON) += arch/powerpc/xmon/ 133core-$(CONFIG_XMON) += arch/powerpc/xmon/
135core-$(CONFIG_APUS) += arch/ppc/amiga/
136drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
137drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
138drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
139 134
140drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 135drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
141 136
@@ -148,9 +143,9 @@ all: $(KBUILD_IMAGE)
148 143
149CPPFLAGS_vmlinux.lds := -Upowerpc 144CPPFLAGS_vmlinux.lds := -Upowerpc
150 145
151BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage 146BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
152 147
153.PHONY: $(BOOT_TARGETS) 148PHONY += $(BOOT_TARGETS)
154 149
155boot := arch/$(ARCH)/boot 150boot := arch/$(ARCH)/boot
156 151
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index e0192c26037b..70e65b13e033 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -45,7 +45,8 @@ _zimage_start:
45 bdnz 2b 45 bdnz 2b
46 46
47 /* Do a cache flush for our text, in case OF didn't */ 47 /* Do a cache flush for our text, in case OF didn't */
483: lis r9,_start@h 483: lis r9,_start@ha
49 addi r9,r9,_start@l
49 add r9,r0,r9 50 add r9,r0,r9
50 lis r8,_etext@ha 51 lis r8,_etext@ha
51 addi r8,r8,_etext@l 52 addi r8,r8,_etext@l
@@ -53,7 +54,7 @@ _zimage_start:
534: dcbf r0,r9 544: dcbf r0,r9
54 icbi r0,r9 55 icbi r0,r9
55 addi r9,r9,0x20 56 addi r9,r9,0x20
56 cmplwi 0,r9,8 57 cmplw cr0,r9,r8
57 blt 4b 58 blt 4b
58 sync 59 sync
59 isync 60 isync
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh
index eacce9590816..b002bfd56786 100644
--- a/arch/powerpc/boot/install.sh
+++ b/arch/powerpc/boot/install.sh
@@ -1,7 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# 2#
3# arch/ppc64/boot/install.sh
4#
5# This file is subject to the terms and conditions of the GNU General Public 3# This file is subject to the terms and conditions of the GNU General Public
6# License. See the file "COPYING" in the main directory of this archive 4# License. See the file "COPYING" in the main directory of this archive
7# for more details. 5# for more details.
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 55ec59867250..816446f0e497 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -152,7 +152,7 @@ static int is_elf64(void *hdr)
152 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + 152 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
153 (unsigned long)elf64->e_phoff); 153 (unsigned long)elf64->e_phoff);
154 for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++) 154 for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
155 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) 155 if (elf64ph->p_type == PT_LOAD)
156 break; 156 break;
157 if (i >= (unsigned int)elf64->e_phnum) 157 if (i >= (unsigned int)elf64->e_phnum)
158 return 0; 158 return 0;
@@ -193,7 +193,7 @@ static int is_elf32(void *hdr)
193 elf32 = (Elf32_Ehdr *)elfheader; 193 elf32 = (Elf32_Ehdr *)elfheader;
194 elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff); 194 elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
195 for (i = 0; i < elf32->e_phnum; i++, elf32ph++) 195 for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
196 if (elf32ph->p_type == PT_LOAD && elf32ph->p_offset != 0) 196 if (elf32ph->p_type == PT_LOAD)
197 break; 197 break;
198 if (i >= elf32->e_phnum) 198 if (i >= elf32->e_phnum)
199 return 0; 199 return 0;
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 063b84f2cbea..fe22e54ab2b0 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc5 3# Linux kernel version: 2.6.16
4# Tue Dec 20 15:59:26 2005 4# Thu Mar 23 20:48:09 2006
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -16,6 +16,10 @@ CONFIG_COMPAT=y
16CONFIG_SYSVIPC_COMPAT=y 16CONFIG_SYSVIPC_COMPAT=y
17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
18CONFIG_ARCH_MAY_HAVE_PC_FDC=y 18CONFIG_ARCH_MAY_HAVE_PC_FDC=y
19CONFIG_PPC_OF=y
20CONFIG_PPC_UDBG_16550=y
21# CONFIG_GENERIC_TBSYNC is not set
22# CONFIG_DEFAULT_UIMAGE is not set
19 23
20# 24#
21# Processor support 25# Processor support
@@ -26,6 +30,7 @@ CONFIG_POWER4=y
26CONFIG_PPC_FPU=y 30CONFIG_PPC_FPU=y
27CONFIG_ALTIVEC=y 31CONFIG_ALTIVEC=y
28CONFIG_PPC_STD_MMU=y 32CONFIG_PPC_STD_MMU=y
33CONFIG_VIRT_CPU_ACCOUNTING=y
29CONFIG_SMP=y 34CONFIG_SMP=y
30CONFIG_NR_CPUS=4 35CONFIG_NR_CPUS=4
31 36
@@ -33,7 +38,6 @@ CONFIG_NR_CPUS=4
33# Code maturity level options 38# Code maturity level options
34# 39#
35CONFIG_EXPERIMENTAL=y 40CONFIG_EXPERIMENTAL=y
36CONFIG_CLEAN_COMPILE=y
37CONFIG_LOCK_KERNEL=y 41CONFIG_LOCK_KERNEL=y
38CONFIG_INIT_ENV_ARG_LIMIT=32 42CONFIG_INIT_ENV_ARG_LIMIT=32
39 43
@@ -48,9 +52,8 @@ CONFIG_SYSVIPC=y
48# CONFIG_BSD_PROCESS_ACCT is not set 52# CONFIG_BSD_PROCESS_ACCT is not set
49CONFIG_SYSCTL=y 53CONFIG_SYSCTL=y
50# CONFIG_AUDIT is not set 54# CONFIG_AUDIT is not set
51CONFIG_HOTPLUG=y 55CONFIG_IKCONFIG=y
52CONFIG_KOBJECT_UEVENT=y 56CONFIG_IKCONFIG_PROC=y
53# CONFIG_IKCONFIG is not set
54# CONFIG_CPUSETS is not set 57# CONFIG_CPUSETS is not set
55CONFIG_INITRAMFS_SOURCE="" 58CONFIG_INITRAMFS_SOURCE=""
56CONFIG_CC_OPTIMIZE_FOR_SIZE=y 59CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -58,8 +61,10 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
58CONFIG_KALLSYMS=y 61CONFIG_KALLSYMS=y
59# CONFIG_KALLSYMS_ALL is not set 62# CONFIG_KALLSYMS_ALL is not set
60# CONFIG_KALLSYMS_EXTRA_PASS is not set 63# CONFIG_KALLSYMS_EXTRA_PASS is not set
64CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y 65CONFIG_PRINTK=y
62CONFIG_BUG=y 66CONFIG_BUG=y
67CONFIG_ELF_CORE=y
63CONFIG_BASE_FULL=y 68CONFIG_BASE_FULL=y
64CONFIG_FUTEX=y 69CONFIG_FUTEX=y
65CONFIG_EPOLL=y 70CONFIG_EPOLL=y
@@ -68,8 +73,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
68CONFIG_CC_ALIGN_LABELS=0 73CONFIG_CC_ALIGN_LABELS=0
69CONFIG_CC_ALIGN_LOOPS=0 74CONFIG_CC_ALIGN_LOOPS=0
70CONFIG_CC_ALIGN_JUMPS=0 75CONFIG_CC_ALIGN_JUMPS=0
76CONFIG_SLAB=y
71# CONFIG_TINY_SHMEM is not set 77# CONFIG_TINY_SHMEM is not set
72CONFIG_BASE_SMALL=0 78CONFIG_BASE_SMALL=0
79# CONFIG_SLOB is not set
73 80
74# 81#
75# Loadable module support 82# Loadable module support
@@ -80,7 +87,7 @@ CONFIG_MODULE_UNLOAD=y
80CONFIG_OBSOLETE_MODPARM=y 87CONFIG_OBSOLETE_MODPARM=y
81# CONFIG_MODVERSIONS is not set 88# CONFIG_MODVERSIONS is not set
82# CONFIG_MODULE_SRCVERSION_ALL is not set 89# CONFIG_MODULE_SRCVERSION_ALL is not set
83# CONFIG_KMOD is not set 90CONFIG_KMOD=y
84CONFIG_STOP_MACHINE=y 91CONFIG_STOP_MACHINE=y
85 92
86# 93#
@@ -111,7 +118,6 @@ CONFIG_PPC_MULTIPLATFORM=y
111# CONFIG_PPC_PMAC is not set 118# CONFIG_PPC_PMAC is not set
112# CONFIG_PPC_MAPLE is not set 119# CONFIG_PPC_MAPLE is not set
113CONFIG_PPC_CELL=y 120CONFIG_PPC_CELL=y
114CONFIG_PPC_OF=y
115# CONFIG_U3_DART is not set 121# CONFIG_U3_DART is not set
116CONFIG_PPC_RTAS=y 122CONFIG_PPC_RTAS=y
117# CONFIG_RTAS_ERROR_LOGGING is not set 123# CONFIG_RTAS_ERROR_LOGGING is not set
@@ -120,11 +126,16 @@ CONFIG_RTAS_FLASH=y
120CONFIG_MMIO_NVRAM=y 126CONFIG_MMIO_NVRAM=y
121CONFIG_CELL_IIC=y 127CONFIG_CELL_IIC=y
122# CONFIG_PPC_MPC106 is not set 128# CONFIG_PPC_MPC106 is not set
123# CONFIG_GENERIC_TBSYNC is not set
124# CONFIG_CPU_FREQ is not set 129# CONFIG_CPU_FREQ is not set
125# CONFIG_WANT_EARLY_SERIAL is not set 130# CONFIG_WANT_EARLY_SERIAL is not set
126 131
127# 132#
133# Cell Broadband Engine options
134#
135CONFIG_SPU_FS=m
136CONFIG_SPUFS_MMAP=y
137
138#
128# Kernel options 139# Kernel options
129# 140#
130# CONFIG_HZ_100 is not set 141# CONFIG_HZ_100 is not set
@@ -136,23 +147,27 @@ CONFIG_PREEMPT_NONE=y
136# CONFIG_PREEMPT is not set 147# CONFIG_PREEMPT is not set
137CONFIG_PREEMPT_BKL=y 148CONFIG_PREEMPT_BKL=y
138CONFIG_BINFMT_ELF=y 149CONFIG_BINFMT_ELF=y
139# CONFIG_BINFMT_MISC is not set 150CONFIG_BINFMT_MISC=m
140CONFIG_FORCE_MAX_ZONEORDER=13 151CONFIG_FORCE_MAX_ZONEORDER=13
141# CONFIG_IOMMU_VMERGE is not set 152# CONFIG_IOMMU_VMERGE is not set
142CONFIG_KEXEC=y 153CONFIG_KEXEC=y
154# CONFIG_CRASH_DUMP is not set
143CONFIG_IRQ_ALL_CPUS=y 155CONFIG_IRQ_ALL_CPUS=y
144# CONFIG_NUMA is not set 156# CONFIG_NUMA is not set
145CONFIG_ARCH_SELECT_MEMORY_MODEL=y 157CONFIG_ARCH_SELECT_MEMORY_MODEL=y
146CONFIG_ARCH_FLATMEM_ENABLE=y 158CONFIG_ARCH_FLATMEM_ENABLE=y
147CONFIG_ARCH_SPARSEMEM_ENABLE=y 159CONFIG_ARCH_SPARSEMEM_ENABLE=y
148CONFIG_SELECT_MEMORY_MODEL=y 160CONFIG_SELECT_MEMORY_MODEL=y
149CONFIG_FLATMEM_MANUAL=y 161# CONFIG_FLATMEM_MANUAL is not set
150# CONFIG_DISCONTIGMEM_MANUAL is not set 162# CONFIG_DISCONTIGMEM_MANUAL is not set
151# CONFIG_SPARSEMEM_MANUAL is not set 163CONFIG_SPARSEMEM_MANUAL=y
152CONFIG_FLATMEM=y 164CONFIG_SPARSEMEM=y
153CONFIG_FLAT_NODE_MEM_MAP=y 165CONFIG_HAVE_MEMORY_PRESENT=y
154# CONFIG_SPARSEMEM_STATIC is not set 166# CONFIG_SPARSEMEM_STATIC is not set
167CONFIG_SPARSEMEM_EXTREME=y
168# CONFIG_MEMORY_HOTPLUG is not set
155CONFIG_SPLIT_PTLOCK_CPUS=4 169CONFIG_SPLIT_PTLOCK_CPUS=4
170CONFIG_MIGRATION=y
156# CONFIG_PPC_64K_PAGES is not set 171# CONFIG_PPC_64K_PAGES is not set
157CONFIG_SCHED_SMT=y 172CONFIG_SCHED_SMT=y
158CONFIG_PROC_DEVICETREE=y 173CONFIG_PROC_DEVICETREE=y
@@ -191,6 +206,7 @@ CONFIG_NET=y
191# 206#
192# Networking options 207# Networking options
193# 208#
209# CONFIG_NETDEBUG is not set
194CONFIG_PACKET=y 210CONFIG_PACKET=y
195# CONFIG_PACKET_MMAP is not set 211# CONFIG_PACKET_MMAP is not set
196CONFIG_UNIX=y 212CONFIG_UNIX=y
@@ -222,6 +238,7 @@ CONFIG_TCP_CONG_BIC=y
222# CONFIG_IP_VS is not set 238# CONFIG_IP_VS is not set
223CONFIG_IPV6=y 239CONFIG_IPV6=y
224# CONFIG_IPV6_PRIVACY is not set 240# CONFIG_IPV6_PRIVACY is not set
241# CONFIG_IPV6_ROUTER_PREF is not set
225CONFIG_INET6_AH=m 242CONFIG_INET6_AH=m
226CONFIG_INET6_ESP=m 243CONFIG_INET6_ESP=m
227CONFIG_INET6_IPCOMP=m 244CONFIG_INET6_IPCOMP=m
@@ -234,6 +251,7 @@ CONFIG_NETFILTER=y
234# Core Netfilter Configuration 251# Core Netfilter Configuration
235# 252#
236# CONFIG_NETFILTER_NETLINK is not set 253# CONFIG_NETFILTER_NETLINK is not set
254# CONFIG_NETFILTER_XTABLES is not set
237 255
238# 256#
239# IP: Netfilter Configuration 257# IP: Netfilter Configuration
@@ -249,69 +267,13 @@ CONFIG_IP_NF_IRC=m
249CONFIG_IP_NF_TFTP=m 267CONFIG_IP_NF_TFTP=m
250CONFIG_IP_NF_AMANDA=m 268CONFIG_IP_NF_AMANDA=m
251# CONFIG_IP_NF_PPTP is not set 269# CONFIG_IP_NF_PPTP is not set
270# CONFIG_IP_NF_H323 is not set
252CONFIG_IP_NF_QUEUE=m 271CONFIG_IP_NF_QUEUE=m
253CONFIG_IP_NF_IPTABLES=m
254CONFIG_IP_NF_MATCH_LIMIT=m
255CONFIG_IP_NF_MATCH_IPRANGE=m
256CONFIG_IP_NF_MATCH_MAC=m
257CONFIG_IP_NF_MATCH_PKTTYPE=m
258CONFIG_IP_NF_MATCH_MARK=m
259CONFIG_IP_NF_MATCH_MULTIPORT=m
260CONFIG_IP_NF_MATCH_TOS=m
261CONFIG_IP_NF_MATCH_RECENT=m
262CONFIG_IP_NF_MATCH_ECN=m
263CONFIG_IP_NF_MATCH_DSCP=m
264CONFIG_IP_NF_MATCH_AH_ESP=m
265CONFIG_IP_NF_MATCH_LENGTH=m
266CONFIG_IP_NF_MATCH_TTL=m
267CONFIG_IP_NF_MATCH_TCPMSS=m
268CONFIG_IP_NF_MATCH_HELPER=m
269CONFIG_IP_NF_MATCH_STATE=m
270CONFIG_IP_NF_MATCH_CONNTRACK=m
271CONFIG_IP_NF_MATCH_OWNER=m
272CONFIG_IP_NF_MATCH_ADDRTYPE=m
273CONFIG_IP_NF_MATCH_REALM=m
274CONFIG_IP_NF_MATCH_SCTP=m
275# CONFIG_IP_NF_MATCH_DCCP is not set
276CONFIG_IP_NF_MATCH_COMMENT=m
277CONFIG_IP_NF_MATCH_HASHLIMIT=m
278CONFIG_IP_NF_MATCH_STRING=m
279CONFIG_IP_NF_FILTER=m
280CONFIG_IP_NF_TARGET_REJECT=m
281CONFIG_IP_NF_TARGET_LOG=m
282CONFIG_IP_NF_TARGET_ULOG=m
283CONFIG_IP_NF_TARGET_TCPMSS=m
284CONFIG_IP_NF_TARGET_NFQUEUE=m
285CONFIG_IP_NF_NAT=m
286CONFIG_IP_NF_NAT_NEEDED=y
287CONFIG_IP_NF_TARGET_MASQUERADE=m
288CONFIG_IP_NF_TARGET_REDIRECT=m
289CONFIG_IP_NF_TARGET_NETMAP=m
290CONFIG_IP_NF_TARGET_SAME=m
291CONFIG_IP_NF_NAT_SNMP_BASIC=m
292CONFIG_IP_NF_NAT_IRC=m
293CONFIG_IP_NF_NAT_FTP=m
294CONFIG_IP_NF_NAT_TFTP=m
295CONFIG_IP_NF_NAT_AMANDA=m
296CONFIG_IP_NF_MANGLE=m
297CONFIG_IP_NF_TARGET_TOS=m
298CONFIG_IP_NF_TARGET_ECN=m
299CONFIG_IP_NF_TARGET_DSCP=m
300CONFIG_IP_NF_TARGET_MARK=m
301CONFIG_IP_NF_TARGET_CLASSIFY=m
302CONFIG_IP_NF_TARGET_TTL=m
303CONFIG_IP_NF_RAW=m
304CONFIG_IP_NF_TARGET_NOTRACK=m
305CONFIG_IP_NF_ARPTABLES=m
306CONFIG_IP_NF_ARPFILTER=m
307CONFIG_IP_NF_ARP_MANGLE=m
308 272
309# 273#
310# IPv6: Netfilter Configuration (EXPERIMENTAL) 274# IPv6: Netfilter Configuration (EXPERIMENTAL)
311# 275#
312# CONFIG_IP6_NF_QUEUE is not set 276# CONFIG_IP6_NF_QUEUE is not set
313# CONFIG_IP6_NF_IPTABLES is not set
314# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
315 277
316# 278#
317# DCCP Configuration (EXPERIMENTAL) 279# DCCP Configuration (EXPERIMENTAL)
@@ -322,6 +284,11 @@ CONFIG_IP_NF_ARP_MANGLE=m
322# SCTP Configuration (EXPERIMENTAL) 284# SCTP Configuration (EXPERIMENTAL)
323# 285#
324# CONFIG_IP_SCTP is not set 286# CONFIG_IP_SCTP is not set
287
288#
289# TIPC Configuration (EXPERIMENTAL)
290#
291# CONFIG_TIPC is not set
325# CONFIG_ATM is not set 292# CONFIG_ATM is not set
326# CONFIG_BRIDGE is not set 293# CONFIG_BRIDGE is not set
327# CONFIG_VLAN_8021Q is not set 294# CONFIG_VLAN_8021Q is not set
@@ -339,7 +306,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
339# QoS and/or fair queueing 306# QoS and/or fair queueing
340# 307#
341# CONFIG_NET_SCHED is not set 308# CONFIG_NET_SCHED is not set
342CONFIG_NET_CLS_ROUTE=y
343 309
344# 310#
345# Network testing 311# Network testing
@@ -392,7 +358,7 @@ CONFIG_FW_LOADER=y
392# CONFIG_BLK_DEV_COW_COMMON is not set 358# CONFIG_BLK_DEV_COW_COMMON is not set
393CONFIG_BLK_DEV_LOOP=y 359CONFIG_BLK_DEV_LOOP=y
394# CONFIG_BLK_DEV_CRYPTOLOOP is not set 360# CONFIG_BLK_DEV_CRYPTOLOOP is not set
395CONFIG_BLK_DEV_NBD=y 361# CONFIG_BLK_DEV_NBD is not set
396# CONFIG_BLK_DEV_SX8 is not set 362# CONFIG_BLK_DEV_SX8 is not set
397CONFIG_BLK_DEV_RAM=y 363CONFIG_BLK_DEV_RAM=y
398CONFIG_BLK_DEV_RAM_COUNT=16 364CONFIG_BLK_DEV_RAM_COUNT=16
@@ -468,7 +434,23 @@ CONFIG_IDEDMA_AUTO=y
468# 434#
469# Multi-device support (RAID and LVM) 435# Multi-device support (RAID and LVM)
470# 436#
471# CONFIG_MD is not set 437CONFIG_MD=y
438CONFIG_BLK_DEV_MD=m
439CONFIG_MD_LINEAR=m
440CONFIG_MD_RAID0=m
441CONFIG_MD_RAID1=m
442# CONFIG_MD_RAID10 is not set
443# CONFIG_MD_RAID5 is not set
444# CONFIG_MD_RAID6 is not set
445# CONFIG_MD_MULTIPATH is not set
446# CONFIG_MD_FAULTY is not set
447CONFIG_BLK_DEV_DM=m
448CONFIG_DM_CRYPT=m
449CONFIG_DM_SNAPSHOT=m
450CONFIG_DM_MIRROR=m
451CONFIG_DM_ZERO=m
452CONFIG_DM_MULTIPATH=m
453# CONFIG_DM_MULTIPATH_EMC is not set
472 454
473# 455#
474# Fusion MPT device support 456# Fusion MPT device support
@@ -532,7 +514,7 @@ CONFIG_MII=y
532# CONFIG_ACENIC is not set 514# CONFIG_ACENIC is not set
533# CONFIG_DL2K is not set 515# CONFIG_DL2K is not set
534CONFIG_E1000=m 516CONFIG_E1000=m
535# CONFIG_E1000_NAPI is not set 517CONFIG_E1000_NAPI=y
536# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set 518# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
537# CONFIG_NS83820 is not set 519# CONFIG_NS83820 is not set
538# CONFIG_HAMACHI is not set 520# CONFIG_HAMACHI is not set
@@ -540,9 +522,11 @@ CONFIG_E1000=m
540# CONFIG_R8169 is not set 522# CONFIG_R8169 is not set
541# CONFIG_SIS190 is not set 523# CONFIG_SIS190 is not set
542CONFIG_SKGE=m 524CONFIG_SKGE=m
525# CONFIG_SKY2 is not set
543# CONFIG_SK98LIN is not set 526# CONFIG_SK98LIN is not set
544# CONFIG_TIGON3 is not set 527# CONFIG_TIGON3 is not set
545# CONFIG_BNX2 is not set 528# CONFIG_BNX2 is not set
529CONFIG_SPIDER_NET=m
546# CONFIG_MV643XX_ETH is not set 530# CONFIG_MV643XX_ETH is not set
547 531
548# 532#
@@ -628,13 +612,16 @@ CONFIG_VT=y
628CONFIG_VT_CONSOLE=y 612CONFIG_VT_CONSOLE=y
629CONFIG_HW_CONSOLE=y 613CONFIG_HW_CONSOLE=y
630CONFIG_SERIAL_NONSTANDARD=y 614CONFIG_SERIAL_NONSTANDARD=y
615# CONFIG_COMPUTONE is not set
631# CONFIG_ROCKETPORT is not set 616# CONFIG_ROCKETPORT is not set
632# CONFIG_CYCLADES is not set 617# CONFIG_CYCLADES is not set
633# CONFIG_DIGIEPCA is not set 618# CONFIG_DIGIEPCA is not set
619# CONFIG_MOXA_INTELLIO is not set
634# CONFIG_MOXA_SMARTIO is not set 620# CONFIG_MOXA_SMARTIO is not set
635# CONFIG_ISI is not set 621# CONFIG_ISI is not set
636# CONFIG_SYNCLINK is not set 622# CONFIG_SYNCLINK is not set
637# CONFIG_SYNCLINKMP is not set 623# CONFIG_SYNCLINKMP is not set
624# CONFIG_SYNCLINK_GT is not set
638# CONFIG_N_HDLC is not set 625# CONFIG_N_HDLC is not set
639# CONFIG_SPECIALIX is not set 626# CONFIG_SPECIALIX is not set
640# CONFIG_SX is not set 627# CONFIG_SX is not set
@@ -646,6 +633,7 @@ CONFIG_SERIAL_NONSTANDARD=y
646CONFIG_SERIAL_8250=y 633CONFIG_SERIAL_8250=y
647CONFIG_SERIAL_8250_CONSOLE=y 634CONFIG_SERIAL_8250_CONSOLE=y
648CONFIG_SERIAL_8250_NR_UARTS=4 635CONFIG_SERIAL_8250_NR_UARTS=4
636CONFIG_SERIAL_8250_RUNTIME_UARTS=4
649# CONFIG_SERIAL_8250_EXTENDED is not set 637# CONFIG_SERIAL_8250_EXTENDED is not set
650 638
651# 639#
@@ -656,6 +644,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y
656# CONFIG_SERIAL_JSM is not set 644# CONFIG_SERIAL_JSM is not set
657CONFIG_UNIX98_PTYS=y 645CONFIG_UNIX98_PTYS=y
658# CONFIG_LEGACY_PTYS is not set 646# CONFIG_LEGACY_PTYS is not set
647CONFIG_HVC_DRIVER=y
648CONFIG_HVC_RTAS=y
659 649
660# 650#
661# IPMI 651# IPMI
@@ -672,14 +662,13 @@ CONFIG_WATCHDOG=y
672# Watchdog Device Drivers 662# Watchdog Device Drivers
673# 663#
674# CONFIG_SOFT_WATCHDOG is not set 664# CONFIG_SOFT_WATCHDOG is not set
675# CONFIG_WATCHDOG_RTAS is not set 665CONFIG_WATCHDOG_RTAS=y
676 666
677# 667#
678# PCI-based Watchdog Cards 668# PCI-based Watchdog Cards
679# 669#
680# CONFIG_PCIPCWATCHDOG is not set 670# CONFIG_PCIPCWATCHDOG is not set
681# CONFIG_WDTPCI is not set 671# CONFIG_WDTPCI is not set
682# CONFIG_RTC is not set
683CONFIG_GEN_RTC=y 672CONFIG_GEN_RTC=y
684# CONFIG_GEN_RTC_X is not set 673# CONFIG_GEN_RTC_X is not set
685# CONFIG_DTLK is not set 674# CONFIG_DTLK is not set
@@ -756,6 +745,12 @@ CONFIG_I2C_ALGOBIT=y
756# CONFIG_I2C_DEBUG_CHIP is not set 745# CONFIG_I2C_DEBUG_CHIP is not set
757 746
758# 747#
748# SPI support
749#
750# CONFIG_SPI is not set
751# CONFIG_SPI_MASTER is not set
752
753#
759# Dallas's 1-wire bus 754# Dallas's 1-wire bus
760# 755#
761# CONFIG_W1 is not set 756# CONFIG_W1 is not set
@@ -805,6 +800,7 @@ CONFIG_DUMMY_CONSOLE=y
805# 800#
806CONFIG_USB_ARCH_HAS_HCD=y 801CONFIG_USB_ARCH_HAS_HCD=y
807CONFIG_USB_ARCH_HAS_OHCI=y 802CONFIG_USB_ARCH_HAS_OHCI=y
803CONFIG_USB_ARCH_HAS_EHCI=y
808# CONFIG_USB is not set 804# CONFIG_USB is not set
809 805
810# 806#
@@ -824,10 +820,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
824# 820#
825# InfiniBand support 821# InfiniBand support
826# 822#
827# CONFIG_INFINIBAND is not set 823CONFIG_INFINIBAND=y
824CONFIG_INFINIBAND_USER_MAD=m
825CONFIG_INFINIBAND_USER_ACCESS=m
826CONFIG_INFINIBAND_MTHCA=m
827CONFIG_INFINIBAND_MTHCA_DEBUG=y
828CONFIG_INFINIBAND_IPOIB=m
829CONFIG_INFINIBAND_IPOIB_DEBUG=y
830CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
828 831
829# 832#
830# SN Devices 833# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
831# 834#
832 835
833# 836#
@@ -847,6 +850,7 @@ CONFIG_FS_MBCACHE=y
847# CONFIG_JFS_FS is not set 850# CONFIG_JFS_FS is not set
848CONFIG_FS_POSIX_ACL=y 851CONFIG_FS_POSIX_ACL=y
849# CONFIG_XFS_FS is not set 852# CONFIG_XFS_FS is not set
853# CONFIG_OCFS2_FS is not set
850# CONFIG_MINIX_FS is not set 854# CONFIG_MINIX_FS is not set
851# CONFIG_ROMFS_FS is not set 855# CONFIG_ROMFS_FS is not set
852CONFIG_INOTIFY=y 856CONFIG_INOTIFY=y
@@ -886,6 +890,7 @@ CONFIG_HUGETLBFS=y
886CONFIG_HUGETLB_PAGE=y 890CONFIG_HUGETLB_PAGE=y
887CONFIG_RAMFS=y 891CONFIG_RAMFS=y
888# CONFIG_RELAYFS_FS is not set 892# CONFIG_RELAYFS_FS is not set
893# CONFIG_CONFIGFS_FS is not set
889 894
890# 895#
891# Miscellaneous filesystems 896# Miscellaneous filesystems
@@ -951,6 +956,7 @@ CONFIG_MSDOS_PARTITION=y
951# CONFIG_SGI_PARTITION is not set 956# CONFIG_SGI_PARTITION is not set
952# CONFIG_ULTRIX_PARTITION is not set 957# CONFIG_ULTRIX_PARTITION is not set
953# CONFIG_SUN_PARTITION is not set 958# CONFIG_SUN_PARTITION is not set
959# CONFIG_KARMA_PARTITION is not set
954CONFIG_EFI_PARTITION=y 960CONFIG_EFI_PARTITION=y
955 961
956# 962#
@@ -1006,10 +1012,6 @@ CONFIG_CRC32=y
1006# CONFIG_LIBCRC32C is not set 1012# CONFIG_LIBCRC32C is not set
1007CONFIG_ZLIB_INFLATE=m 1013CONFIG_ZLIB_INFLATE=m
1008CONFIG_ZLIB_DEFLATE=m 1014CONFIG_ZLIB_DEFLATE=m
1009CONFIG_TEXTSEARCH=y
1010CONFIG_TEXTSEARCH_KMP=m
1011CONFIG_TEXTSEARCH_BM=m
1012CONFIG_TEXTSEARCH_FSM=m
1013 1015
1014# 1016#
1015# Instrumentation Support 1017# Instrumentation Support
@@ -1021,18 +1023,20 @@ CONFIG_TEXTSEARCH_FSM=m
1021# Kernel hacking 1023# Kernel hacking
1022# 1024#
1023# CONFIG_PRINTK_TIME is not set 1025# CONFIG_PRINTK_TIME is not set
1024CONFIG_DEBUG_KERNEL=y
1025CONFIG_MAGIC_SYSRQ=y 1026CONFIG_MAGIC_SYSRQ=y
1027CONFIG_DEBUG_KERNEL=y
1026CONFIG_LOG_BUF_SHIFT=15 1028CONFIG_LOG_BUF_SHIFT=15
1027CONFIG_DETECT_SOFTLOCKUP=y 1029CONFIG_DETECT_SOFTLOCKUP=y
1028# CONFIG_SCHEDSTATS is not set 1030# CONFIG_SCHEDSTATS is not set
1029# CONFIG_DEBUG_SLAB is not set 1031# CONFIG_DEBUG_SLAB is not set
1032CONFIG_DEBUG_MUTEXES=y
1030# CONFIG_DEBUG_SPINLOCK is not set 1033# CONFIG_DEBUG_SPINLOCK is not set
1031CONFIG_DEBUG_SPINLOCK_SLEEP=y 1034CONFIG_DEBUG_SPINLOCK_SLEEP=y
1032# CONFIG_DEBUG_KOBJECT is not set 1035# CONFIG_DEBUG_KOBJECT is not set
1033# CONFIG_DEBUG_INFO is not set 1036# CONFIG_DEBUG_INFO is not set
1034CONFIG_DEBUG_FS=y 1037CONFIG_DEBUG_FS=y
1035# CONFIG_DEBUG_VM is not set 1038# CONFIG_DEBUG_VM is not set
1039# CONFIG_FORCED_INLINING is not set
1036# CONFIG_RCU_TORTURE_TEST is not set 1040# CONFIG_RCU_TORTURE_TEST is not set
1037# CONFIG_DEBUG_STACKOVERFLOW is not set 1041# CONFIG_DEBUG_STACKOVERFLOW is not set
1038# CONFIG_DEBUG_STACK_USAGE is not set 1042# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1040,6 +1044,11 @@ CONFIG_DEBUGGER=y
1040# CONFIG_XMON is not set 1044# CONFIG_XMON is not set
1041CONFIG_IRQSTACKS=y 1045CONFIG_IRQSTACKS=y
1042# CONFIG_BOOTX_TEXT is not set 1046# CONFIG_BOOTX_TEXT is not set
1047# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
1048# CONFIG_PPC_EARLY_DEBUG_G5 is not set
1049# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
1050# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
1051# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
1043 1052
1044# 1053#
1045# Security options 1054# Security options
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index c775027947f9..1816a46742f6 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc5 3# Linux kernel version: 2.6.16-rc6
4# Tue Dec 20 15:59:32 2005 4# Wed Mar 15 16:19:52 2006
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -16,6 +16,10 @@ CONFIG_COMPAT=y
16CONFIG_SYSVIPC_COMPAT=y 16CONFIG_SYSVIPC_COMPAT=y
17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
18CONFIG_ARCH_MAY_HAVE_PC_FDC=y 18CONFIG_ARCH_MAY_HAVE_PC_FDC=y
19CONFIG_PPC_OF=y
20# CONFIG_PPC_UDBG_16550 is not set
21# CONFIG_GENERIC_TBSYNC is not set
22# CONFIG_DEFAULT_UIMAGE is not set
19 23
20# 24#
21# Processor support 25# Processor support
@@ -33,7 +37,6 @@ CONFIG_NR_CPUS=32
33# Code maturity level options 37# Code maturity level options
34# 38#
35CONFIG_EXPERIMENTAL=y 39CONFIG_EXPERIMENTAL=y
36CONFIG_CLEAN_COMPILE=y
37CONFIG_LOCK_KERNEL=y 40CONFIG_LOCK_KERNEL=y
38CONFIG_INIT_ENV_ARG_LIMIT=32 41CONFIG_INIT_ENV_ARG_LIMIT=32
39 42
@@ -49,8 +52,6 @@ CONFIG_POSIX_MQUEUE=y
49CONFIG_SYSCTL=y 52CONFIG_SYSCTL=y
50CONFIG_AUDIT=y 53CONFIG_AUDIT=y
51CONFIG_AUDITSYSCALL=y 54CONFIG_AUDITSYSCALL=y
52CONFIG_HOTPLUG=y
53CONFIG_KOBJECT_UEVENT=y
54CONFIG_IKCONFIG=y 55CONFIG_IKCONFIG=y
55CONFIG_IKCONFIG_PROC=y 56CONFIG_IKCONFIG_PROC=y
56# CONFIG_CPUSETS is not set 57# CONFIG_CPUSETS is not set
@@ -60,8 +61,10 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
60CONFIG_KALLSYMS=y 61CONFIG_KALLSYMS=y
61# CONFIG_KALLSYMS_ALL is not set 62# CONFIG_KALLSYMS_ALL is not set
62# CONFIG_KALLSYMS_EXTRA_PASS is not set 63# CONFIG_KALLSYMS_EXTRA_PASS is not set
64CONFIG_HOTPLUG=y
63CONFIG_PRINTK=y 65CONFIG_PRINTK=y
64CONFIG_BUG=y 66CONFIG_BUG=y
67CONFIG_ELF_CORE=y
65CONFIG_BASE_FULL=y 68CONFIG_BASE_FULL=y
66CONFIG_FUTEX=y 69CONFIG_FUTEX=y
67CONFIG_EPOLL=y 70CONFIG_EPOLL=y
@@ -70,8 +73,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
70CONFIG_CC_ALIGN_LABELS=0 73CONFIG_CC_ALIGN_LABELS=0
71CONFIG_CC_ALIGN_LOOPS=0 74CONFIG_CC_ALIGN_LOOPS=0
72CONFIG_CC_ALIGN_JUMPS=0 75CONFIG_CC_ALIGN_JUMPS=0
76CONFIG_SLAB=y
73# CONFIG_TINY_SHMEM is not set 77# CONFIG_TINY_SHMEM is not set
74CONFIG_BASE_SMALL=0 78CONFIG_BASE_SMALL=0
79# CONFIG_SLOB is not set
75 80
76# 81#
77# Loadable module support 82# Loadable module support
@@ -113,7 +118,6 @@ CONFIG_PPC_ISERIES=y
113# CONFIG_MMIO_NVRAM is not set 118# CONFIG_MMIO_NVRAM is not set
114CONFIG_IBMVIO=y 119CONFIG_IBMVIO=y
115# CONFIG_PPC_MPC106 is not set 120# CONFIG_PPC_MPC106 is not set
116# CONFIG_GENERIC_TBSYNC is not set
117# CONFIG_CPU_FREQ is not set 121# CONFIG_CPU_FREQ is not set
118# CONFIG_WANT_EARLY_SERIAL is not set 122# CONFIG_WANT_EARLY_SERIAL is not set
119 123
@@ -183,6 +187,7 @@ CONFIG_NET=y
183# 187#
184# Networking options 188# Networking options
185# 189#
190# CONFIG_NETDEBUG is not set
186CONFIG_PACKET=y 191CONFIG_PACKET=y
187# CONFIG_PACKET_MMAP is not set 192# CONFIG_PACKET_MMAP is not set
188CONFIG_UNIX=y 193CONFIG_UNIX=y
@@ -220,6 +225,28 @@ CONFIG_NETFILTER=y
220# Core Netfilter Configuration 225# Core Netfilter Configuration
221# 226#
222# CONFIG_NETFILTER_NETLINK is not set 227# CONFIG_NETFILTER_NETLINK is not set
228CONFIG_NETFILTER_XTABLES=m
229CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
230CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
231CONFIG_NETFILTER_XT_TARGET_MARK=m
232CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
233CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
234CONFIG_NETFILTER_XT_MATCH_COMMENT=m
235CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
236CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
237CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
238# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
239CONFIG_NETFILTER_XT_MATCH_HELPER=m
240CONFIG_NETFILTER_XT_MATCH_LENGTH=m
241CONFIG_NETFILTER_XT_MATCH_LIMIT=m
242CONFIG_NETFILTER_XT_MATCH_MAC=m
243CONFIG_NETFILTER_XT_MATCH_MARK=m
244CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
245CONFIG_NETFILTER_XT_MATCH_REALM=m
246CONFIG_NETFILTER_XT_MATCH_SCTP=m
247CONFIG_NETFILTER_XT_MATCH_STATE=m
248CONFIG_NETFILTER_XT_MATCH_STRING=m
249CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
223 250
224# 251#
225# IP: Netfilter Configuration 252# IP: Netfilter Configuration
@@ -237,39 +264,23 @@ CONFIG_IP_NF_AMANDA=m
237# CONFIG_IP_NF_PPTP is not set 264# CONFIG_IP_NF_PPTP is not set
238CONFIG_IP_NF_QUEUE=m 265CONFIG_IP_NF_QUEUE=m
239CONFIG_IP_NF_IPTABLES=m 266CONFIG_IP_NF_IPTABLES=m
240CONFIG_IP_NF_MATCH_LIMIT=m
241CONFIG_IP_NF_MATCH_IPRANGE=m 267CONFIG_IP_NF_MATCH_IPRANGE=m
242CONFIG_IP_NF_MATCH_MAC=m
243CONFIG_IP_NF_MATCH_PKTTYPE=m
244CONFIG_IP_NF_MATCH_MARK=m
245CONFIG_IP_NF_MATCH_MULTIPORT=m 268CONFIG_IP_NF_MATCH_MULTIPORT=m
246CONFIG_IP_NF_MATCH_TOS=m 269CONFIG_IP_NF_MATCH_TOS=m
247CONFIG_IP_NF_MATCH_RECENT=m 270CONFIG_IP_NF_MATCH_RECENT=m
248CONFIG_IP_NF_MATCH_ECN=m 271CONFIG_IP_NF_MATCH_ECN=m
249CONFIG_IP_NF_MATCH_DSCP=m 272CONFIG_IP_NF_MATCH_DSCP=m
250CONFIG_IP_NF_MATCH_AH_ESP=m 273CONFIG_IP_NF_MATCH_AH_ESP=m
251CONFIG_IP_NF_MATCH_LENGTH=m
252CONFIG_IP_NF_MATCH_TTL=m 274CONFIG_IP_NF_MATCH_TTL=m
253CONFIG_IP_NF_MATCH_TCPMSS=m
254CONFIG_IP_NF_MATCH_HELPER=m
255CONFIG_IP_NF_MATCH_STATE=m
256CONFIG_IP_NF_MATCH_CONNTRACK=m
257CONFIG_IP_NF_MATCH_OWNER=m 275CONFIG_IP_NF_MATCH_OWNER=m
258CONFIG_IP_NF_MATCH_ADDRTYPE=m 276CONFIG_IP_NF_MATCH_ADDRTYPE=m
259CONFIG_IP_NF_MATCH_REALM=m
260CONFIG_IP_NF_MATCH_SCTP=m
261# CONFIG_IP_NF_MATCH_DCCP is not set
262CONFIG_IP_NF_MATCH_COMMENT=m
263CONFIG_IP_NF_MATCH_CONNMARK=m
264CONFIG_IP_NF_MATCH_CONNBYTES=m
265CONFIG_IP_NF_MATCH_HASHLIMIT=m 277CONFIG_IP_NF_MATCH_HASHLIMIT=m
266CONFIG_IP_NF_MATCH_STRING=m 278CONFIG_IP_NF_MATCH_POLICY=m
267CONFIG_IP_NF_FILTER=m 279CONFIG_IP_NF_FILTER=m
268CONFIG_IP_NF_TARGET_REJECT=m 280CONFIG_IP_NF_TARGET_REJECT=m
269CONFIG_IP_NF_TARGET_LOG=m 281CONFIG_IP_NF_TARGET_LOG=m
270CONFIG_IP_NF_TARGET_ULOG=m 282CONFIG_IP_NF_TARGET_ULOG=m
271CONFIG_IP_NF_TARGET_TCPMSS=m 283CONFIG_IP_NF_TARGET_TCPMSS=m
272CONFIG_IP_NF_TARGET_NFQUEUE=m
273CONFIG_IP_NF_NAT=m 284CONFIG_IP_NF_NAT=m
274CONFIG_IP_NF_NAT_NEEDED=y 285CONFIG_IP_NF_NAT_NEEDED=y
275CONFIG_IP_NF_TARGET_MASQUERADE=m 286CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -285,13 +296,9 @@ CONFIG_IP_NF_MANGLE=m
285CONFIG_IP_NF_TARGET_TOS=m 296CONFIG_IP_NF_TARGET_TOS=m
286CONFIG_IP_NF_TARGET_ECN=m 297CONFIG_IP_NF_TARGET_ECN=m
287CONFIG_IP_NF_TARGET_DSCP=m 298CONFIG_IP_NF_TARGET_DSCP=m
288CONFIG_IP_NF_TARGET_MARK=m
289CONFIG_IP_NF_TARGET_CLASSIFY=m
290CONFIG_IP_NF_TARGET_TTL=m 299CONFIG_IP_NF_TARGET_TTL=m
291CONFIG_IP_NF_TARGET_CONNMARK=m
292CONFIG_IP_NF_TARGET_CLUSTERIP=m 300CONFIG_IP_NF_TARGET_CLUSTERIP=m
293CONFIG_IP_NF_RAW=m 301CONFIG_IP_NF_RAW=m
294CONFIG_IP_NF_TARGET_NOTRACK=m
295CONFIG_IP_NF_ARPTABLES=m 302CONFIG_IP_NF_ARPTABLES=m
296CONFIG_IP_NF_ARPFILTER=m 303CONFIG_IP_NF_ARPFILTER=m
297CONFIG_IP_NF_ARP_MANGLE=m 304CONFIG_IP_NF_ARP_MANGLE=m
@@ -305,6 +312,11 @@ CONFIG_IP_NF_ARP_MANGLE=m
305# SCTP Configuration (EXPERIMENTAL) 312# SCTP Configuration (EXPERIMENTAL)
306# 313#
307# CONFIG_IP_SCTP is not set 314# CONFIG_IP_SCTP is not set
315
316#
317# TIPC Configuration (EXPERIMENTAL)
318#
319# CONFIG_TIPC is not set
308# CONFIG_ATM is not set 320# CONFIG_ATM is not set
309# CONFIG_BRIDGE is not set 321# CONFIG_BRIDGE is not set
310# CONFIG_VLAN_8021Q is not set 322# CONFIG_VLAN_8021Q is not set
@@ -451,13 +463,7 @@ CONFIG_SCSI_IBMVSCSI=m
451# CONFIG_SCSI_IPR is not set 463# CONFIG_SCSI_IPR is not set
452# CONFIG_SCSI_QLOGIC_FC is not set 464# CONFIG_SCSI_QLOGIC_FC is not set
453# CONFIG_SCSI_QLOGIC_1280 is not set 465# CONFIG_SCSI_QLOGIC_1280 is not set
454CONFIG_SCSI_QLA2XXX=y 466# CONFIG_SCSI_QLA_FC is not set
455# CONFIG_SCSI_QLA21XX is not set
456# CONFIG_SCSI_QLA22XX is not set
457# CONFIG_SCSI_QLA2300 is not set
458# CONFIG_SCSI_QLA2322 is not set
459# CONFIG_SCSI_QLA6312 is not set
460# CONFIG_SCSI_QLA24XX is not set
461# CONFIG_SCSI_LPFC is not set 467# CONFIG_SCSI_LPFC is not set
462# CONFIG_SCSI_DC395x is not set 468# CONFIG_SCSI_DC395x is not set
463# CONFIG_SCSI_DC390T is not set 469# CONFIG_SCSI_DC390T is not set
@@ -574,6 +580,7 @@ CONFIG_E1000=m
574# CONFIG_R8169 is not set 580# CONFIG_R8169 is not set
575# CONFIG_SIS190 is not set 581# CONFIG_SIS190 is not set
576# CONFIG_SKGE is not set 582# CONFIG_SKGE is not set
583# CONFIG_SKY2 is not set
577# CONFIG_SK98LIN is not set 584# CONFIG_SK98LIN is not set
578# CONFIG_VIA_VELOCITY is not set 585# CONFIG_VIA_VELOCITY is not set
579# CONFIG_TIGON3 is not set 586# CONFIG_TIGON3 is not set
@@ -723,6 +730,12 @@ CONFIG_MAX_RAW_DEVS=256
723# CONFIG_I2C is not set 730# CONFIG_I2C is not set
724 731
725# 732#
733# SPI support
734#
735# CONFIG_SPI is not set
736# CONFIG_SPI_MASTER is not set
737
738#
726# Dallas's 1-wire bus 739# Dallas's 1-wire bus
727# 740#
728# CONFIG_W1 is not set 741# CONFIG_W1 is not set
@@ -788,7 +801,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
788# CONFIG_INFINIBAND is not set 801# CONFIG_INFINIBAND is not set
789 802
790# 803#
791# SN Devices 804# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
792# 805#
793 806
794# 807#
@@ -825,6 +838,7 @@ CONFIG_XFS_EXPORT=y
825CONFIG_XFS_SECURITY=y 838CONFIG_XFS_SECURITY=y
826CONFIG_XFS_POSIX_ACL=y 839CONFIG_XFS_POSIX_ACL=y
827# CONFIG_XFS_RT is not set 840# CONFIG_XFS_RT is not set
841# CONFIG_OCFS2_FS is not set
828# CONFIG_MINIX_FS is not set 842# CONFIG_MINIX_FS is not set
829# CONFIG_ROMFS_FS is not set 843# CONFIG_ROMFS_FS is not set
830CONFIG_INOTIFY=y 844CONFIG_INOTIFY=y
@@ -865,6 +879,7 @@ CONFIG_TMPFS=y
865# CONFIG_HUGETLB_PAGE is not set 879# CONFIG_HUGETLB_PAGE is not set
866CONFIG_RAMFS=y 880CONFIG_RAMFS=y
867# CONFIG_RELAYFS_FS is not set 881# CONFIG_RELAYFS_FS is not set
882# CONFIG_CONFIGFS_FS is not set
868 883
869# 884#
870# Miscellaneous filesystems 885# Miscellaneous filesystems
@@ -993,31 +1008,36 @@ CONFIG_TEXTSEARCH_FSM=m
993# 1008#
994# Instrumentation Support 1009# Instrumentation Support
995# 1010#
996CONFIG_PROFILING=y
997CONFIG_OPROFILE=y
998# CONFIG_KPROBES is not set 1011# CONFIG_KPROBES is not set
999 1012
1000# 1013#
1001# Kernel hacking 1014# Kernel hacking
1002# 1015#
1003# CONFIG_PRINTK_TIME is not set 1016# CONFIG_PRINTK_TIME is not set
1004CONFIG_DEBUG_KERNEL=y
1005CONFIG_MAGIC_SYSRQ=y 1017CONFIG_MAGIC_SYSRQ=y
1018CONFIG_DEBUG_KERNEL=y
1006CONFIG_LOG_BUF_SHIFT=17 1019CONFIG_LOG_BUF_SHIFT=17
1007CONFIG_DETECT_SOFTLOCKUP=y 1020CONFIG_DETECT_SOFTLOCKUP=y
1008# CONFIG_SCHEDSTATS is not set 1021# CONFIG_SCHEDSTATS is not set
1009# CONFIG_DEBUG_SLAB is not set 1022# CONFIG_DEBUG_SLAB is not set
1023# CONFIG_DEBUG_MUTEXES is not set
1010# CONFIG_DEBUG_SPINLOCK is not set 1024# CONFIG_DEBUG_SPINLOCK is not set
1011# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1025# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1012# CONFIG_DEBUG_KOBJECT is not set 1026# CONFIG_DEBUG_KOBJECT is not set
1013# CONFIG_DEBUG_INFO is not set 1027# CONFIG_DEBUG_INFO is not set
1014CONFIG_DEBUG_FS=y 1028CONFIG_DEBUG_FS=y
1015# CONFIG_DEBUG_VM is not set 1029# CONFIG_DEBUG_VM is not set
1030# CONFIG_FORCED_INLINING is not set
1016# CONFIG_RCU_TORTURE_TEST is not set 1031# CONFIG_RCU_TORTURE_TEST is not set
1017CONFIG_DEBUG_STACKOVERFLOW=y 1032CONFIG_DEBUG_STACKOVERFLOW=y
1018CONFIG_DEBUG_STACK_USAGE=y 1033CONFIG_DEBUG_STACK_USAGE=y
1019# CONFIG_DEBUGGER is not set 1034# CONFIG_DEBUGGER is not set
1020CONFIG_IRQSTACKS=y 1035CONFIG_IRQSTACKS=y
1036# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
1037# CONFIG_PPC_EARLY_DEBUG_G5 is not set
1038# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
1039# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
1040# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
1021 1041
1022# 1042#
1023# Security options 1043# Security options
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 68194c03f6d1..80a0db43aeb7 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc5 3# Linux kernel version: 2.6.16-rc6
4# Tue Dec 20 15:59:36 2005 4# Wed Mar 15 16:19:54 2006
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -16,6 +16,10 @@ CONFIG_COMPAT=y
16CONFIG_SYSVIPC_COMPAT=y 16CONFIG_SYSVIPC_COMPAT=y
17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
18CONFIG_ARCH_MAY_HAVE_PC_FDC=y 18CONFIG_ARCH_MAY_HAVE_PC_FDC=y
19CONFIG_PPC_OF=y
20CONFIG_PPC_UDBG_16550=y
21CONFIG_GENERIC_TBSYNC=y
22# CONFIG_DEFAULT_UIMAGE is not set
19 23
20# 24#
21# Processor support 25# Processor support
@@ -32,7 +36,6 @@ CONFIG_NR_CPUS=2
32# Code maturity level options 36# Code maturity level options
33# 37#
34CONFIG_EXPERIMENTAL=y 38CONFIG_EXPERIMENTAL=y
35CONFIG_CLEAN_COMPILE=y
36CONFIG_LOCK_KERNEL=y 39CONFIG_LOCK_KERNEL=y
37CONFIG_INIT_ENV_ARG_LIMIT=32 40CONFIG_INIT_ENV_ARG_LIMIT=32
38 41
@@ -47,8 +50,6 @@ CONFIG_POSIX_MQUEUE=y
47# CONFIG_BSD_PROCESS_ACCT is not set 50# CONFIG_BSD_PROCESS_ACCT is not set
48CONFIG_SYSCTL=y 51CONFIG_SYSCTL=y
49# CONFIG_AUDIT is not set 52# CONFIG_AUDIT is not set
50# CONFIG_HOTPLUG is not set
51CONFIG_KOBJECT_UEVENT=y
52CONFIG_IKCONFIG=y 53CONFIG_IKCONFIG=y
53CONFIG_IKCONFIG_PROC=y 54CONFIG_IKCONFIG_PROC=y
54# CONFIG_CPUSETS is not set 55# CONFIG_CPUSETS is not set
@@ -58,8 +59,10 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
58CONFIG_KALLSYMS=y 59CONFIG_KALLSYMS=y
59CONFIG_KALLSYMS_ALL=y 60CONFIG_KALLSYMS_ALL=y
60# CONFIG_KALLSYMS_EXTRA_PASS is not set 61# CONFIG_KALLSYMS_EXTRA_PASS is not set
62CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y 63CONFIG_PRINTK=y
62CONFIG_BUG=y 64CONFIG_BUG=y
65CONFIG_ELF_CORE=y
63CONFIG_BASE_FULL=y 66CONFIG_BASE_FULL=y
64CONFIG_FUTEX=y 67CONFIG_FUTEX=y
65CONFIG_EPOLL=y 68CONFIG_EPOLL=y
@@ -68,8 +71,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
68CONFIG_CC_ALIGN_LABELS=0 71CONFIG_CC_ALIGN_LABELS=0
69CONFIG_CC_ALIGN_LOOPS=0 72CONFIG_CC_ALIGN_LOOPS=0
70CONFIG_CC_ALIGN_JUMPS=0 73CONFIG_CC_ALIGN_JUMPS=0
74CONFIG_SLAB=y
71# CONFIG_TINY_SHMEM is not set 75# CONFIG_TINY_SHMEM is not set
72CONFIG_BASE_SMALL=0 76CONFIG_BASE_SMALL=0
77# CONFIG_SLOB is not set
73 78
74# 79#
75# Loadable module support 80# Loadable module support
@@ -111,14 +116,12 @@ CONFIG_PPC_MULTIPLATFORM=y
111# CONFIG_PPC_PMAC is not set 116# CONFIG_PPC_PMAC is not set
112CONFIG_PPC_MAPLE=y 117CONFIG_PPC_MAPLE=y
113# CONFIG_PPC_CELL is not set 118# CONFIG_PPC_CELL is not set
114CONFIG_PPC_OF=y
115CONFIG_U3_DART=y 119CONFIG_U3_DART=y
116CONFIG_MPIC=y 120CONFIG_MPIC=y
117# CONFIG_PPC_RTAS is not set 121# CONFIG_PPC_RTAS is not set
118# CONFIG_MMIO_NVRAM is not set 122# CONFIG_MMIO_NVRAM is not set
119CONFIG_MPIC_BROKEN_U3=y 123CONFIG_MPIC_BROKEN_U3=y
120# CONFIG_PPC_MPC106 is not set 124# CONFIG_PPC_MPC106 is not set
121CONFIG_GENERIC_TBSYNC=y
122# CONFIG_CPU_FREQ is not set 125# CONFIG_CPU_FREQ is not set
123# CONFIG_WANT_EARLY_SERIAL is not set 126# CONFIG_WANT_EARLY_SERIAL is not set
124 127
@@ -138,6 +141,7 @@ CONFIG_BINFMT_ELF=y
138CONFIG_FORCE_MAX_ZONEORDER=13 141CONFIG_FORCE_MAX_ZONEORDER=13
139CONFIG_IOMMU_VMERGE=y 142CONFIG_IOMMU_VMERGE=y
140CONFIG_KEXEC=y 143CONFIG_KEXEC=y
144# CONFIG_CRASH_DUMP is not set
141CONFIG_IRQ_ALL_CPUS=y 145CONFIG_IRQ_ALL_CPUS=y
142# CONFIG_NUMA is not set 146# CONFIG_NUMA is not set
143CONFIG_ARCH_SELECT_MEMORY_MODEL=y 147CONFIG_ARCH_SELECT_MEMORY_MODEL=y
@@ -189,6 +193,7 @@ CONFIG_NET=y
189# 193#
190# Networking options 194# Networking options
191# 195#
196# CONFIG_NETDEBUG is not set
192CONFIG_PACKET=y 197CONFIG_PACKET=y
193CONFIG_PACKET_MMAP=y 198CONFIG_PACKET_MMAP=y
194CONFIG_UNIX=y 199CONFIG_UNIX=y
@@ -226,6 +231,11 @@ CONFIG_TCP_CONG_BIC=y
226# SCTP Configuration (EXPERIMENTAL) 231# SCTP Configuration (EXPERIMENTAL)
227# 232#
228# CONFIG_IP_SCTP is not set 233# CONFIG_IP_SCTP is not set
234
235#
236# TIPC Configuration (EXPERIMENTAL)
237#
238# CONFIG_TIPC is not set
229# CONFIG_ATM is not set 239# CONFIG_ATM is not set
230# CONFIG_BRIDGE is not set 240# CONFIG_BRIDGE is not set
231# CONFIG_VLAN_8021Q is not set 241# CONFIG_VLAN_8021Q is not set
@@ -461,6 +471,7 @@ CONFIG_E1000=y
461# CONFIG_R8169 is not set 471# CONFIG_R8169 is not set
462# CONFIG_SIS190 is not set 472# CONFIG_SIS190 is not set
463# CONFIG_SKGE is not set 473# CONFIG_SKGE is not set
474# CONFIG_SKY2 is not set
464# CONFIG_SK98LIN is not set 475# CONFIG_SK98LIN is not set
465# CONFIG_VIA_VELOCITY is not set 476# CONFIG_VIA_VELOCITY is not set
466# CONFIG_TIGON3 is not set 477# CONFIG_TIGON3 is not set
@@ -553,6 +564,7 @@ CONFIG_HW_CONSOLE=y
553CONFIG_SERIAL_8250=y 564CONFIG_SERIAL_8250=y
554CONFIG_SERIAL_8250_CONSOLE=y 565CONFIG_SERIAL_8250_CONSOLE=y
555CONFIG_SERIAL_8250_NR_UARTS=4 566CONFIG_SERIAL_8250_NR_UARTS=4
567CONFIG_SERIAL_8250_RUNTIME_UARTS=4
556# CONFIG_SERIAL_8250_EXTENDED is not set 568# CONFIG_SERIAL_8250_EXTENDED is not set
557 569
558# 570#
@@ -651,6 +663,12 @@ CONFIG_I2C_AMD8111=y
651# CONFIG_I2C_DEBUG_CHIP is not set 663# CONFIG_I2C_DEBUG_CHIP is not set
652 664
653# 665#
666# SPI support
667#
668# CONFIG_SPI is not set
669# CONFIG_SPI_MASTER is not set
670
671#
654# Dallas's 1-wire bus 672# Dallas's 1-wire bus
655# 673#
656# CONFIG_W1 is not set 674# CONFIG_W1 is not set
@@ -738,12 +756,14 @@ CONFIG_USB_UHCI_HCD=y
738# may also be needed; see USB_STORAGE Help for more information 756# may also be needed; see USB_STORAGE Help for more information
739# 757#
740# CONFIG_USB_STORAGE is not set 758# CONFIG_USB_STORAGE is not set
759# CONFIG_USB_LIBUSUAL is not set
741 760
742# 761#
743# USB Input Devices 762# USB Input Devices
744# 763#
745CONFIG_USB_HID=y 764CONFIG_USB_HID=y
746CONFIG_USB_HIDINPUT=y 765CONFIG_USB_HIDINPUT=y
766# CONFIG_USB_HIDINPUT_POWERBOOK is not set
747# CONFIG_HID_FF is not set 767# CONFIG_HID_FF is not set
748# CONFIG_USB_HIDDEV is not set 768# CONFIG_USB_HIDDEV is not set
749# CONFIG_USB_AIPTEK is not set 769# CONFIG_USB_AIPTEK is not set
@@ -757,6 +777,7 @@ CONFIG_USB_HIDINPUT=y
757# CONFIG_USB_YEALINK is not set 777# CONFIG_USB_YEALINK is not set
758# CONFIG_USB_XPAD is not set 778# CONFIG_USB_XPAD is not set
759# CONFIG_USB_ATI_REMOTE is not set 779# CONFIG_USB_ATI_REMOTE is not set
780# CONFIG_USB_ATI_REMOTE2 is not set
760# CONFIG_USB_KEYSPAN_REMOTE is not set 781# CONFIG_USB_KEYSPAN_REMOTE is not set
761# CONFIG_USB_APPLETOUCH is not set 782# CONFIG_USB_APPLETOUCH is not set
762 783
@@ -797,6 +818,7 @@ CONFIG_USB_SERIAL_GENERIC=y
797# CONFIG_USB_SERIAL_AIRPRIME is not set 818# CONFIG_USB_SERIAL_AIRPRIME is not set
798# CONFIG_USB_SERIAL_ANYDATA is not set 819# CONFIG_USB_SERIAL_ANYDATA is not set
799# CONFIG_USB_SERIAL_BELKIN is not set 820# CONFIG_USB_SERIAL_BELKIN is not set
821# CONFIG_USB_SERIAL_WHITEHEAT is not set
800# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set 822# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
801# CONFIG_USB_SERIAL_CP2101 is not set 823# CONFIG_USB_SERIAL_CP2101 is not set
802CONFIG_USB_SERIAL_CYPRESS_M8=m 824CONFIG_USB_SERIAL_CYPRESS_M8=m
@@ -873,7 +895,7 @@ CONFIG_USB_EZUSB=y
873# CONFIG_INFINIBAND is not set 895# CONFIG_INFINIBAND is not set
874 896
875# 897#
876# SN Devices 898# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
877# 899#
878 900
879# 901#
@@ -891,6 +913,7 @@ CONFIG_JBD=y
891# CONFIG_JFS_FS is not set 913# CONFIG_JFS_FS is not set
892CONFIG_FS_POSIX_ACL=y 914CONFIG_FS_POSIX_ACL=y
893# CONFIG_XFS_FS is not set 915# CONFIG_XFS_FS is not set
916# CONFIG_OCFS2_FS is not set
894# CONFIG_MINIX_FS is not set 917# CONFIG_MINIX_FS is not set
895# CONFIG_ROMFS_FS is not set 918# CONFIG_ROMFS_FS is not set
896CONFIG_INOTIFY=y 919CONFIG_INOTIFY=y
@@ -927,6 +950,7 @@ CONFIG_HUGETLBFS=y
927CONFIG_HUGETLB_PAGE=y 950CONFIG_HUGETLB_PAGE=y
928CONFIG_RAMFS=y 951CONFIG_RAMFS=y
929# CONFIG_RELAYFS_FS is not set 952# CONFIG_RELAYFS_FS is not set
953# CONFIG_CONFIGFS_FS is not set
930 954
931# 955#
932# Miscellaneous filesystems 956# Miscellaneous filesystems
@@ -988,6 +1012,7 @@ CONFIG_MSDOS_PARTITION=y
988# CONFIG_SGI_PARTITION is not set 1012# CONFIG_SGI_PARTITION is not set
989# CONFIG_ULTRIX_PARTITION is not set 1013# CONFIG_ULTRIX_PARTITION is not set
990# CONFIG_SUN_PARTITION is not set 1014# CONFIG_SUN_PARTITION is not set
1015# CONFIG_KARMA_PARTITION is not set
991# CONFIG_EFI_PARTITION is not set 1016# CONFIG_EFI_PARTITION is not set
992 1017
993# 1018#
@@ -1053,18 +1078,20 @@ CONFIG_ZLIB_INFLATE=y
1053# Kernel hacking 1078# Kernel hacking
1054# 1079#
1055# CONFIG_PRINTK_TIME is not set 1080# CONFIG_PRINTK_TIME is not set
1056CONFIG_DEBUG_KERNEL=y
1057CONFIG_MAGIC_SYSRQ=y 1081CONFIG_MAGIC_SYSRQ=y
1082CONFIG_DEBUG_KERNEL=y
1058CONFIG_LOG_BUF_SHIFT=17 1083CONFIG_LOG_BUF_SHIFT=17
1059CONFIG_DETECT_SOFTLOCKUP=y 1084CONFIG_DETECT_SOFTLOCKUP=y
1060# CONFIG_SCHEDSTATS is not set 1085# CONFIG_SCHEDSTATS is not set
1061CONFIG_DEBUG_SLAB=y 1086CONFIG_DEBUG_SLAB=y
1087# CONFIG_DEBUG_MUTEXES is not set
1062# CONFIG_DEBUG_SPINLOCK is not set 1088# CONFIG_DEBUG_SPINLOCK is not set
1063CONFIG_DEBUG_SPINLOCK_SLEEP=y 1089CONFIG_DEBUG_SPINLOCK_SLEEP=y
1064# CONFIG_DEBUG_KOBJECT is not set 1090# CONFIG_DEBUG_KOBJECT is not set
1065# CONFIG_DEBUG_INFO is not set 1091# CONFIG_DEBUG_INFO is not set
1066CONFIG_DEBUG_FS=y 1092CONFIG_DEBUG_FS=y
1067# CONFIG_DEBUG_VM is not set 1093# CONFIG_DEBUG_VM is not set
1094# CONFIG_FORCED_INLINING is not set
1068# CONFIG_RCU_TORTURE_TEST is not set 1095# CONFIG_RCU_TORTURE_TEST is not set
1069CONFIG_DEBUG_STACKOVERFLOW=y 1096CONFIG_DEBUG_STACKOVERFLOW=y
1070CONFIG_DEBUG_STACK_USAGE=y 1097CONFIG_DEBUG_STACK_USAGE=y
@@ -1073,6 +1100,11 @@ CONFIG_XMON=y
1073CONFIG_XMON_DEFAULT=y 1100CONFIG_XMON_DEFAULT=y
1074# CONFIG_IRQSTACKS is not set 1101# CONFIG_IRQSTACKS is not set
1075CONFIG_BOOTX_TEXT=y 1102CONFIG_BOOTX_TEXT=y
1103# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
1104# CONFIG_PPC_EARLY_DEBUG_G5 is not set
1105# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
1106# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
1107# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
1076 1108
1077# 1109#
1078# Security options 1110# Security options
diff --git a/arch/powerpc/configs/mpc834x_sys_defconfig b/arch/powerpc/configs/mpc834x_sys_defconfig
index 3bff761965c2..5078b0441d61 100644
--- a/arch/powerpc/configs/mpc834x_sys_defconfig
+++ b/arch/powerpc/configs/mpc834x_sys_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-g461d4edf-dirty 3# Linux kernel version: 2.6.16-rc6
4# Fri Jan 13 11:01:47 2006 4# Wed Mar 15 16:19:56 2006
5# 5#
6# CONFIG_PPC64 is not set 6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y 7CONFIG_PPC32=y
@@ -43,7 +43,6 @@ CONFIG_PPC_STD_MMU_32=y
43# Code maturity level options 43# Code maturity level options
44# 44#
45CONFIG_EXPERIMENTAL=y 45CONFIG_EXPERIMENTAL=y
46CONFIG_CLEAN_COMPILE=y
47CONFIG_BROKEN_ON_SMP=y 46CONFIG_BROKEN_ON_SMP=y
48CONFIG_INIT_ENV_ARG_LIMIT=32 47CONFIG_INIT_ENV_ARG_LIMIT=32
49 48
@@ -189,6 +188,7 @@ CONFIG_NET=y
189# 188#
190# Networking options 189# Networking options
191# 190#
191# CONFIG_NETDEBUG is not set
192CONFIG_PACKET=y 192CONFIG_PACKET=y
193# CONFIG_PACKET_MMAP is not set 193# CONFIG_PACKET_MMAP is not set
194CONFIG_UNIX=y 194CONFIG_UNIX=y
@@ -226,6 +226,11 @@ CONFIG_TCP_CONG_BIC=y
226# SCTP Configuration (EXPERIMENTAL) 226# SCTP Configuration (EXPERIMENTAL)
227# 227#
228# CONFIG_IP_SCTP is not set 228# CONFIG_IP_SCTP is not set
229
230#
231# TIPC Configuration (EXPERIMENTAL)
232#
233# CONFIG_TIPC is not set
229# CONFIG_ATM is not set 234# CONFIG_ATM is not set
230# CONFIG_BRIDGE is not set 235# CONFIG_BRIDGE is not set
231# CONFIG_VLAN_8021Q is not set 236# CONFIG_VLAN_8021Q is not set
@@ -511,6 +516,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
511# 516#
512CONFIG_SERIAL_CORE=y 517CONFIG_SERIAL_CORE=y
513CONFIG_SERIAL_CORE_CONSOLE=y 518CONFIG_SERIAL_CORE_CONSOLE=y
519# CONFIG_SERIAL_JSM is not set
514CONFIG_UNIX98_PTYS=y 520CONFIG_UNIX98_PTYS=y
515CONFIG_LEGACY_PTYS=y 521CONFIG_LEGACY_PTYS=y
516CONFIG_LEGACY_PTY_COUNT=256 522CONFIG_LEGACY_PTY_COUNT=256
@@ -615,6 +621,12 @@ CONFIG_I2C_MPC=y
615# CONFIG_I2C_DEBUG_CHIP is not set 621# CONFIG_I2C_DEBUG_CHIP is not set
616 622
617# 623#
624# SPI support
625#
626# CONFIG_SPI is not set
627# CONFIG_SPI_MASTER is not set
628
629#
618# Dallas's 1-wire bus 630# Dallas's 1-wire bus
619# 631#
620# CONFIG_W1 is not set 632# CONFIG_W1 is not set
@@ -632,6 +644,7 @@ CONFIG_HWMON=y
632# CONFIG_SENSORS_ASB100 is not set 644# CONFIG_SENSORS_ASB100 is not set
633# CONFIG_SENSORS_ATXP1 is not set 645# CONFIG_SENSORS_ATXP1 is not set
634# CONFIG_SENSORS_DS1621 is not set 646# CONFIG_SENSORS_DS1621 is not set
647# CONFIG_SENSORS_F71805F is not set
635# CONFIG_SENSORS_FSCHER is not set 648# CONFIG_SENSORS_FSCHER is not set
636# CONFIG_SENSORS_FSCPOS is not set 649# CONFIG_SENSORS_FSCPOS is not set
637# CONFIG_SENSORS_GL518SM is not set 650# CONFIG_SENSORS_GL518SM is not set
@@ -716,7 +729,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
716# CONFIG_INFINIBAND is not set 729# CONFIG_INFINIBAND is not set
717 730
718# 731#
719# SN Devices 732# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
720# 733#
721 734
722# 735#
@@ -826,6 +839,7 @@ CONFIG_PARTITION_ADVANCED=y
826# CONFIG_SGI_PARTITION is not set 839# CONFIG_SGI_PARTITION is not set
827# CONFIG_ULTRIX_PARTITION is not set 840# CONFIG_ULTRIX_PARTITION is not set
828# CONFIG_SUN_PARTITION is not set 841# CONFIG_SUN_PARTITION is not set
842# CONFIG_KARMA_PARTITION is not set
829# CONFIG_EFI_PARTITION is not set 843# CONFIG_EFI_PARTITION is not set
830 844
831# 845#
@@ -899,13 +913,3 @@ CONFIG_CRYPTO_DES=y
899# 913#
900# Hardware crypto devices 914# Hardware crypto devices
901# 915#
902
903#
904# SEC2.x Options
905#
906CONFIG_MPC8349E_SEC2x=y
907
908#
909# SEC2.x Test Options
910#
911CONFIG_MPC8349E_SEC2xTEST=y
diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig
new file mode 100644
index 000000000000..7f0780f1aa39
--- /dev/null
+++ b/arch/powerpc/configs/mpc8540_ads_defconfig
@@ -0,0 +1,728 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16
4# Mon Mar 27 23:37:36 2006
5#
6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
12CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y
14CONFIG_PPC=y
15CONFIG_EARLY_PRINTK=y
16CONFIG_GENERIC_NVRAM=y
17CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
18CONFIG_ARCH_MAY_HAVE_PC_FDC=y
19CONFIG_PPC_OF=y
20CONFIG_PPC_UDBG_16550=y
21# CONFIG_GENERIC_TBSYNC is not set
22CONFIG_DEFAULT_UIMAGE=y
23
24#
25# Processor support
26#
27# CONFIG_CLASSIC32 is not set
28# CONFIG_PPC_52xx is not set
29# CONFIG_PPC_82xx is not set
30# CONFIG_PPC_83xx is not set
31CONFIG_PPC_85xx=y
32# CONFIG_40x is not set
33# CONFIG_44x is not set
34# CONFIG_8xx is not set
35# CONFIG_E200 is not set
36CONFIG_85xx=y
37CONFIG_E500=y
38CONFIG_BOOKE=y
39CONFIG_FSL_BOOKE=y
40# CONFIG_PHYS_64BIT is not set
41CONFIG_SPE=y
42
43#
44# Code maturity level options
45#
46CONFIG_EXPERIMENTAL=y
47CONFIG_BROKEN_ON_SMP=y
48CONFIG_INIT_ENV_ARG_LIMIT=32
49
50#
51# General setup
52#
53CONFIG_LOCALVERSION=""
54CONFIG_LOCALVERSION_AUTO=y
55CONFIG_SWAP=y
56CONFIG_SYSVIPC=y
57# CONFIG_POSIX_MQUEUE is not set
58# CONFIG_BSD_PROCESS_ACCT is not set
59CONFIG_SYSCTL=y
60# CONFIG_AUDIT is not set
61# CONFIG_IKCONFIG is not set
62# CONFIG_RELAY is not set
63CONFIG_INITRAMFS_SOURCE=""
64# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
65CONFIG_EMBEDDED=y
66CONFIG_KALLSYMS=y
67# CONFIG_KALLSYMS_ALL is not set
68# CONFIG_KALLSYMS_EXTRA_PASS is not set
69CONFIG_HOTPLUG=y
70CONFIG_PRINTK=y
71CONFIG_BUG=y
72CONFIG_ELF_CORE=y
73CONFIG_BASE_FULL=y
74CONFIG_FUTEX=y
75CONFIG_EPOLL=y
76CONFIG_SHMEM=y
77CONFIG_SLAB=y
78# CONFIG_TINY_SHMEM is not set
79CONFIG_BASE_SMALL=0
80# CONFIG_SLOB is not set
81
82#
83# Loadable module support
84#
85# CONFIG_MODULES is not set
86
87#
88# Block layer
89#
90# CONFIG_LBD is not set
91# CONFIG_BLK_DEV_IO_TRACE is not set
92# CONFIG_LSF is not set
93
94#
95# IO Schedulers
96#
97CONFIG_IOSCHED_NOOP=y
98CONFIG_IOSCHED_AS=y
99CONFIG_IOSCHED_DEADLINE=y
100CONFIG_IOSCHED_CFQ=y
101CONFIG_DEFAULT_AS=y
102# CONFIG_DEFAULT_DEADLINE is not set
103# CONFIG_DEFAULT_CFQ is not set
104# CONFIG_DEFAULT_NOOP is not set
105CONFIG_DEFAULT_IOSCHED="anticipatory"
106CONFIG_MPIC=y
107# CONFIG_WANT_EARLY_SERIAL is not set
108
109#
110# Platform support
111#
112CONFIG_MPC8540_ADS=y
113CONFIG_MPC8540=y
114CONFIG_PPC_INDIRECT_PCI_BE=y
115
116#
117# Kernel options
118#
119# CONFIG_HIGHMEM is not set
120# CONFIG_HZ_100 is not set
121CONFIG_HZ_250=y
122# CONFIG_HZ_1000 is not set
123CONFIG_HZ=250
124CONFIG_PREEMPT_NONE=y
125# CONFIG_PREEMPT_VOLUNTARY is not set
126# CONFIG_PREEMPT is not set
127CONFIG_BINFMT_ELF=y
128CONFIG_BINFMT_MISC=y
129CONFIG_MATH_EMULATION=y
130CONFIG_ARCH_FLATMEM_ENABLE=y
131CONFIG_SELECT_MEMORY_MODEL=y
132CONFIG_FLATMEM_MANUAL=y
133# CONFIG_DISCONTIGMEM_MANUAL is not set
134# CONFIG_SPARSEMEM_MANUAL is not set
135CONFIG_FLATMEM=y
136CONFIG_FLAT_NODE_MEM_MAP=y
137# CONFIG_SPARSEMEM_STATIC is not set
138CONFIG_SPLIT_PTLOCK_CPUS=4
139CONFIG_PROC_DEVICETREE=y
140# CONFIG_CMDLINE_BOOL is not set
141# CONFIG_PM is not set
142# CONFIG_SOFTWARE_SUSPEND is not set
143# CONFIG_SECCOMP is not set
144CONFIG_ISA_DMA_API=y
145
146#
147# Bus options
148#
149# CONFIG_PPC_I8259 is not set
150CONFIG_PPC_INDIRECT_PCI=y
151CONFIG_FSL_SOC=y
152# CONFIG_PCI is not set
153# CONFIG_PCI_DOMAINS is not set
154
155#
156# PCCARD (PCMCIA/CardBus) support
157#
158# CONFIG_PCCARD is not set
159
160#
161# PCI Hotplug Support
162#
163
164#
165# Advanced setup
166#
167# CONFIG_ADVANCED_OPTIONS is not set
168
169#
170# Default settings for advanced configuration options are used
171#
172CONFIG_HIGHMEM_START=0xfe000000
173CONFIG_LOWMEM_SIZE=0x30000000
174CONFIG_KERNEL_START=0xc0000000
175CONFIG_TASK_SIZE=0x80000000
176CONFIG_BOOT_LOAD=0x00800000
177
178#
179# Networking
180#
181CONFIG_NET=y
182
183#
184# Networking options
185#
186# CONFIG_NETDEBUG is not set
187CONFIG_PACKET=y
188# CONFIG_PACKET_MMAP is not set
189CONFIG_UNIX=y
190# CONFIG_NET_KEY is not set
191CONFIG_INET=y
192CONFIG_IP_MULTICAST=y
193# CONFIG_IP_ADVANCED_ROUTER is not set
194CONFIG_IP_FIB_HASH=y
195CONFIG_IP_PNP=y
196CONFIG_IP_PNP_DHCP=y
197CONFIG_IP_PNP_BOOTP=y
198# CONFIG_IP_PNP_RARP is not set
199# CONFIG_NET_IPIP is not set
200# CONFIG_NET_IPGRE is not set
201# CONFIG_IP_MROUTE is not set
202# CONFIG_ARPD is not set
203CONFIG_SYN_COOKIES=y
204# CONFIG_INET_AH is not set
205# CONFIG_INET_ESP is not set
206# CONFIG_INET_IPCOMP is not set
207# CONFIG_INET_TUNNEL is not set
208CONFIG_INET_DIAG=y
209CONFIG_INET_TCP_DIAG=y
210# CONFIG_TCP_CONG_ADVANCED is not set
211CONFIG_TCP_CONG_BIC=y
212# CONFIG_IPV6 is not set
213# CONFIG_NETFILTER is not set
214
215#
216# DCCP Configuration (EXPERIMENTAL)
217#
218# CONFIG_IP_DCCP is not set
219
220#
221# SCTP Configuration (EXPERIMENTAL)
222#
223# CONFIG_IP_SCTP is not set
224
225#
226# TIPC Configuration (EXPERIMENTAL)
227#
228# CONFIG_TIPC is not set
229# CONFIG_ATM is not set
230# CONFIG_BRIDGE is not set
231# CONFIG_VLAN_8021Q is not set
232# CONFIG_DECNET is not set
233# CONFIG_LLC2 is not set
234# CONFIG_IPX is not set
235# CONFIG_ATALK is not set
236# CONFIG_X25 is not set
237# CONFIG_LAPB is not set
238# CONFIG_NET_DIVERT is not set
239# CONFIG_ECONET is not set
240# CONFIG_WAN_ROUTER is not set
241
242#
243# QoS and/or fair queueing
244#
245# CONFIG_NET_SCHED is not set
246
247#
248# Network testing
249#
250# CONFIG_NET_PKTGEN is not set
251# CONFIG_HAMRADIO is not set
252# CONFIG_IRDA is not set
253# CONFIG_BT is not set
254# CONFIG_IEEE80211 is not set
255
256#
257# Device Drivers
258#
259
260#
261# Generic Driver Options
262#
263CONFIG_STANDALONE=y
264CONFIG_PREVENT_FIRMWARE_BUILD=y
265# CONFIG_FW_LOADER is not set
266# CONFIG_DEBUG_DRIVER is not set
267
268#
269# Connector - unified userspace <-> kernelspace linker
270#
271# CONFIG_CONNECTOR is not set
272
273#
274# Memory Technology Devices (MTD)
275#
276# CONFIG_MTD is not set
277
278#
279# Parallel port support
280#
281# CONFIG_PARPORT is not set
282
283#
284# Plug and Play support
285#
286
287#
288# Block devices
289#
290# CONFIG_BLK_DEV_FD is not set
291# CONFIG_BLK_DEV_COW_COMMON is not set
292CONFIG_BLK_DEV_LOOP=y
293# CONFIG_BLK_DEV_CRYPTOLOOP is not set
294# CONFIG_BLK_DEV_NBD is not set
295CONFIG_BLK_DEV_RAM=y
296CONFIG_BLK_DEV_RAM_COUNT=16
297CONFIG_BLK_DEV_RAM_SIZE=32768
298CONFIG_BLK_DEV_INITRD=y
299# CONFIG_CDROM_PKTCDVD is not set
300# CONFIG_ATA_OVER_ETH is not set
301
302#
303# ATA/ATAPI/MFM/RLL support
304#
305# CONFIG_IDE is not set
306
307#
308# SCSI device support
309#
310# CONFIG_RAID_ATTRS is not set
311# CONFIG_SCSI is not set
312
313#
314# Multi-device support (RAID and LVM)
315#
316# CONFIG_MD is not set
317
318#
319# Fusion MPT device support
320#
321# CONFIG_FUSION is not set
322
323#
324# IEEE 1394 (FireWire) support
325#
326
327#
328# I2O device support
329#
330
331#
332# Macintosh device drivers
333#
334# CONFIG_WINDFARM is not set
335
336#
337# Network device support
338#
339CONFIG_NETDEVICES=y
340# CONFIG_DUMMY is not set
341# CONFIG_BONDING is not set
342# CONFIG_EQUALIZER is not set
343# CONFIG_TUN is not set
344
345#
346# PHY device support
347#
348CONFIG_PHYLIB=y
349
350#
351# MII PHY device drivers
352#
353# CONFIG_MARVELL_PHY is not set
354# CONFIG_DAVICOM_PHY is not set
355# CONFIG_QSEMI_PHY is not set
356# CONFIG_LXT_PHY is not set
357# CONFIG_CICADA_PHY is not set
358
359#
360# Ethernet (10 or 100Mbit)
361#
362CONFIG_NET_ETHERNET=y
363CONFIG_MII=y
364
365#
366# Ethernet (1000 Mbit)
367#
368CONFIG_GIANFAR=y
369CONFIG_GFAR_NAPI=y
370
371#
372# Ethernet (10000 Mbit)
373#
374
375#
376# Token Ring devices
377#
378
379#
380# Wireless LAN (non-hamradio)
381#
382# CONFIG_NET_RADIO is not set
383
384#
385# Wan interfaces
386#
387# CONFIG_WAN is not set
388# CONFIG_PPP is not set
389# CONFIG_SLIP is not set
390# CONFIG_SHAPER is not set
391# CONFIG_NETCONSOLE is not set
392# CONFIG_NETPOLL is not set
393# CONFIG_NET_POLL_CONTROLLER is not set
394
395#
396# ISDN subsystem
397#
398# CONFIG_ISDN is not set
399
400#
401# Telephony Support
402#
403# CONFIG_PHONE is not set
404
405#
406# Input device support
407#
408CONFIG_INPUT=y
409
410#
411# Userland interfaces
412#
413# CONFIG_INPUT_MOUSEDEV is not set
414# CONFIG_INPUT_JOYDEV is not set
415# CONFIG_INPUT_TSDEV is not set
416# CONFIG_INPUT_EVDEV is not set
417# CONFIG_INPUT_EVBUG is not set
418
419#
420# Input Device Drivers
421#
422# CONFIG_INPUT_KEYBOARD is not set
423# CONFIG_INPUT_MOUSE is not set
424# CONFIG_INPUT_JOYSTICK is not set
425# CONFIG_INPUT_TOUCHSCREEN is not set
426# CONFIG_INPUT_MISC is not set
427
428#
429# Hardware I/O ports
430#
431# CONFIG_SERIO is not set
432# CONFIG_GAMEPORT is not set
433
434#
435# Character devices
436#
437# CONFIG_VT is not set
438# CONFIG_SERIAL_NONSTANDARD is not set
439
440#
441# Serial drivers
442#
443CONFIG_SERIAL_8250=y
444CONFIG_SERIAL_8250_CONSOLE=y
445CONFIG_SERIAL_8250_NR_UARTS=4
446CONFIG_SERIAL_8250_RUNTIME_UARTS=4
447# CONFIG_SERIAL_8250_EXTENDED is not set
448
449#
450# Non-8250 serial port support
451#
452CONFIG_SERIAL_CORE=y
453CONFIG_SERIAL_CORE_CONSOLE=y
454CONFIG_UNIX98_PTYS=y
455CONFIG_LEGACY_PTYS=y
456CONFIG_LEGACY_PTY_COUNT=256
457
458#
459# IPMI
460#
461# CONFIG_IPMI_HANDLER is not set
462
463#
464# Watchdog Cards
465#
466# CONFIG_WATCHDOG is not set
467# CONFIG_NVRAM is not set
468CONFIG_GEN_RTC=y
469# CONFIG_GEN_RTC_X is not set
470# CONFIG_DTLK is not set
471# CONFIG_R3964 is not set
472
473#
474# Ftape, the floppy tape device driver
475#
476# CONFIG_AGP is not set
477# CONFIG_RAW_DRIVER is not set
478
479#
480# TPM devices
481#
482# CONFIG_TCG_TPM is not set
483# CONFIG_TELCLOCK is not set
484
485#
486# I2C support
487#
488# CONFIG_I2C is not set
489
490#
491# SPI support
492#
493# CONFIG_SPI is not set
494# CONFIG_SPI_MASTER is not set
495
496#
497# Dallas's 1-wire bus
498#
499# CONFIG_W1 is not set
500
501#
502# Hardware Monitoring support
503#
504CONFIG_HWMON=y
505# CONFIG_HWMON_VID is not set
506# CONFIG_SENSORS_F71805F is not set
507# CONFIG_HWMON_DEBUG_CHIP is not set
508
509#
510# Misc devices
511#
512
513#
514# Multimedia devices
515#
516# CONFIG_VIDEO_DEV is not set
517
518#
519# Digital Video Broadcasting Devices
520#
521# CONFIG_DVB is not set
522
523#
524# Graphics support
525#
526# CONFIG_FB is not set
527
528#
529# Sound
530#
531# CONFIG_SOUND is not set
532
533#
534# USB support
535#
536# CONFIG_USB_ARCH_HAS_HCD is not set
537# CONFIG_USB_ARCH_HAS_OHCI is not set
538# CONFIG_USB_ARCH_HAS_EHCI is not set
539
540#
541# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
542#
543
544#
545# USB Gadget Support
546#
547# CONFIG_USB_GADGET is not set
548
549#
550# MMC/SD Card support
551#
552# CONFIG_MMC is not set
553
554#
555# InfiniBand support
556#
557
558#
559# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
560#
561
562#
563# File systems
564#
565CONFIG_EXT2_FS=y
566# CONFIG_EXT2_FS_XATTR is not set
567# CONFIG_EXT2_FS_XIP is not set
568CONFIG_EXT3_FS=y
569CONFIG_EXT3_FS_XATTR=y
570# CONFIG_EXT3_FS_POSIX_ACL is not set
571# CONFIG_EXT3_FS_SECURITY is not set
572CONFIG_JBD=y
573# CONFIG_JBD_DEBUG is not set
574CONFIG_FS_MBCACHE=y
575# CONFIG_REISERFS_FS is not set
576# CONFIG_JFS_FS is not set
577# CONFIG_FS_POSIX_ACL is not set
578# CONFIG_XFS_FS is not set
579# CONFIG_OCFS2_FS is not set
580# CONFIG_MINIX_FS is not set
581# CONFIG_ROMFS_FS is not set
582CONFIG_INOTIFY=y
583# CONFIG_QUOTA is not set
584CONFIG_DNOTIFY=y
585# CONFIG_AUTOFS_FS is not set
586# CONFIG_AUTOFS4_FS is not set
587# CONFIG_FUSE_FS is not set
588
589#
590# CD-ROM/DVD Filesystems
591#
592# CONFIG_ISO9660_FS is not set
593# CONFIG_UDF_FS is not set
594
595#
596# DOS/FAT/NT Filesystems
597#
598# CONFIG_MSDOS_FS is not set
599# CONFIG_VFAT_FS is not set
600# CONFIG_NTFS_FS is not set
601
602#
603# Pseudo filesystems
604#
605CONFIG_PROC_FS=y
606CONFIG_PROC_KCORE=y
607CONFIG_SYSFS=y
608CONFIG_TMPFS=y
609# CONFIG_HUGETLB_PAGE is not set
610CONFIG_RAMFS=y
611# CONFIG_CONFIGFS_FS is not set
612
613#
614# Miscellaneous filesystems
615#
616# CONFIG_ADFS_FS is not set
617# CONFIG_AFFS_FS is not set
618# CONFIG_HFS_FS is not set
619# CONFIG_HFSPLUS_FS is not set
620# CONFIG_BEFS_FS is not set
621# CONFIG_BFS_FS is not set
622# CONFIG_EFS_FS is not set
623# CONFIG_CRAMFS is not set
624# CONFIG_VXFS_FS is not set
625# CONFIG_HPFS_FS is not set
626# CONFIG_QNX4FS_FS is not set
627# CONFIG_SYSV_FS is not set
628# CONFIG_UFS_FS is not set
629
630#
631# Network File Systems
632#
633CONFIG_NFS_FS=y
634# CONFIG_NFS_V3 is not set
635# CONFIG_NFS_V4 is not set
636# CONFIG_NFS_DIRECTIO is not set
637# CONFIG_NFSD is not set
638CONFIG_ROOT_NFS=y
639CONFIG_LOCKD=y
640CONFIG_NFS_COMMON=y
641CONFIG_SUNRPC=y
642# CONFIG_RPCSEC_GSS_KRB5 is not set
643# CONFIG_RPCSEC_GSS_SPKM3 is not set
644# CONFIG_SMB_FS is not set
645# CONFIG_CIFS is not set
646# CONFIG_NCP_FS is not set
647# CONFIG_CODA_FS is not set
648# CONFIG_AFS_FS is not set
649# CONFIG_9P_FS is not set
650
651#
652# Partition Types
653#
654CONFIG_PARTITION_ADVANCED=y
655# CONFIG_ACORN_PARTITION is not set
656# CONFIG_OSF_PARTITION is not set
657# CONFIG_AMIGA_PARTITION is not set
658# CONFIG_ATARI_PARTITION is not set
659# CONFIG_MAC_PARTITION is not set
660# CONFIG_MSDOS_PARTITION is not set
661# CONFIG_LDM_PARTITION is not set
662# CONFIG_SGI_PARTITION is not set
663# CONFIG_ULTRIX_PARTITION is not set
664# CONFIG_SUN_PARTITION is not set
665# CONFIG_KARMA_PARTITION is not set
666# CONFIG_EFI_PARTITION is not set
667
668#
669# Native Language Support
670#
671# CONFIG_NLS is not set
672
673#
674# Library routines
675#
676# CONFIG_CRC_CCITT is not set
677# CONFIG_CRC16 is not set
678CONFIG_CRC32=y
679# CONFIG_LIBCRC32C is not set
680
681#
682# Instrumentation Support
683#
684# CONFIG_PROFILING is not set
685
686#
687# Kernel hacking
688#
689# CONFIG_PRINTK_TIME is not set
690# CONFIG_MAGIC_SYSRQ is not set
691CONFIG_DEBUG_KERNEL=y
692CONFIG_LOG_BUF_SHIFT=14
693CONFIG_DETECT_SOFTLOCKUP=y
694# CONFIG_SCHEDSTATS is not set
695# CONFIG_DEBUG_SLAB is not set
696CONFIG_DEBUG_MUTEXES=y
697# CONFIG_DEBUG_SPINLOCK is not set
698# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
699# CONFIG_DEBUG_KOBJECT is not set
700# CONFIG_DEBUG_INFO is not set
701# CONFIG_DEBUG_FS is not set
702# CONFIG_DEBUG_VM is not set
703# CONFIG_UNWIND_INFO is not set
704CONFIG_FORCED_INLINING=y
705# CONFIG_RCU_TORTURE_TEST is not set
706# CONFIG_DEBUGGER is not set
707# CONFIG_BDI_SWITCH is not set
708# CONFIG_BOOTX_TEXT is not set
709# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
710# CONFIG_PPC_EARLY_DEBUG_G5 is not set
711# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
712# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
713# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
714
715#
716# Security options
717#
718# CONFIG_KEYS is not set
719# CONFIG_SECURITY is not set
720
721#
722# Cryptographic options
723#
724# CONFIG_CRYPTO is not set
725
726#
727# Hardware crypto devices
728#
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 2ace57d1e333..57a027971d67 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15 3# Linux kernel version: 2.6.16-rc6
4# Sat Jan 14 16:26:08 2006 4# Wed Mar 15 16:21:32 2006
5# 5#
6# CONFIG_PPC64 is not set 6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y 7CONFIG_PPC32=y
@@ -17,8 +17,8 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
17CONFIG_ARCH_MAY_HAVE_PC_FDC=y 17CONFIG_ARCH_MAY_HAVE_PC_FDC=y
18CONFIG_PPC_OF=y 18CONFIG_PPC_OF=y
19# CONFIG_PPC_UDBG_16550 is not set 19# CONFIG_PPC_UDBG_16550 is not set
20# CONFIG_CRASH_DUMP is not set
21# CONFIG_GENERIC_TBSYNC is not set 20# CONFIG_GENERIC_TBSYNC is not set
21# CONFIG_DEFAULT_UIMAGE is not set
22 22
23# 23#
24# Processor support 24# Processor support
@@ -43,7 +43,6 @@ CONFIG_PPC_STD_MMU_32=y
43# Code maturity level options 43# Code maturity level options
44# 44#
45CONFIG_EXPERIMENTAL=y 45CONFIG_EXPERIMENTAL=y
46CONFIG_CLEAN_COMPILE=y
47CONFIG_BROKEN_ON_SMP=y 46CONFIG_BROKEN_ON_SMP=y
48CONFIG_INIT_ENV_ARG_LIMIT=32 47CONFIG_INIT_ENV_ARG_LIMIT=32
49 48
@@ -236,6 +235,7 @@ CONFIG_NET=y
236# 235#
237# Networking options 236# Networking options
238# 237#
238# CONFIG_NETDEBUG is not set
239CONFIG_PACKET=y 239CONFIG_PACKET=y
240# CONFIG_PACKET_MMAP is not set 240# CONFIG_PACKET_MMAP is not set
241CONFIG_UNIX=y 241CONFIG_UNIX=y
@@ -271,6 +271,25 @@ CONFIG_NETFILTER=y
271# Core Netfilter Configuration 271# Core Netfilter Configuration
272# 272#
273# CONFIG_NETFILTER_NETLINK is not set 273# CONFIG_NETFILTER_NETLINK is not set
274CONFIG_NETFILTER_XTABLES=m
275CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
276CONFIG_NETFILTER_XT_TARGET_MARK=m
277CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
278CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
279CONFIG_NETFILTER_XT_MATCH_COMMENT=m
280CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
281# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
282CONFIG_NETFILTER_XT_MATCH_HELPER=m
283CONFIG_NETFILTER_XT_MATCH_LENGTH=m
284CONFIG_NETFILTER_XT_MATCH_LIMIT=m
285CONFIG_NETFILTER_XT_MATCH_MAC=m
286CONFIG_NETFILTER_XT_MATCH_MARK=m
287CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
288CONFIG_NETFILTER_XT_MATCH_REALM=m
289CONFIG_NETFILTER_XT_MATCH_SCTP=m
290CONFIG_NETFILTER_XT_MATCH_STATE=m
291CONFIG_NETFILTER_XT_MATCH_STRING=m
292CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
274 293
275# 294#
276# IP: Netfilter Configuration 295# IP: Netfilter Configuration
@@ -288,37 +307,22 @@ CONFIG_IP_NF_AMANDA=m
288CONFIG_IP_NF_PPTP=m 307CONFIG_IP_NF_PPTP=m
289# CONFIG_IP_NF_QUEUE is not set 308# CONFIG_IP_NF_QUEUE is not set
290CONFIG_IP_NF_IPTABLES=m 309CONFIG_IP_NF_IPTABLES=m
291CONFIG_IP_NF_MATCH_LIMIT=m
292CONFIG_IP_NF_MATCH_IPRANGE=m 310CONFIG_IP_NF_MATCH_IPRANGE=m
293CONFIG_IP_NF_MATCH_MAC=m
294CONFIG_IP_NF_MATCH_PKTTYPE=m
295CONFIG_IP_NF_MATCH_MARK=m
296CONFIG_IP_NF_MATCH_MULTIPORT=m 311CONFIG_IP_NF_MATCH_MULTIPORT=m
297CONFIG_IP_NF_MATCH_TOS=m 312CONFIG_IP_NF_MATCH_TOS=m
298CONFIG_IP_NF_MATCH_RECENT=m 313CONFIG_IP_NF_MATCH_RECENT=m
299CONFIG_IP_NF_MATCH_ECN=m 314CONFIG_IP_NF_MATCH_ECN=m
300CONFIG_IP_NF_MATCH_DSCP=m 315CONFIG_IP_NF_MATCH_DSCP=m
301CONFIG_IP_NF_MATCH_AH_ESP=m 316CONFIG_IP_NF_MATCH_AH_ESP=m
302CONFIG_IP_NF_MATCH_LENGTH=m
303CONFIG_IP_NF_MATCH_TTL=m 317CONFIG_IP_NF_MATCH_TTL=m
304CONFIG_IP_NF_MATCH_TCPMSS=m
305CONFIG_IP_NF_MATCH_HELPER=m
306CONFIG_IP_NF_MATCH_STATE=m
307CONFIG_IP_NF_MATCH_CONNTRACK=m
308CONFIG_IP_NF_MATCH_OWNER=m 318CONFIG_IP_NF_MATCH_OWNER=m
309# CONFIG_IP_NF_MATCH_ADDRTYPE is not set 319CONFIG_IP_NF_MATCH_ADDRTYPE=m
310# CONFIG_IP_NF_MATCH_REALM is not set 320CONFIG_IP_NF_MATCH_HASHLIMIT=m
311# CONFIG_IP_NF_MATCH_SCTP is not set
312CONFIG_IP_NF_MATCH_DCCP=m
313# CONFIG_IP_NF_MATCH_COMMENT is not set
314# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
315CONFIG_IP_NF_MATCH_STRING=m
316CONFIG_IP_NF_FILTER=m 321CONFIG_IP_NF_FILTER=m
317CONFIG_IP_NF_TARGET_REJECT=m 322CONFIG_IP_NF_TARGET_REJECT=m
318# CONFIG_IP_NF_TARGET_LOG is not set 323CONFIG_IP_NF_TARGET_LOG=m
319CONFIG_IP_NF_TARGET_ULOG=m 324CONFIG_IP_NF_TARGET_ULOG=m
320CONFIG_IP_NF_TARGET_TCPMSS=m 325CONFIG_IP_NF_TARGET_TCPMSS=m
321# CONFIG_IP_NF_TARGET_NFQUEUE is not set
322CONFIG_IP_NF_NAT=m 326CONFIG_IP_NF_NAT=m
323CONFIG_IP_NF_NAT_NEEDED=y 327CONFIG_IP_NF_NAT_NEEDED=y
324CONFIG_IP_NF_TARGET_MASQUERADE=m 328CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -331,9 +335,12 @@ CONFIG_IP_NF_NAT_FTP=m
331CONFIG_IP_NF_NAT_TFTP=m 335CONFIG_IP_NF_NAT_TFTP=m
332CONFIG_IP_NF_NAT_AMANDA=m 336CONFIG_IP_NF_NAT_AMANDA=m
333CONFIG_IP_NF_NAT_PPTP=m 337CONFIG_IP_NF_NAT_PPTP=m
334# CONFIG_IP_NF_MANGLE is not set 338CONFIG_IP_NF_MANGLE=m
339CONFIG_IP_NF_TARGET_TOS=m
340CONFIG_IP_NF_TARGET_ECN=m
341CONFIG_IP_NF_TARGET_DSCP=m
342CONFIG_IP_NF_TARGET_TTL=m
335CONFIG_IP_NF_RAW=m 343CONFIG_IP_NF_RAW=m
336CONFIG_IP_NF_TARGET_NOTRACK=m
337CONFIG_IP_NF_ARPTABLES=m 344CONFIG_IP_NF_ARPTABLES=m
338CONFIG_IP_NF_ARPFILTER=m 345CONFIG_IP_NF_ARPFILTER=m
339CONFIG_IP_NF_ARP_MANGLE=m 346CONFIG_IP_NF_ARP_MANGLE=m
@@ -360,6 +367,11 @@ CONFIG_IP_DCCP_TFRC_LIB=m
360# SCTP Configuration (EXPERIMENTAL) 367# SCTP Configuration (EXPERIMENTAL)
361# 368#
362# CONFIG_IP_SCTP is not set 369# CONFIG_IP_SCTP is not set
370
371#
372# TIPC Configuration (EXPERIMENTAL)
373#
374# CONFIG_TIPC is not set
363# CONFIG_ATM is not set 375# CONFIG_ATM is not set
364# CONFIG_BRIDGE is not set 376# CONFIG_BRIDGE is not set
365# CONFIG_VLAN_8021Q is not set 377# CONFIG_VLAN_8021Q is not set
@@ -377,6 +389,7 @@ CONFIG_IP_DCCP_TFRC_LIB=m
377# QoS and/or fair queueing 389# QoS and/or fair queueing
378# 390#
379# CONFIG_NET_SCHED is not set 391# CONFIG_NET_SCHED is not set
392CONFIG_NET_CLS_ROUTE=y
380 393
381# 394#
382# Network testing 395# Network testing
@@ -568,7 +581,6 @@ CONFIG_IDEDMA_PCI_AUTO=y
568# CONFIG_BLK_DEV_NS87415 is not set 581# CONFIG_BLK_DEV_NS87415 is not set
569# CONFIG_BLK_DEV_PDC202XX_OLD is not set 582# CONFIG_BLK_DEV_PDC202XX_OLD is not set
570CONFIG_BLK_DEV_PDC202XX_NEW=y 583CONFIG_BLK_DEV_PDC202XX_NEW=y
571# CONFIG_PDC202XX_FORCE is not set
572# CONFIG_BLK_DEV_SVWKS is not set 584# CONFIG_BLK_DEV_SVWKS is not set
573# CONFIG_BLK_DEV_SIIMAGE is not set 585# CONFIG_BLK_DEV_SIIMAGE is not set
574# CONFIG_BLK_DEV_SLC90E66 is not set 586# CONFIG_BLK_DEV_SLC90E66 is not set
@@ -654,8 +666,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
654# CONFIG_SCSI_IPR is not set 666# CONFIG_SCSI_IPR is not set
655# CONFIG_SCSI_QLOGIC_FC is not set 667# CONFIG_SCSI_QLOGIC_FC is not set
656# CONFIG_SCSI_QLOGIC_1280 is not set 668# CONFIG_SCSI_QLOGIC_1280 is not set
657CONFIG_SCSI_QLA2XXX=y 669# CONFIG_SCSI_QLA_FC is not set
658# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set
659# CONFIG_SCSI_LPFC is not set 670# CONFIG_SCSI_LPFC is not set
660# CONFIG_SCSI_DC395x is not set 671# CONFIG_SCSI_DC395x is not set
661# CONFIG_SCSI_DC390T is not set 672# CONFIG_SCSI_DC390T is not set
@@ -991,6 +1002,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
991# 1002#
992CONFIG_SERIAL_CORE=m 1003CONFIG_SERIAL_CORE=m
993CONFIG_SERIAL_PMACZILOG=m 1004CONFIG_SERIAL_PMACZILOG=m
1005# CONFIG_SERIAL_JSM is not set
994CONFIG_UNIX98_PTYS=y 1006CONFIG_UNIX98_PTYS=y
995CONFIG_LEGACY_PTYS=y 1007CONFIG_LEGACY_PTYS=y
996CONFIG_LEGACY_PTY_COUNT=256 1008CONFIG_LEGACY_PTY_COUNT=256
@@ -1098,6 +1110,12 @@ CONFIG_I2C_POWERMAC=y
1098# CONFIG_I2C_DEBUG_CHIP is not set 1110# CONFIG_I2C_DEBUG_CHIP is not set
1099 1111
1100# 1112#
1113# SPI support
1114#
1115# CONFIG_SPI is not set
1116# CONFIG_SPI_MASTER is not set
1117
1118#
1101# Dallas's 1-wire bus 1119# Dallas's 1-wire bus
1102# 1120#
1103# CONFIG_W1 is not set 1121# CONFIG_W1 is not set
@@ -1348,6 +1366,7 @@ CONFIG_USB_PRINTER=m
1348# 1366#
1349CONFIG_USB_HID=y 1367CONFIG_USB_HID=y
1350CONFIG_USB_HIDINPUT=y 1368CONFIG_USB_HIDINPUT=y
1369CONFIG_USB_HIDINPUT_POWERBOOK=y
1351# CONFIG_HID_FF is not set 1370# CONFIG_HID_FF is not set
1352# CONFIG_USB_HIDDEV is not set 1371# CONFIG_USB_HIDDEV is not set
1353# CONFIG_USB_AIPTEK is not set 1372# CONFIG_USB_AIPTEK is not set
@@ -1488,7 +1507,7 @@ CONFIG_USB_EZUSB=y
1488# CONFIG_INFINIBAND is not set 1507# CONFIG_INFINIBAND is not set
1489 1508
1490# 1509#
1491# SN Devices 1510# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1492# 1511#
1493 1512
1494# 1513#
@@ -1609,6 +1628,7 @@ CONFIG_MSDOS_PARTITION=y
1609# CONFIG_SGI_PARTITION is not set 1628# CONFIG_SGI_PARTITION is not set
1610# CONFIG_ULTRIX_PARTITION is not set 1629# CONFIG_ULTRIX_PARTITION is not set
1611# CONFIG_SUN_PARTITION is not set 1630# CONFIG_SUN_PARTITION is not set
1631# CONFIG_KARMA_PARTITION is not set
1612# CONFIG_EFI_PARTITION is not set 1632# CONFIG_EFI_PARTITION is not set
1613 1633
1614# 1634#
@@ -1692,6 +1712,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
1692# CONFIG_DEBUG_INFO is not set 1712# CONFIG_DEBUG_INFO is not set
1693# CONFIG_DEBUG_FS is not set 1713# CONFIG_DEBUG_FS is not set
1694# CONFIG_DEBUG_VM is not set 1714# CONFIG_DEBUG_VM is not set
1715# CONFIG_FORCED_INLINING is not set
1695# CONFIG_RCU_TORTURE_TEST is not set 1716# CONFIG_RCU_TORTURE_TEST is not set
1696CONFIG_DEBUGGER=y 1717CONFIG_DEBUGGER=y
1697CONFIG_XMON=y 1718CONFIG_XMON=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 0362a70aa97c..395e49847788 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -407,7 +407,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y
407# CONFIG_BLK_DEV_OFFBOARD is not set 407# CONFIG_BLK_DEV_OFFBOARD is not set
408CONFIG_BLK_DEV_GENERIC=y 408CONFIG_BLK_DEV_GENERIC=y
409# CONFIG_BLK_DEV_OPTI621 is not set 409# CONFIG_BLK_DEV_OPTI621 is not set
410# CONFIG_BLK_DEV_SL82C105 is not set 410CONFIG_BLK_DEV_SL82C105=y
411CONFIG_BLK_DEV_IDEDMA_PCI=y 411CONFIG_BLK_DEV_IDEDMA_PCI=y
412# CONFIG_BLK_DEV_IDEDMA_FORCED is not set 412# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
413CONFIG_IDEDMA_PCI_AUTO=y 413CONFIG_IDEDMA_PCI_AUTO=y
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 80e9fe2632b8..0cc0995b81b0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -12,12 +12,12 @@ endif
12 12
13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ 13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
14 irq.o align.o signal_32.o pmc.o vdso.o \ 14 irq.o align.o signal_32.o pmc.o vdso.o \
15 init_task.o process.o systbl.o 15 init_task.o process.o systbl.o idle.o
16obj-y += vdso32/ 16obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(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_power4.o \ 19 paca.o cpu_setup_power4.o \
20 firmware.o sysfs.o idle_64.o 20 firmware.o sysfs.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_POWER4) += idle_power4.o
@@ -34,6 +34,11 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o
34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o 35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
37obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
38obj-$(CONFIG_TAU) += tau_6xx.o
39obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
40obj32-$(CONFIG_MODULES) += module_32.o
41obj-$(CONFIG_E500) += perfmon_fsl_booke.o
37 42
38ifeq ($(CONFIG_PPC_MERGE),y) 43ifeq ($(CONFIG_PPC_MERGE),y)
39 44
@@ -51,7 +56,6 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
51obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 56obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
52obj-$(CONFIG_MODULES) += ppc_ksyms.o 57obj-$(CONFIG_MODULES) += ppc_ksyms.o
53obj-$(CONFIG_BOOTX_TEXT) += btext.o 58obj-$(CONFIG_BOOTX_TEXT) += btext.o
54obj-$(CONFIG_6xx) += idle_6xx.o
55obj-$(CONFIG_SMP) += smp.o 59obj-$(CONFIG_SMP) += smp.o
56obj-$(CONFIG_KPROBES) += kprobes.o 60obj-$(CONFIG_KPROBES) += kprobes.o
57obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o 61obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
@@ -77,6 +81,7 @@ smpobj-$(CONFIG_SMP) += smp.o
77 81
78endif 82endif
79 83
84obj-$(CONFIG_PPC32) += $(obj32-y)
80obj-$(CONFIG_PPC64) += $(obj64-y) 85obj-$(CONFIG_PPC64) += $(obj64-y)
81 86
82extra-$(CONFIG_PPC_FPU) += fpu.o 87extra-$(CONFIG_PPC_FPU) += fpu.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index c9a660e4c2db..54b48f330051 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -105,8 +105,6 @@ int main(void)
105 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); 105 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
106 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); 106 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
107 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); 107 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
108 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
109
110 /* paca */ 108 /* paca */
111 DEFINE(PACA_SIZE, sizeof(struct paca_struct)); 109 DEFINE(PACA_SIZE, sizeof(struct paca_struct));
112 DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); 110 DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
@@ -136,6 +134,9 @@ int main(void)
136 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); 134 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
137 DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); 135 DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
138 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 136 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
137 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
138 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
139 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
139 140
140 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 141 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
141 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); 142 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
new file mode 100644
index 000000000000..55ed7716636f
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -0,0 +1,474 @@
1/*
2 * This file contains low level CPU setup functions.
3 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <linux/config.h>
13#include <asm/processor.h>
14#include <asm/page.h>
15#include <asm/cputable.h>
16#include <asm/ppc_asm.h>
17#include <asm/asm-offsets.h>
18#include <asm/cache.h>
19
20_GLOBAL(__setup_cpu_603)
21 b setup_common_caches
22_GLOBAL(__setup_cpu_604)
23 mflr r4
24 bl setup_common_caches
25 bl setup_604_hid0
26 mtlr r4
27 blr
28_GLOBAL(__setup_cpu_750)
29 mflr r4
30 bl __init_fpu_registers
31 bl setup_common_caches
32 bl setup_750_7400_hid0
33 mtlr r4
34 blr
35_GLOBAL(__setup_cpu_750cx)
36 mflr r4
37 bl __init_fpu_registers
38 bl setup_common_caches
39 bl setup_750_7400_hid0
40 bl setup_750cx
41 mtlr r4
42 blr
43_GLOBAL(__setup_cpu_750fx)
44 mflr r4
45 bl __init_fpu_registers
46 bl setup_common_caches
47 bl setup_750_7400_hid0
48 bl setup_750fx
49 mtlr r4
50 blr
51_GLOBAL(__setup_cpu_7400)
52 mflr r4
53 bl __init_fpu_registers
54 bl setup_7400_workarounds
55 bl setup_common_caches
56 bl setup_750_7400_hid0
57 mtlr r4
58 blr
59_GLOBAL(__setup_cpu_7410)
60 mflr r4
61 bl __init_fpu_registers
62 bl setup_7410_workarounds
63 bl setup_common_caches
64 bl setup_750_7400_hid0
65 li r3,0
66 mtspr SPRN_L2CR2,r3
67 mtlr r4
68 blr
69_GLOBAL(__setup_cpu_745x)
70 mflr r4
71 bl setup_common_caches
72 bl setup_745x_specifics
73 mtlr r4
74 blr
75
76/* Enable caches for 603's, 604, 750 & 7400 */
77setup_common_caches:
78 mfspr r11,SPRN_HID0
79 andi. r0,r11,HID0_DCE
80 ori r11,r11,HID0_ICE|HID0_DCE
81 ori r8,r11,HID0_ICFI
82 bne 1f /* don't invalidate the D-cache */
83 ori r8,r8,HID0_DCI /* unless it wasn't enabled */
841: sync
85 mtspr SPRN_HID0,r8 /* enable and invalidate caches */
86 sync
87 mtspr SPRN_HID0,r11 /* enable caches */
88 sync
89 isync
90 blr
91
92/* 604, 604e, 604ev, ...
93 * Enable superscalar execution & branch history table
94 */
95setup_604_hid0:
96 mfspr r11,SPRN_HID0
97 ori r11,r11,HID0_SIED|HID0_BHTE
98 ori r8,r11,HID0_BTCD
99 sync
100 mtspr SPRN_HID0,r8 /* flush branch target address cache */
101 sync /* on 604e/604r */
102 mtspr SPRN_HID0,r11
103 sync
104 isync
105 blr
106
107/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some
108 * erratas we work around here.
109 * Moto MPC710CE.pdf describes them, those are errata
110 * #3, #4 and #5
111 * Note that we assume the firmware didn't choose to
112 * apply other workarounds (there are other ones documented
113 * in the .pdf). It appear that Apple firmware only works
114 * around #3 and with the same fix we use. We may want to
115 * check if the CPU is using 60x bus mode in which case
116 * the workaround for errata #4 is useless. Also, we may
117 * want to explicitely clear HID0_NOPDST as this is not
118 * needed once we have applied workaround #5 (though it's
119 * not set by Apple's firmware at least).
120 */
121setup_7400_workarounds:
122 mfpvr r3
123 rlwinm r3,r3,0,20,31
124 cmpwi 0,r3,0x0207
125 ble 1f
126 blr
127setup_7410_workarounds:
128 mfpvr r3
129 rlwinm r3,r3,0,20,31
130 cmpwi 0,r3,0x0100
131 bnelr
1321:
133 mfspr r11,SPRN_MSSSR0
134 /* Errata #3: Set L1OPQ_SIZE to 0x10 */
135 rlwinm r11,r11,0,9,6
136 oris r11,r11,0x0100
137 /* Errata #4: Set L2MQ_SIZE to 1 (check for MPX mode first ?) */
138 oris r11,r11,0x0002
139 /* Errata #5: Set DRLT_SIZE to 0x01 */
140 rlwinm r11,r11,0,5,2
141 oris r11,r11,0x0800
142 sync
143 mtspr SPRN_MSSSR0,r11
144 sync
145 isync
146 blr
147
148/* 740/750/7400/7410
149 * Enable Store Gathering (SGE), Address Brodcast (ABE),
150 * Branch History Table (BHTE), Branch Target ICache (BTIC)
151 * Dynamic Power Management (DPM), Speculative (SPD)
152 * Clear Instruction cache throttling (ICTC)
153 */
154setup_750_7400_hid0:
155 mfspr r11,SPRN_HID0
156 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
157 oris r11,r11,HID0_DPM@h
158BEGIN_FTR_SECTION
159 xori r11,r11,HID0_BTIC
160END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
161BEGIN_FTR_SECTION
162 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
163END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
164 li r3,HID0_SPD
165 andc r11,r11,r3 /* clear SPD: enable speculative */
166 li r3,0
167 mtspr SPRN_ICTC,r3 /* Instruction Cache Throttling off */
168 isync
169 mtspr SPRN_HID0,r11
170 sync
171 isync
172 blr
173
174/* 750cx specific
175 * Looks like we have to disable NAP feature for some PLL settings...
176 * (waiting for confirmation)
177 */
178setup_750cx:
179 mfspr r10, SPRN_HID1
180 rlwinm r10,r10,4,28,31
181 cmpwi cr0,r10,7
182 cmpwi cr1,r10,9
183 cmpwi cr2,r10,11
184 cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
185 cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
186 bnelr
187 lwz r6,CPU_SPEC_FEATURES(r5)
188 li r7,CPU_FTR_CAN_NAP
189 andc r6,r6,r7
190 stw r6,CPU_SPEC_FEATURES(r5)
191 blr
192
193/* 750fx specific
194 */
195setup_750fx:
196 blr
197
198/* MPC 745x
199 * Enable Store Gathering (SGE), Branch Folding (FOLD)
200 * Branch History Table (BHTE), Branch Target ICache (BTIC)
201 * Dynamic Power Management (DPM), Speculative (SPD)
202 * Ensure our data cache instructions really operate.
203 * Timebase has to be running or we wouldn't have made it here,
204 * just ensure we don't disable it.
205 * Clear Instruction cache throttling (ICTC)
206 * Enable L2 HW prefetch
207 */
208setup_745x_specifics:
209 /* We check for the presence of an L3 cache setup by
210 * the firmware. If any, we disable NAP capability as
211 * it's known to be bogus on rev 2.1 and earlier
212 */
213 mfspr r11,SPRN_L3CR
214 andis. r11,r11,L3CR_L3E@h
215 beq 1f
216 lwz r6,CPU_SPEC_FEATURES(r5)
217 andi. r0,r6,CPU_FTR_L3_DISABLE_NAP
218 beq 1f
219 li r7,CPU_FTR_CAN_NAP
220 andc r6,r6,r7
221 stw r6,CPU_SPEC_FEATURES(r5)
2221:
223 mfspr r11,SPRN_HID0
224
225 /* All of the bits we have to set.....
226 */
227 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
228 ori r11,r11,HID0_LRSTK | HID0_BTIC
229 oris r11,r11,HID0_DPM@h
230BEGIN_FTR_SECTION
231 xori r11,r11,HID0_BTIC
232END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
233BEGIN_FTR_SECTION
234 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
235END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
236
237 /* All of the bits we have to clear....
238 */
239 li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI
240 andc r11,r11,r3 /* clear SPD: enable speculative */
241 li r3,0
242
243 mtspr SPRN_ICTC,r3 /* Instruction Cache Throttling off */
244 isync
245 mtspr SPRN_HID0,r11
246 sync
247 isync
248
249 /* Enable L2 HW prefetch, if L2 is enabled
250 */
251 mfspr r3,SPRN_L2CR
252 andis. r3,r3,L2CR_L2E@h
253 beqlr
254 mfspr r3,SPRN_MSSCR0
255 ori r3,r3,3
256 sync
257 mtspr SPRN_MSSCR0,r3
258 sync
259 isync
260 blr
261
262/*
263 * Initialize the FPU registers. This is needed to work around an errata
264 * in some 750 cpus where using a not yet initialized FPU register after
265 * power on reset may hang the CPU
266 */
267_GLOBAL(__init_fpu_registers)
268 mfmsr r10
269 ori r11,r10,MSR_FP
270 mtmsr r11
271 isync
272 addis r9,r3,empty_zero_page@ha
273 addi r9,r9,empty_zero_page@l
274 REST_32FPRS(0,r9)
275 sync
276 mtmsr r10
277 isync
278 blr
279
280
281/* Definitions for the table use to save CPU states */
282#define CS_HID0 0
283#define CS_HID1 4
284#define CS_HID2 8
285#define CS_MSSCR0 12
286#define CS_MSSSR0 16
287#define CS_ICTRL 20
288#define CS_LDSTCR 24
289#define CS_LDSTDB 28
290#define CS_SIZE 32
291
292 .data
293 .balign L1_CACHE_BYTES
294cpu_state_storage:
295 .space CS_SIZE
296 .balign L1_CACHE_BYTES,0
297 .text
298
299/* Called in normal context to backup CPU 0 state. This
300 * does not include cache settings. This function is also
301 * called for machine sleep. This does not include the MMU
302 * setup, BATs, etc... but rather the "special" registers
303 * like HID0, HID1, MSSCR0, etc...
304 */
305_GLOBAL(__save_cpu_setup)
306 /* Some CR fields are volatile, we back it up all */
307 mfcr r7
308
309 /* Get storage ptr */
310 lis r5,cpu_state_storage@h
311 ori r5,r5,cpu_state_storage@l
312
313 /* Save HID0 (common to all CONFIG_6xx cpus) */
314 mfspr r3,SPRN_HID0
315 stw r3,CS_HID0(r5)
316
317 /* Now deal with CPU type dependent registers */
318 mfspr r3,SPRN_PVR
319 srwi r3,r3,16
320 cmplwi cr0,r3,0x8000 /* 7450 */
321 cmplwi cr1,r3,0x000c /* 7400 */
322 cmplwi cr2,r3,0x800c /* 7410 */
323 cmplwi cr3,r3,0x8001 /* 7455 */
324 cmplwi cr4,r3,0x8002 /* 7457 */
325 cmplwi cr5,r3,0x8003 /* 7447A */
326 cmplwi cr6,r3,0x7000 /* 750FX */
327 cmplwi cr7,r3,0x8004 /* 7448 */
328 /* cr1 is 7400 || 7410 */
329 cror 4*cr1+eq,4*cr1+eq,4*cr2+eq
330 /* cr0 is 74xx */
331 cror 4*cr0+eq,4*cr0+eq,4*cr3+eq
332 cror 4*cr0+eq,4*cr0+eq,4*cr4+eq
333 cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
334 cror 4*cr0+eq,4*cr0+eq,4*cr5+eq
335 cror 4*cr0+eq,4*cr0+eq,4*cr7+eq
336 bne 1f
337 /* Backup 74xx specific regs */
338 mfspr r4,SPRN_MSSCR0
339 stw r4,CS_MSSCR0(r5)
340 mfspr r4,SPRN_MSSSR0
341 stw r4,CS_MSSSR0(r5)
342 beq cr1,1f
343 /* Backup 745x specific registers */
344 mfspr r4,SPRN_HID1
345 stw r4,CS_HID1(r5)
346 mfspr r4,SPRN_ICTRL
347 stw r4,CS_ICTRL(r5)
348 mfspr r4,SPRN_LDSTCR
349 stw r4,CS_LDSTCR(r5)
350 mfspr r4,SPRN_LDSTDB
351 stw r4,CS_LDSTDB(r5)
3521:
353 bne cr6,1f
354 /* Backup 750FX specific registers */
355 mfspr r4,SPRN_HID1
356 stw r4,CS_HID1(r5)
357 /* If rev 2.x, backup HID2 */
358 mfspr r3,SPRN_PVR
359 andi. r3,r3,0xff00
360 cmpwi cr0,r3,0x0200
361 bne 1f
362 mfspr r4,SPRN_HID2
363 stw r4,CS_HID2(r5)
3641:
365 mtcr r7
366 blr
367
368/* Called with no MMU context (typically MSR:IR/DR off) to
369 * restore CPU state as backed up by the previous
370 * function. This does not include cache setting
371 */
372_GLOBAL(__restore_cpu_setup)
373 /* Some CR fields are volatile, we back it up all */
374 mfcr r7
375
376 /* Get storage ptr */
377 lis r5,(cpu_state_storage-KERNELBASE)@h
378 ori r5,r5,cpu_state_storage@l
379
380 /* Restore HID0 */
381 lwz r3,CS_HID0(r5)
382 sync
383 isync
384 mtspr SPRN_HID0,r3
385 sync
386 isync
387
388 /* Now deal with CPU type dependent registers */
389 mfspr r3,SPRN_PVR
390 srwi r3,r3,16
391 cmplwi cr0,r3,0x8000 /* 7450 */
392 cmplwi cr1,r3,0x000c /* 7400 */
393 cmplwi cr2,r3,0x800c /* 7410 */
394 cmplwi cr3,r3,0x8001 /* 7455 */
395 cmplwi cr4,r3,0x8002 /* 7457 */
396 cmplwi cr5,r3,0x8003 /* 7447A */
397 cmplwi cr6,r3,0x7000 /* 750FX */
398 cmplwi cr7,r3,0x8004 /* 7448 */
399 /* cr1 is 7400 || 7410 */
400 cror 4*cr1+eq,4*cr1+eq,4*cr2+eq
401 /* cr0 is 74xx */
402 cror 4*cr0+eq,4*cr0+eq,4*cr3+eq
403 cror 4*cr0+eq,4*cr0+eq,4*cr4+eq
404 cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
405 cror 4*cr0+eq,4*cr0+eq,4*cr5+eq
406 cror 4*cr0+eq,4*cr0+eq,4*cr7+eq
407 bne 2f
408 /* Restore 74xx specific regs */
409 lwz r4,CS_MSSCR0(r5)
410 sync
411 mtspr SPRN_MSSCR0,r4
412 sync
413 isync
414 lwz r4,CS_MSSSR0(r5)
415 sync
416 mtspr SPRN_MSSSR0,r4
417 sync
418 isync
419 bne cr2,1f
420 /* Clear 7410 L2CR2 */
421 li r4,0
422 mtspr SPRN_L2CR2,r4
4231: beq cr1,2f
424 /* Restore 745x specific registers */
425 lwz r4,CS_HID1(r5)
426 sync
427 mtspr SPRN_HID1,r4
428 isync
429 sync
430 lwz r4,CS_ICTRL(r5)
431 sync
432 mtspr SPRN_ICTRL,r4
433 isync
434 sync
435 lwz r4,CS_LDSTCR(r5)
436 sync
437 mtspr SPRN_LDSTCR,r4
438 isync
439 sync
440 lwz r4,CS_LDSTDB(r5)
441 sync
442 mtspr SPRN_LDSTDB,r4
443 isync
444 sync
4452: bne cr6,1f
446 /* Restore 750FX specific registers
447 * that is restore HID2 on rev 2.x and PLL config & switch
448 * to PLL 0 on all
449 */
450 /* If rev 2.x, restore HID2 with low voltage bit cleared */
451 mfspr r3,SPRN_PVR
452 andi. r3,r3,0xff00
453 cmpwi cr0,r3,0x0200
454 bne 4f
455 lwz r4,CS_HID2(r5)
456 rlwinm r4,r4,0,19,17
457 mtspr SPRN_HID2,r4
458 sync
4594:
460 lwz r4,CS_HID1(r5)
461 rlwinm r5,r4,0,16,14
462 mtspr SPRN_HID1,r5
463 /* Wait for PLL to stabilize */
464 mftbl r5
4653: mftbl r6
466 sub r6,r6,r5
467 cmplwi cr0,r6,10000
468 ble 3b
469 /* Setup final PLL */
470 mtspr SPRN_HID1,r4
4711:
472 mtcr r7
473 blr
474
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index e4e81374cb9a..39e348a3ade2 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -894,7 +894,7 @@ struct cpu_spec cpu_specs[] = {
894 .platform = "ppc405", 894 .platform = "ppc405",
895 }, 895 },
896 { /* Xilinx Virtex-II Pro */ 896 { /* Xilinx Virtex-II Pro */
897 .pvr_mask = 0xffff0000, 897 .pvr_mask = 0xfffff000,
898 .pvr_value = 0x20010000, 898 .pvr_value = 0x20010000,
899 .cpu_name = "Virtex-II Pro", 899 .cpu_name = "Virtex-II Pro",
900 .cpu_features = CPU_FTRS_40X, 900 .cpu_features = CPU_FTRS_40X,
@@ -904,6 +904,16 @@ struct cpu_spec cpu_specs[] = {
904 .dcache_bsize = 32, 904 .dcache_bsize = 32,
905 .platform = "ppc405", 905 .platform = "ppc405",
906 }, 906 },
907 { /* Xilinx Virtex-4 FX */
908 .pvr_mask = 0xfffff000,
909 .pvr_value = 0x20011000,
910 .cpu_name = "Virtex-4 FX",
911 .cpu_features = CPU_FTRS_40X,
912 .cpu_user_features = PPC_FEATURE_32 |
913 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
914 .icache_bsize = 32,
915 .dcache_bsize = 32,
916 },
907 { /* 405EP */ 917 { /* 405EP */
908 .pvr_mask = 0xffff0000, 918 .pvr_mask = 0xffff0000,
909 .pvr_value = 0x51210000, 919 .pvr_value = 0x51210000,
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 211d72653ea6..764d07329716 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -61,7 +61,7 @@ static int __init parse_elfcorehdr(char *p)
61 if (p) 61 if (p)
62 elfcorehdr_addr = memparse(p, &p); 62 elfcorehdr_addr = memparse(p, &p);
63 63
64 return 0; 64 return 1;
65} 65}
66__setup("elfcorehdr=", parse_elfcorehdr); 66__setup("elfcorehdr=", parse_elfcorehdr);
67#endif 67#endif
@@ -71,7 +71,7 @@ static int __init parse_savemaxmem(char *p)
71 if (p) 71 if (p)
72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; 72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
73 73
74 return 0; 74 return 1;
75} 75}
76__setup("savemaxmem=", parse_savemaxmem); 76__setup("savemaxmem=", parse_savemaxmem);
77 77
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4827ca1ec89b..b3a979467225 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -135,10 +135,10 @@ transfer_to_handler:
135 mfspr r11,SPRN_HID0 135 mfspr r11,SPRN_HID0
136 mtcr r11 136 mtcr r11
137BEGIN_FTR_SECTION 137BEGIN_FTR_SECTION
138 bt- 8,power_save_6xx_restore /* Check DOZE */ 138 bt- 8,4f /* Check DOZE */
139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) 139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
140BEGIN_FTR_SECTION 140BEGIN_FTR_SECTION
141 bt- 9,power_save_6xx_restore /* Check NAP */ 141 bt- 9,4f /* Check NAP */
142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) 142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
143#endif /* CONFIG_6xx */ 143#endif /* CONFIG_6xx */
144 .globl transfer_to_handler_cont 144 .globl transfer_to_handler_cont
@@ -157,6 +157,10 @@ transfer_to_handler_cont:
157 SYNC 157 SYNC
158 RFI /* jump to handler, enable MMU */ 158 RFI /* jump to handler, enable MMU */
159 159
160#ifdef CONFIG_6xx
1614: b power_save_6xx_restore
162#endif
163
160/* 164/*
161 * On kernel stack overflow, load up an initial stack pointer 165 * On kernel stack overflow, load up an initial stack pointer
162 * and call StackOverflow(regs), which should not return. 166 * and call StackOverflow(regs), which should not return.
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 24be0cf86d7f..19ad5c6b1818 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/entry.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 4 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -63,6 +61,7 @@ system_call_common:
63 std r12,_MSR(r1) 61 std r12,_MSR(r1)
64 std r0,GPR0(r1) 62 std r0,GPR0(r1)
65 std r10,GPR1(r1) 63 std r10,GPR1(r1)
64 ACCOUNT_CPU_USER_ENTRY(r10, r11)
66 std r2,GPR2(r1) 65 std r2,GPR2(r1)
67 std r3,GPR3(r1) 66 std r3,GPR3(r1)
68 std r4,GPR4(r1) 67 std r4,GPR4(r1)
@@ -170,8 +169,9 @@ syscall_error_cont:
170 stdcx. r0,0,r1 /* to clear the reservation */ 169 stdcx. r0,0,r1 /* to clear the reservation */
171 andi. r6,r8,MSR_PR 170 andi. r6,r8,MSR_PR
172 ld r4,_LINK(r1) 171 ld r4,_LINK(r1)
173 beq- 1f /* only restore r13 if */ 172 beq- 1f
174 ld r13,GPR13(r1) /* returning to usermode */ 173 ACCOUNT_CPU_USER_EXIT(r11, r12)
174 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1751: ld r2,GPR2(r1) 1751: ld r2,GPR2(r1)
176 li r12,MSR_RI 176 li r12,MSR_RI
177 andc r11,r10,r12 177 andc r11,r10,r12
@@ -322,7 +322,7 @@ _GLOBAL(ret_from_fork)
322 * the fork code also. 322 * the fork code also.
323 * 323 *
324 * The code which creates the new task context is in 'copy_thread' 324 * The code which creates the new task context is in 'copy_thread'
325 * in arch/ppc64/kernel/process.c 325 * in arch/powerpc/kernel/process.c
326 */ 326 */
327 .align 7 327 .align 7
328_GLOBAL(_switch) 328_GLOBAL(_switch)
@@ -486,6 +486,7 @@ restore:
486 * userspace 486 * userspace
487 */ 487 */
488 beq 1f 488 beq 1f
489 ACCOUNT_CPU_USER_EXIT(r3, r4)
489 REST_GPR(13, r1) 490 REST_GPR(13, r1)
4901: 4911:
491 ld r3,_CTR(r1) 492 ld r3,_CTR(r1)
@@ -616,6 +617,12 @@ _GLOBAL(enter_rtas)
616 mfsrr1 r10 617 mfsrr1 r10
617 std r10,_SRR1(r1) 618 std r10,_SRR1(r1)
618 619
620 /* Temporary workaround to clear CR until RTAS can be modified to
621 * ignore all bits.
622 */
623 li r0,0
624 mtcr r0
625
619 /* There is no way it is acceptable to get here with interrupts enabled, 626 /* There is no way it is acceptable to get here with interrupts enabled,
620 * check it with the asm equivalent of WARN_ON 627 * check it with the asm equivalent of WARN_ON
621 */ 628 */
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index 65eae752a527..0bfe9061720a 100644
--- a/arch/powerpc/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -14,32 +14,9 @@
14 */ 14 */
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/module.h>
17 18
18#include <asm/firmware.h> 19#include <asm/firmware.h>
19 20
20unsigned long ppc64_firmware_features; 21unsigned long powerpc_firmware_features;
21 22EXPORT_SYMBOL_GPL(powerpc_firmware_features);
22#ifdef CONFIG_PPC_PSERIES
23firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
24 {FW_FEATURE_PFT, "hcall-pft"},
25 {FW_FEATURE_TCE, "hcall-tce"},
26 {FW_FEATURE_SPRG0, "hcall-sprg0"},
27 {FW_FEATURE_DABR, "hcall-dabr"},
28 {FW_FEATURE_COPY, "hcall-copy"},
29 {FW_FEATURE_ASR, "hcall-asr"},
30 {FW_FEATURE_DEBUG, "hcall-debug"},
31 {FW_FEATURE_PERF, "hcall-perf"},
32 {FW_FEATURE_DUMP, "hcall-dump"},
33 {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
34 {FW_FEATURE_MIGRATE, "hcall-migrate"},
35 {FW_FEATURE_PERFMON, "hcall-perfmon"},
36 {FW_FEATURE_CRQ, "hcall-crq"},
37 {FW_FEATURE_VIO, "hcall-vio"},
38 {FW_FEATURE_RDMA, "hcall-rdma"},
39 {FW_FEATURE_LLAN, "hcall-lLAN"},
40 {FW_FEATURE_BULK, "hcall-bulk"},
41 {FW_FEATURE_XDABR, "hcall-xdabr"},
42 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
43 {FW_FEATURE_SPLPAR, "hcall-splpar"},
44};
45#endif
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 8b49679fad54..47c7fa148c9a 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/head_44x.S
3 *
4 * Kernel execution entry point code. 2 * Kernel execution entry point code.
5 * 3 *
6 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 4 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 9b65029dd2a3..a5ae04a57c78 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/head.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -279,6 +277,7 @@ exception_marker:
279 std r10,0(r1); /* make stack chain pointer */ \ 277 std r10,0(r1); /* make stack chain pointer */ \
280 std r0,GPR0(r1); /* save r0 in stackframe */ \ 278 std r0,GPR0(r1); /* save r0 in stackframe */ \
281 std r10,GPR1(r1); /* save r1 in stackframe */ \ 279 std r10,GPR1(r1); /* save r1 in stackframe */ \
280 ACCOUNT_CPU_USER_ENTRY(r9, r10); \
282 std r2,GPR2(r1); /* save r2 in stackframe */ \ 281 std r2,GPR2(r1); /* save r2 in stackframe */ \
283 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ 282 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
284 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ 283 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
@@ -846,6 +845,14 @@ fast_exception_return:
846 ld r11,_NIP(r1) 845 ld r11,_NIP(r1)
847 andi. r3,r12,MSR_RI /* check if RI is set */ 846 andi. r3,r12,MSR_RI /* check if RI is set */
848 beq- unrecov_fer 847 beq- unrecov_fer
848
849#ifdef CONFIG_VIRT_CPU_ACCOUNTING
850 andi. r3,r12,MSR_PR
851 beq 2f
852 ACCOUNT_CPU_USER_EXIT(r3, r4)
8532:
854#endif
855
849 ld r3,_CCR(r1) 856 ld r3,_CCR(r1)
850 ld r4,_LINK(r1) 857 ld r4,_LINK(r1)
851 ld r5,_CTR(r1) 858 ld r5,_CTR(r1)
@@ -1537,7 +1544,11 @@ _STATIC(__boot_from_prom)
1537 mr r28,r6 1544 mr r28,r6
1538 mr r27,r7 1545 mr r27,r7
1539 1546
1540 /* Align the stack to 16-byte boundary for broken yaboot */ 1547 /*
1548 * Align the stack to 16-byte boundary
1549 * Depending on the size and layout of the ELF sections in the initial
1550 * boot binary, the stack pointer will be unalignet on PowerMac
1551 */
1541 rldicr r1,r1,0,59 1552 rldicr r1,r1,0,59
1542 1553
1543 /* Make sure we are running in 64 bits mode */ 1554 /* Make sure we are running in 64 bits mode */
@@ -1840,21 +1851,6 @@ _STATIC(start_here_multiplatform)
1840 bl .__save_cpu_setup 1851 bl .__save_cpu_setup
1841 sync 1852 sync
1842 1853
1843 /* Setup a valid physical PACA pointer in SPRG3 for early_setup
1844 * note that boot_cpuid can always be 0 nowadays since there is
1845 * nowhere it can be initialized differently before we reach this
1846 * code
1847 */
1848 LOAD_REG_IMMEDIATE(r27, boot_cpuid)
1849 add r27,r27,r26
1850 lwz r27,0(r27)
1851
1852 LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */
1853 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1854 add r13,r13,r24 /* for this processor. */
1855 add r13,r13,r26 /* convert to physical addr */
1856 mtspr SPRN_SPRG3,r13
1857
1858 /* Do very early kernel initializations, including initial hash table, 1854 /* Do very early kernel initializations, including initial hash table,
1859 * stab and slb setup before we turn on relocation. */ 1855 * stab and slb setup before we turn on relocation. */
1860 1856
@@ -1923,6 +1919,17 @@ _STATIC(start_here_common)
1923 /* Not reached */ 1919 /* Not reached */
1924 BUG_OPCODE 1920 BUG_OPCODE
1925 1921
1922/* Put the paca pointer into r13 and SPRG3 */
1923_GLOBAL(setup_boot_paca)
1924 LOAD_REG_IMMEDIATE(r3, boot_cpuid)
1925 lwz r3,0(r3)
1926 LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */
1927 mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */
1928 add r13,r3,r4 /* for this processor. */
1929 mtspr SPRN_SPRG3,r13
1930
1931 blr
1932
1926/* 1933/*
1927 * We put a few things here that have to be page-aligned. 1934 * We put a few things here that have to be page-aligned.
1928 * This stuff goes at the beginning of the bss, which is page-aligned. 1935 * This stuff goes at the beginning of the bss, which is page-aligned.
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index bc6d1ac55235..28941f5ce673 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/except_8xx.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 4 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
new file mode 100644
index 000000000000..8536e7676160
--- /dev/null
+++ b/arch/powerpc/kernel/head_booke.h
@@ -0,0 +1,363 @@
1#ifndef __HEAD_BOOKE_H__
2#define __HEAD_BOOKE_H__
3
4/*
5 * Macros used for common Book-e exception handling
6 */
7
8#define SET_IVOR(vector_number, vector_label) \
9 li r26,vector_label@l; \
10 mtspr SPRN_IVOR##vector_number,r26; \
11 sync
12
13#define NORMAL_EXCEPTION_PROLOG \
14 mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
15 mtspr SPRN_SPRG1,r11; \
16 mtspr SPRN_SPRG4W,r1; \
17 mfcr r10; /* save CR in r10 for now */\
18 mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
19 andi. r11,r11,MSR_PR; \
20 beq 1f; \
21 mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
22 lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
23 addi r1,r1,THREAD_SIZE; \
241: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
25 mr r11,r1; \
26 stw r10,_CCR(r11); /* save various registers */\
27 stw r12,GPR12(r11); \
28 stw r9,GPR9(r11); \
29 mfspr r10,SPRN_SPRG0; \
30 stw r10,GPR10(r11); \
31 mfspr r12,SPRN_SPRG1; \
32 stw r12,GPR11(r11); \
33 mflr r10; \
34 stw r10,_LINK(r11); \
35 mfspr r10,SPRN_SPRG4R; \
36 mfspr r12,SPRN_SRR0; \
37 stw r10,GPR1(r11); \
38 mfspr r9,SPRN_SRR1; \
39 stw r10,0(r11); \
40 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
41 stw r0,GPR0(r11); \
42 SAVE_4GPRS(3, r11); \
43 SAVE_2GPRS(7, r11)
44
45/* To handle the additional exception priority levels on 40x and Book-E
46 * processors we allocate a 4k stack per additional priority level. The various
47 * head_xxx.S files allocate space (exception_stack_top) for each priority's
48 * stack times the number of CPUs
49 *
50 * On 40x critical is the only additional level
51 * On 44x/e500 we have critical and machine check
52 * On e200 we have critical and debug (machine check occurs via critical)
53 *
54 * Additionally we reserve a SPRG for each priority level so we can free up a
55 * GPR to use as the base for indirect access to the exception stacks. This
56 * is necessary since the MMU is always on, for Book-E parts, and the stacks
57 * are offset from KERNELBASE.
58 *
59 */
60#define BOOKE_EXCEPTION_STACK_SIZE (8192)
61
62/* CRIT_SPRG only used in critical exception handling */
63#define CRIT_SPRG SPRN_SPRG2
64/* MCHECK_SPRG only used in machine check exception handling */
65#define MCHECK_SPRG SPRN_SPRG6W
66
67#define MCHECK_STACK_TOP (exception_stack_top - 4096)
68#define CRIT_STACK_TOP (exception_stack_top)
69
70/* only on e200 for now */
71#define DEBUG_STACK_TOP (exception_stack_top - 4096)
72#define DEBUG_SPRG SPRN_SPRG6W
73
74#ifdef CONFIG_SMP
75#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
76 mfspr r8,SPRN_PIR; \
77 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
78 neg r8,r8; \
79 addis r8,r8,level##_STACK_TOP@ha; \
80 addi r8,r8,level##_STACK_TOP@l
81#else
82#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
83 lis r8,level##_STACK_TOP@h; \
84 ori r8,r8,level##_STACK_TOP@l
85#endif
86
87/*
88 * Exception prolog for critical/machine check exceptions. This is a
89 * little different from the normal exception prolog above since a
90 * critical/machine check exception can potentially occur at any point
91 * during normal exception processing. Thus we cannot use the same SPRG
92 * registers as the normal prolog above. Instead we use a portion of the
93 * critical/machine check exception stack at low physical addresses.
94 */
95#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
96 mtspr exc_level##_SPRG,r8; \
97 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
98 stw r10,GPR10-INT_FRAME_SIZE(r8); \
99 stw r11,GPR11-INT_FRAME_SIZE(r8); \
100 mfcr r10; /* save CR in r10 for now */\
101 mfspr r11,exc_level_srr1; /* check whether user or kernel */\
102 andi. r11,r11,MSR_PR; \
103 mr r11,r8; \
104 mfspr r8,exc_level##_SPRG; \
105 beq 1f; \
106 /* COMING FROM USER MODE */ \
107 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
108 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
109 addi r11,r11,THREAD_SIZE; \
1101: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
111 stw r10,_CCR(r11); /* save various registers */\
112 stw r12,GPR12(r11); \
113 stw r9,GPR9(r11); \
114 mflr r10; \
115 stw r10,_LINK(r11); \
116 mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
117 stw r12,_DEAR(r11); /* since they may have had stuff */\
118 mfspr r9,SPRN_ESR; /* in them at the point where the */\
119 stw r9,_ESR(r11); /* exception was taken */\
120 mfspr r12,exc_level_srr0; \
121 stw r1,GPR1(r11); \
122 mfspr r9,exc_level_srr1; \
123 stw r1,0(r11); \
124 mr r1,r11; \
125 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
126 stw r0,GPR0(r11); \
127 SAVE_4GPRS(3, r11); \
128 SAVE_2GPRS(7, r11)
129
130#define CRITICAL_EXCEPTION_PROLOG \
131 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
132#define DEBUG_EXCEPTION_PROLOG \
133 EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
134#define MCHECK_EXCEPTION_PROLOG \
135 EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
136
137/*
138 * Exception vectors.
139 */
140#define START_EXCEPTION(label) \
141 .align 5; \
142label:
143
144#define FINISH_EXCEPTION(func) \
145 bl transfer_to_handler_full; \
146 .long func; \
147 .long ret_from_except_full
148
149#define EXCEPTION(n, label, hdlr, xfer) \
150 START_EXCEPTION(label); \
151 NORMAL_EXCEPTION_PROLOG; \
152 addi r3,r1,STACK_FRAME_OVERHEAD; \
153 xfer(n, hdlr)
154
155#define CRITICAL_EXCEPTION(n, label, hdlr) \
156 START_EXCEPTION(label); \
157 CRITICAL_EXCEPTION_PROLOG; \
158 addi r3,r1,STACK_FRAME_OVERHEAD; \
159 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
160 NOCOPY, crit_transfer_to_handler, \
161 ret_from_crit_exc)
162
163#define MCHECK_EXCEPTION(n, label, hdlr) \
164 START_EXCEPTION(label); \
165 MCHECK_EXCEPTION_PROLOG; \
166 mfspr r5,SPRN_ESR; \
167 stw r5,_ESR(r11); \
168 addi r3,r1,STACK_FRAME_OVERHEAD; \
169 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
170 NOCOPY, mcheck_transfer_to_handler, \
171 ret_from_mcheck_exc)
172
173#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
174 li r10,trap; \
175 stw r10,_TRAP(r11); \
176 lis r10,msr@h; \
177 ori r10,r10,msr@l; \
178 copyee(r10, r9); \
179 bl tfer; \
180 .long hdlr; \
181 .long ret
182
183#define COPY_EE(d, s) rlwimi d,s,0,16,16
184#define NOCOPY(d, s)
185
186#define EXC_XFER_STD(n, hdlr) \
187 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
188 ret_from_except_full)
189
190#define EXC_XFER_LITE(n, hdlr) \
191 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
192 ret_from_except)
193
194#define EXC_XFER_EE(n, hdlr) \
195 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
196 ret_from_except_full)
197
198#define EXC_XFER_EE_LITE(n, hdlr) \
199 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
200 ret_from_except)
201
202/* Check for a single step debug exception while in an exception
203 * handler before state has been saved. This is to catch the case
204 * where an instruction that we are trying to single step causes
205 * an exception (eg ITLB/DTLB miss) and thus the first instruction of
206 * the exception handler generates a single step debug exception.
207 *
208 * If we get a debug trap on the first instruction of an exception handler,
209 * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
210 * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
211 * The exception handler was handling a non-critical interrupt, so it will
212 * save (and later restore) the MSR via SPRN_CSRR1, which will still have
213 * the MSR_DE bit set.
214 */
215#ifdef CONFIG_E200
216#define DEBUG_EXCEPTION \
217 START_EXCEPTION(Debug); \
218 DEBUG_EXCEPTION_PROLOG; \
219 \
220 /* \
221 * If there is a single step or branch-taken exception in an \
222 * exception entry sequence, it was probably meant to apply to \
223 * the code where the exception occurred (since exception entry \
224 * doesn't turn off DE automatically). We simulate the effect \
225 * of turning off DE on entry to an exception handler by turning \
226 * off DE in the CSRR1 value and clearing the debug status. \
227 */ \
228 mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
229 andis. r10,r10,DBSR_IC@h; \
230 beq+ 2f; \
231 \
232 lis r10,KERNELBASE@h; /* check if exception in vectors */ \
233 ori r10,r10,KERNELBASE@l; \
234 cmplw r12,r10; \
235 blt+ 2f; /* addr below exception vectors */ \
236 \
237 lis r10,Debug@h; \
238 ori r10,r10,Debug@l; \
239 cmplw r12,r10; \
240 bgt+ 2f; /* addr above exception vectors */ \
241 \
242 /* here it looks like we got an inappropriate debug exception. */ \
2431: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CDRR1 value */ \
244 lis r10,DBSR_IC@h; /* clear the IC event */ \
245 mtspr SPRN_DBSR,r10; \
246 /* restore state and get out */ \
247 lwz r10,_CCR(r11); \
248 lwz r0,GPR0(r11); \
249 lwz r1,GPR1(r11); \
250 mtcrf 0x80,r10; \
251 mtspr SPRN_DSRR0,r12; \
252 mtspr SPRN_DSRR1,r9; \
253 lwz r9,GPR9(r11); \
254 lwz r12,GPR12(r11); \
255 mtspr DEBUG_SPRG,r8; \
256 BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
257 lwz r10,GPR10-INT_FRAME_SIZE(r8); \
258 lwz r11,GPR11-INT_FRAME_SIZE(r8); \
259 mfspr r8,DEBUG_SPRG; \
260 \
261 RFDI; \
262 b .; \
263 \
264 /* continue normal handling for a critical exception... */ \
2652: mfspr r4,SPRN_DBSR; \
266 addi r3,r1,STACK_FRAME_OVERHEAD; \
267 EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
268#else
269#define DEBUG_EXCEPTION \
270 START_EXCEPTION(Debug); \
271 CRITICAL_EXCEPTION_PROLOG; \
272 \
273 /* \
274 * If there is a single step or branch-taken exception in an \
275 * exception entry sequence, it was probably meant to apply to \
276 * the code where the exception occurred (since exception entry \
277 * doesn't turn off DE automatically). We simulate the effect \
278 * of turning off DE on entry to an exception handler by turning \
279 * off DE in the CSRR1 value and clearing the debug status. \
280 */ \
281 mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
282 andis. r10,r10,DBSR_IC@h; \
283 beq+ 2f; \
284 \
285 lis r10,KERNELBASE@h; /* check if exception in vectors */ \
286 ori r10,r10,KERNELBASE@l; \
287 cmplw r12,r10; \
288 blt+ 2f; /* addr below exception vectors */ \
289 \
290 lis r10,Debug@h; \
291 ori r10,r10,Debug@l; \
292 cmplw r12,r10; \
293 bgt+ 2f; /* addr above exception vectors */ \
294 \
295 /* here it looks like we got an inappropriate debug exception. */ \
2961: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CSRR1 value */ \
297 lis r10,DBSR_IC@h; /* clear the IC event */ \
298 mtspr SPRN_DBSR,r10; \
299 /* restore state and get out */ \
300 lwz r10,_CCR(r11); \
301 lwz r0,GPR0(r11); \
302 lwz r1,GPR1(r11); \
303 mtcrf 0x80,r10; \
304 mtspr SPRN_CSRR0,r12; \
305 mtspr SPRN_CSRR1,r9; \
306 lwz r9,GPR9(r11); \
307 lwz r12,GPR12(r11); \
308 mtspr CRIT_SPRG,r8; \
309 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
310 lwz r10,GPR10-INT_FRAME_SIZE(r8); \
311 lwz r11,GPR11-INT_FRAME_SIZE(r8); \
312 mfspr r8,CRIT_SPRG; \
313 \
314 rfci; \
315 b .; \
316 \
317 /* continue normal handling for a critical exception... */ \
3182: mfspr r4,SPRN_DBSR; \
319 addi r3,r1,STACK_FRAME_OVERHEAD; \
320 EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
321#endif
322
323#define INSTRUCTION_STORAGE_EXCEPTION \
324 START_EXCEPTION(InstructionStorage) \
325 NORMAL_EXCEPTION_PROLOG; \
326 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
327 stw r5,_ESR(r11); \
328 mr r4,r12; /* Pass SRR0 as arg2 */ \
329 li r5,0; /* Pass zero as arg3 */ \
330 EXC_XFER_EE_LITE(0x0400, handle_page_fault)
331
332#define ALIGNMENT_EXCEPTION \
333 START_EXCEPTION(Alignment) \
334 NORMAL_EXCEPTION_PROLOG; \
335 mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
336 stw r4,_DEAR(r11); \
337 addi r3,r1,STACK_FRAME_OVERHEAD; \
338 EXC_XFER_EE(0x0600, alignment_exception)
339
340#define PROGRAM_EXCEPTION \
341 START_EXCEPTION(Program) \
342 NORMAL_EXCEPTION_PROLOG; \
343 mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
344 stw r4,_ESR(r11); \
345 addi r3,r1,STACK_FRAME_OVERHEAD; \
346 EXC_XFER_STD(0x0700, program_check_exception)
347
348#define DECREMENTER_EXCEPTION \
349 START_EXCEPTION(Decrementer) \
350 NORMAL_EXCEPTION_PROLOG; \
351 lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
352 mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
353 addi r3,r1,STACK_FRAME_OVERHEAD; \
354 EXC_XFER_LITE(0x0900, timer_interrupt)
355
356#define FP_UNAVAILABLE_EXCEPTION \
357 START_EXCEPTION(FloatingPointUnavailable) \
358 NORMAL_EXCEPTION_PROLOG; \
359 bne load_up_fpu; /* if from user, just load it up */ \
360 addi r3,r1,STACK_FRAME_OVERHEAD; \
361 EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
362
363#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..dd86bbed7627 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/head_fsl_booke.S
3 *
4 * Kernel execution entry point code. 2 * Kernel execution entry point code.
5 * 3 *
6 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 4 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
@@ -316,6 +314,7 @@ skpinv: addi r6,r6,1 /* Increment */
316 */ 314 */
317 lis r2,DBCR0_IDM@h 315 lis r2,DBCR0_IDM@h
318 mtspr SPRN_DBCR0,r2 316 mtspr SPRN_DBCR0,r2
317 isync
319 /* clear any residual debug events */ 318 /* clear any residual debug events */
320 li r2,-1 319 li r2,-1
321 mtspr SPRN_DBSR,r2 320 mtspr SPRN_DBSR,r2
@@ -1002,12 +1001,15 @@ _GLOBAL(giveup_fpu)
1002_GLOBAL(abort) 1001_GLOBAL(abort)
1003 li r13,0 1002 li r13,0
1004 mtspr SPRN_DBCR0,r13 /* disable all debug events */ 1003 mtspr SPRN_DBCR0,r13 /* disable all debug events */
1004 isync
1005 mfmsr r13 1005 mfmsr r13
1006 ori r13,r13,MSR_DE@l /* Enable Debug Events */ 1006 ori r13,r13,MSR_DE@l /* Enable Debug Events */
1007 mtmsr r13 1007 mtmsr r13
1008 isync
1008 mfspr r13,SPRN_DBCR0 1009 mfspr r13,SPRN_DBCR0
1009 lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h 1010 lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
1010 mtspr SPRN_DBCR0,r13 1011 mtspr SPRN_DBCR0,r13
1012 isync
1011 1013
1012_GLOBAL(set_context) 1014_GLOBAL(set_context)
1013 1015
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle.c
index b879d3057ef8..e9f321d74d85 100644
--- a/arch/powerpc/kernel/idle_64.c
+++ b/arch/powerpc/kernel/idle.c
@@ -2,13 +2,17 @@
2 * Idle daemon for PowerPC. Idle daemon will handle any action 2 * Idle daemon for PowerPC. Idle daemon will handle any action
3 * that needs to be taken when the system becomes idle. 3 * that needs to be taken when the system becomes idle.
4 * 4 *
5 * Originally Written by Cort Dougan (cort@cs.nmt.edu) 5 * Originally written by Cort Dougan (cort@cs.nmt.edu).
6 * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
7 * Paul Mackerras and others.
6 * 8 *
7 * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> 9 * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
8 * 10 *
9 * Additional shared processor, SMT, and firmware support 11 * Additional shared processor, SMT, and firmware support
10 * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> 12 * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
11 * 13 *
14 * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
15 *
12 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 17 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 18 * as published by the Free Software Foundation; either version
@@ -29,18 +33,43 @@
29#include <asm/machdep.h> 33#include <asm/machdep.h>
30#include <asm/smp.h> 34#include <asm/smp.h>
31 35
32extern void power4_idle(void); 36#ifdef CONFIG_HOTPLUG_CPU
37#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
38 system_state == SYSTEM_RUNNING)
39#else
40#define cpu_should_die() 0
41#endif
33 42
34void default_idle(void) 43/*
44 * The body of the idle task.
45 */
46void cpu_idle(void)
35{ 47{
36 unsigned int cpu = smp_processor_id(); 48 if (ppc_md.idle_loop)
37 set_thread_flag(TIF_POLLING_NRFLAG); 49 ppc_md.idle_loop(); /* doesn't return */
38 50
51 set_thread_flag(TIF_POLLING_NRFLAG);
39 while (1) { 52 while (1) {
40 if (!need_resched()) { 53 ppc64_runlatch_off();
41 while (!need_resched() && !cpu_is_offline(cpu)) {
42 ppc64_runlatch_off();
43 54
55 while (!need_resched() && !cpu_should_die()) {
56 if (ppc_md.power_save) {
57 clear_thread_flag(TIF_POLLING_NRFLAG);
58 /*
59 * smp_mb is so clearing of TIF_POLLING_NRFLAG
60 * is ordered w.r.t. need_resched() test.
61 */
62 smp_mb();
63 local_irq_disable();
64
65 /* check again after disabling irqs */
66 if (!need_resched() && !cpu_should_die())
67 ppc_md.power_save();
68
69 local_irq_enable();
70 set_thread_flag(TIF_POLLING_NRFLAG);
71
72 } else {
44 /* 73 /*
45 * Go into low thread priority and possibly 74 * Go into low thread priority and possibly
46 * low power mode. 75 * low power mode.
@@ -48,46 +77,18 @@ void default_idle(void)
48 HMT_low(); 77 HMT_low();
49 HMT_very_low(); 78 HMT_very_low();
50 } 79 }
51
52 HMT_medium();
53 } 80 }
54 81
82 HMT_medium();
55 ppc64_runlatch_on(); 83 ppc64_runlatch_on();
84 if (cpu_should_die())
85 cpu_die();
56 preempt_enable_no_resched(); 86 preempt_enable_no_resched();
57 schedule(); 87 schedule();
58 preempt_disable(); 88 preempt_disable();
59 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
60 cpu_die();
61 } 89 }
62} 90}
63 91
64void native_idle(void)
65{
66 while (1) {
67 ppc64_runlatch_off();
68
69 if (!need_resched())
70 power4_idle();
71
72 if (need_resched()) {
73 ppc64_runlatch_on();
74 preempt_enable_no_resched();
75 schedule();
76 preempt_disable();
77 }
78
79 if (cpu_is_offline(smp_processor_id()) &&
80 system_state == SYSTEM_RUNNING)
81 cpu_die();
82 }
83}
84
85void cpu_idle(void)
86{
87 BUG_ON(NULL == ppc_md.idle_loop);
88 ppc_md.idle_loop();
89}
90
91int powersave_nap; 92int powersave_nap;
92 93
93#ifdef CONFIG_SYSCTL 94#ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 444fdcc769f1..12a4efbaa08f 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -87,19 +87,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
87 cmpwi 0,r3,0 87 cmpwi 0,r3,0
88 beqlr 88 beqlr
89 89
90 /* Clear MSR:EE */
91 mfmsr r7
92 rlwinm r0,r7,0,17,15
93 mtmsr r0
94
95 /* Check current_thread_info()->flags */
96 rlwinm r4,r1,0,0,18
97 lwz r4,TI_FLAGS(r4)
98 andi. r0,r4,_TIF_NEED_RESCHED
99 beq 1f
100 mtmsr r7 /* out of line this ? */
101 blr
1021:
103 /* Some pre-nap cleanups needed on some CPUs */ 90 /* Some pre-nap cleanups needed on some CPUs */
104 andis. r0,r3,HID0_NAP@h 91 andis. r0,r3,HID0_NAP@h
105 beq 2f 92 beq 2f
@@ -157,7 +144,8 @@ BEGIN_FTR_SECTION
157 DSSALL 144 DSSALL
158 sync 145 sync
159END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 146END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
160 ori r7,r7,MSR_EE /* Could be ommited (already set) */ 147 mfmsr r7
148 ori r7,r7,MSR_EE
161 oris r7,r7,MSR_POW@h 149 oris r7,r7,MSR_POW@h
162 sync 150 sync
163 isync 151 isync
@@ -220,8 +208,6 @@ _GLOBAL(nap_save_msscr0)
220_GLOBAL(nap_save_hid1) 208_GLOBAL(nap_save_hid1)
221 .space 4*NR_CPUS 209 .space 4*NR_CPUS
222 210
223_GLOBAL(powersave_nap)
224 .long 0
225_GLOBAL(powersave_lowspeed) 211_GLOBAL(powersave_lowspeed)
226 .long 0 212 .long 0
227 213
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index c16b4afab582..6dad1c02496e 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -1,11 +1,5 @@
1/* 1/*
2 * This file contains the power_save function for 6xx & 7xxx CPUs 2 * This file contains the power_save function for 970-family CPUs.
3 * rewritten in assembler
4 *
5 * Warning ! This code assumes that if your machine has a 750fx
6 * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
7 * if this is not the case some additional changes will have to
8 * be done to check a runtime var (a bit like powersave-nap)
9 * 3 *
10 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -26,49 +20,23 @@
26 20
27 .text 21 .text
28 22
29/*
30 * Here is the power_save_6xx function. This could eventually be
31 * split into several functions & changing the function pointer
32 * depending on the various features.
33 */
34_GLOBAL(power4_idle) 23_GLOBAL(power4_idle)
35BEGIN_FTR_SECTION 24BEGIN_FTR_SECTION
36 blr 25 blr
37END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) 26END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
38 /* We must dynamically check for the NAP feature as it
39 * can be cleared by CPU init after the fixups are done
40 */
41 LOAD_REG_ADDRBASE(r3,cur_cpu_spec)
42 ld r4,ADDROFF(cur_cpu_spec)(r3)
43 ld r4,CPU_SPEC_FEATURES(r4)
44 andi. r0,r4,CPU_FTR_CAN_NAP
45 beqlr
46 /* Now check if user or arch enabled NAP mode */ 27 /* Now check if user or arch enabled NAP mode */
47 LOAD_REG_ADDRBASE(r3,powersave_nap) 28 LOAD_REG_ADDRBASE(r3,powersave_nap)
48 lwz r4,ADDROFF(powersave_nap)(r3) 29 lwz r4,ADDROFF(powersave_nap)(r3)
49 cmpwi 0,r4,0 30 cmpwi 0,r4,0
50 beqlr 31 beqlr
51 32
52 /* Clear MSR:EE */
53 mfmsr r7
54 li r4,0
55 ori r4,r4,MSR_EE
56 andc r0,r7,r4
57 mtmsrd r0
58
59 /* Check current_thread_info()->flags */
60 clrrdi r4,r1,THREAD_SHIFT
61 ld r4,TI_FLAGS(r4)
62 andi. r0,r4,_TIF_NEED_RESCHED
63 beq 1f
64 mtmsrd r7 /* out of line this ? */
65 blr
661:
67 /* Go to NAP now */ 33 /* Go to NAP now */
68BEGIN_FTR_SECTION 34BEGIN_FTR_SECTION
69 DSSALL 35 DSSALL
70 sync 36 sync
71END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
38 mfmsr r7
39 ori r7,r7,MSR_EE
72 oris r7,r7,MSR_POW@h 40 oris r7,r7,MSR_POW@h
73 sync 41 sync
74 isync 42 isync
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index 6160c8dbb7c5..fd8214caedee 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/iomap.c
3 *
4 * ppc64 "iomap" interface implementation. 2 * ppc64 "iomap" interface implementation.
5 * 3 *
6 * (C) Copyright 2004 Linus Torvalds 4 * (C) Copyright 2004 Linus Torvalds
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 946f3219fd29..d9a7fdef59b9 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/iommu.c
3 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
4 * 3 *
5 * Rewrite, cleanup, new allocation schemes, virtual merging: 4 * Rewrite, cleanup, new allocation schemes, virtual merging:
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index d1fffce86df9..bb5c9501234c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/irq.c
3 *
4 * Derived from arch/i386/kernel/irq.c 2 * Derived from arch/i386/kernel/irq.c
5 * Copyright (C) 1992 Linus Torvalds 3 * Copyright (C) 1992 Linus Torvalds
6 * Adapted from arch/i386 by Gary Thomas 4 * Adapted from arch/i386 by Gary Thomas
@@ -137,9 +135,8 @@ skip:
137#ifdef CONFIG_TAU_INT 135#ifdef CONFIG_TAU_INT
138 if (tau_initialized){ 136 if (tau_initialized){
139 seq_puts(p, "TAU: "); 137 seq_puts(p, "TAU: ");
140 for (j = 0; j < NR_CPUS; j++) 138 for_each_online_cpu(j)
141 if (cpu_online(j)) 139 seq_printf(p, "%10u ", tau_interrupts(j));
142 seq_printf(p, "%10u ", tau_interrupts(j));
143 seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); 140 seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
144 } 141 }
145#endif 142#endif
@@ -371,6 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
371 return NO_IRQ; 368 return NO_IRQ;
372 369
373} 370}
371#endif /* CONFIG_PPC64 */
374 372
375#ifdef CONFIG_IRQSTACKS 373#ifdef CONFIG_IRQSTACKS
376struct thread_info *softirq_ctx[NR_CPUS]; 374struct thread_info *softirq_ctx[NR_CPUS];
@@ -381,7 +379,7 @@ void irq_ctx_init(void)
381 struct thread_info *tp; 379 struct thread_info *tp;
382 int i; 380 int i;
383 381
384 for_each_cpu(i) { 382 for_each_possible_cpu(i) {
385 memset((void *)softirq_ctx[i], 0, THREAD_SIZE); 383 memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
386 tp = softirq_ctx[i]; 384 tp = softirq_ctx[i];
387 tp->cpu = i; 385 tp->cpu = i;
@@ -394,10 +392,24 @@ void irq_ctx_init(void)
394 } 392 }
395} 393}
396 394
395static inline void do_softirq_onstack(void)
396{
397 struct thread_info *curtp, *irqtp;
398
399 curtp = current_thread_info();
400 irqtp = softirq_ctx[smp_processor_id()];
401 irqtp->task = curtp->task;
402 call_do_softirq(irqtp);
403 irqtp->task = NULL;
404}
405
406#else
407#define do_softirq_onstack() __do_softirq()
408#endif /* CONFIG_IRQSTACKS */
409
397void do_softirq(void) 410void do_softirq(void)
398{ 411{
399 unsigned long flags; 412 unsigned long flags;
400 struct thread_info *curtp, *irqtp;
401 413
402 if (in_interrupt()) 414 if (in_interrupt())
403 return; 415 return;
@@ -405,19 +417,18 @@ void do_softirq(void)
405 local_irq_save(flags); 417 local_irq_save(flags);
406 418
407 if (local_softirq_pending()) { 419 if (local_softirq_pending()) {
408 curtp = current_thread_info(); 420 account_system_vtime(current);
409 irqtp = softirq_ctx[smp_processor_id()]; 421 local_bh_disable();
410 irqtp->task = curtp->task; 422 do_softirq_onstack();
411 call_do_softirq(irqtp); 423 account_system_vtime(current);
412 irqtp->task = NULL; 424 __local_bh_enable();
413 } 425 }
414 426
415 local_irq_restore(flags); 427 local_irq_restore(flags);
416} 428}
417EXPORT_SYMBOL(do_softirq); 429EXPORT_SYMBOL(do_softirq);
418 430
419#endif /* CONFIG_IRQSTACKS */ 431#ifdef CONFIG_PPC64
420
421static int __init setup_noirqdistrib(char *str) 432static int __init setup_noirqdistrib(char *str)
422{ 433{
423 distribute_irqs = 0; 434 distribute_irqs = 0;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cfab48566db1..ad7a90212204 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Kernel Probes (KProbes) 2 * Kernel Probes (KProbes)
3 * arch/ppc64/kernel/kprobes.c
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -31,9 +30,11 @@
31#include <linux/kprobes.h> 30#include <linux/kprobes.h>
32#include <linux/ptrace.h> 31#include <linux/ptrace.h>
33#include <linux/preempt.h> 32#include <linux/preempt.h>
33#include <linux/module.h>
34#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
35#include <asm/kdebug.h> 35#include <asm/kdebug.h>
36#include <asm/sstep.h> 36#include <asm/sstep.h>
37#include <asm/uaccess.h>
37 38
38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 39DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 40DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -82,9 +83,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
82 83
83void __kprobes arch_remove_kprobe(struct kprobe *p) 84void __kprobes arch_remove_kprobe(struct kprobe *p)
84{ 85{
85 down(&kprobe_mutex); 86 mutex_lock(&kprobe_mutex);
86 free_insn_slot(p->ainsn.insn); 87 free_insn_slot(p->ainsn.insn);
87 up(&kprobe_mutex); 88 mutex_unlock(&kprobe_mutex);
88} 89}
89 90
90static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 91static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -373,17 +374,62 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
373{ 374{
374 struct kprobe *cur = kprobe_running(); 375 struct kprobe *cur = kprobe_running();
375 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 376 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
376 377 const struct exception_table_entry *entry;
377 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) 378
378 return 1; 379 switch(kcb->kprobe_status) {
379 380 case KPROBE_HIT_SS:
380 if (kcb->kprobe_status & KPROBE_HIT_SS) { 381 case KPROBE_REENTER:
381 resume_execution(cur, regs); 382 /*
383 * We are here because the instruction being single
384 * stepped caused a page fault. We reset the current
385 * kprobe and the nip points back to the probe address
386 * and allow the page fault handler to continue as a
387 * normal page fault.
388 */
389 regs->nip = (unsigned long)cur->addr;
382 regs->msr &= ~MSR_SE; 390 regs->msr &= ~MSR_SE;
383 regs->msr |= kcb->kprobe_saved_msr; 391 regs->msr |= kcb->kprobe_saved_msr;
384 392 if (kcb->kprobe_status == KPROBE_REENTER)
385 reset_current_kprobe(); 393 restore_previous_kprobe(kcb);
394 else
395 reset_current_kprobe();
386 preempt_enable_no_resched(); 396 preempt_enable_no_resched();
397 break;
398 case KPROBE_HIT_ACTIVE:
399 case KPROBE_HIT_SSDONE:
400 /*
401 * We increment the nmissed count for accounting,
402 * we can also use npre/npostfault count for accouting
403 * these specific fault cases.
404 */
405 kprobes_inc_nmissed_count(cur);
406
407 /*
408 * We come here because instructions in the pre/post
409 * handler caused the page_fault, this could happen
410 * if handler tries to access user space by
411 * copy_from_user(), get_user() etc. Let the
412 * user-specified handler try to fix it first.
413 */
414 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
415 return 1;
416
417 /*
418 * In case the user-specified fault handler returned
419 * zero, try to fix up.
420 */
421 if ((entry = search_exception_tables(regs->nip)) != NULL) {
422 regs->nip = entry->fixup;
423 return 1;
424 }
425
426 /*
427 * fixup_exception() could not handle it,
428 * Let do_page_fault() fix it.
429 */
430 break;
431 default:
432 break;
387 } 433 }
388 return 0; 434 return 0;
389} 435}
@@ -397,6 +443,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
397 struct die_args *args = (struct die_args *)data; 443 struct die_args *args = (struct die_args *)data;
398 int ret = NOTIFY_DONE; 444 int ret = NOTIFY_DONE;
399 445
446 if (args->regs && user_mode(args->regs))
447 return ret;
448
400 switch (val) { 449 switch (val) {
401 case DIE_BPT: 450 case DIE_BPT:
402 if (kprobe_handler(args->regs)) 451 if (kprobe_handler(args->regs))
diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S
new file mode 100644
index 000000000000..d7f4e982b539
--- /dev/null
+++ b/arch/powerpc/kernel/l2cr_6xx.S
@@ -0,0 +1,471 @@
1/*
2 L2CR functions
3 Copyright © 1997-1998 by PowerLogix R & D, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19/*
20 Thur, Dec. 12, 1998.
21 - First public release, contributed by PowerLogix.
22 ***********
23 Sat, Aug. 7, 1999.
24 - Terry: Made sure code disabled interrupts before running. (Previously
25 it was assumed interrupts were already disabled).
26 - Terry: Updated for tentative G4 support. 4MB of memory is now flushed
27 instead of 2MB. (Prob. only 3 is necessary).
28 - Terry: Updated for workaround to HID0[DPM] processor bug
29 during global invalidates.
30 ***********
31 Thu, July 13, 2000.
32 - Terry: Added isync to correct for an errata.
33
34 22 August 2001.
35 - DanM: Finally added the 7450 patch I've had for the past
36 several months. The L2CR is similar, but I'm going
37 to assume the user of this functions knows what they
38 are doing.
39
40 Author: Terry Greeniaus (tgree@phys.ualberta.ca)
41 Please e-mail updates to this file to me, thanks!
42*/
43#include <linux/config.h>
44#include <asm/processor.h>
45#include <asm/cputable.h>
46#include <asm/ppc_asm.h>
47#include <asm/cache.h>
48#include <asm/page.h>
49
50/* Usage:
51
52 When setting the L2CR register, you must do a few special
53 things. If you are enabling the cache, you must perform a
54 global invalidate. If you are disabling the cache, you must
55 flush the cache contents first. This routine takes care of
56 doing these things. When first enabling the cache, make sure
57 you pass in the L2CR you want, as well as passing in the
58 global invalidate bit set. A global invalidate will only be
59 performed if the L2I bit is set in applyThis. When enabling
60 the cache, you should also set the L2E bit in applyThis. If
61 you want to modify the L2CR contents after the cache has been
62 enabled, the recommended procedure is to first call
63 __setL2CR(0) to disable the cache and then call it again with
64 the new values for L2CR. Examples:
65
66 _setL2CR(0) - disables the cache
67 _setL2CR(0xB3A04000) - enables my G3 upgrade card:
68 - L2E set to turn on the cache
69 - L2SIZ set to 1MB
70 - L2CLK set to 1:1
71 - L2RAM set to pipelined synchronous late-write
72 - L2I set to perform a global invalidation
73 - L2OH set to 0.5 nS
74 - L2DF set because this upgrade card
75 requires it
76
77 A similar call should work for your card. You need to know
78 the correct setting for your card and then place them in the
79 fields I have outlined above. Other fields support optional
80 features, such as L2DO which caches only data, or L2TS which
81 causes cache pushes from the L1 cache to go to the L2 cache
82 instead of to main memory.
83
84IMPORTANT:
85 Starting with the 7450, the bits in this register have moved
86 or behave differently. The Enable, Parity Enable, Size,
87 and L2 Invalidate are the only bits that have not moved.
88 The size is read-only for these processors with internal L2
89 cache, and the invalidate is a control as well as status.
90 -- Dan
91
92*/
93/*
94 * Summary: this procedure ignores the L2I bit in the value passed in,
95 * flushes the cache if it was already enabled, always invalidates the
96 * cache, then enables the cache if the L2E bit is set in the value
97 * passed in.
98 * -- paulus.
99 */
100_GLOBAL(_set_L2CR)
101 /* Make sure this is a 750 or 7400 chip */
102BEGIN_FTR_SECTION
103 li r3,-1
104 blr
105END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
106
107 mflr r9
108
109 /* Stop DST streams */
110BEGIN_FTR_SECTION
111 DSSALL
112 sync
113END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
114
115 /* Turn off interrupts and data relocation. */
116 mfmsr r7 /* Save MSR in r7 */
117 rlwinm r4,r7,0,17,15
118 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
119 sync
120 mtmsr r4
121 isync
122
123 /* Before we perform the global invalidation, we must disable dynamic
124 * power management via HID0[DPM] to work around a processor bug where
125 * DPM can possibly interfere with the state machine in the processor
126 * that invalidates the L2 cache tags.
127 */
128 mfspr r8,SPRN_HID0 /* Save HID0 in r8 */
129 rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
130 sync
131 mtspr SPRN_HID0,r4 /* Disable DPM */
132 sync
133
134 /* Get the current enable bit of the L2CR into r4 */
135 mfspr r4,SPRN_L2CR
136
137 /* Tweak some bits */
138 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
139 rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
140 rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
141
142 /* Check to see if we need to flush */
143 rlwinm. r4,r4,0,0,0
144 beq 2f
145
146 /* Flush the cache. First, read the first 4MB of memory (physical) to
147 * put new data in the cache. (Actually we only need
148 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
149 * cover everything just to be safe).
150 */
151
152 /**** Might be a good idea to set L2DO here - to prevent instructions
153 from getting into the cache. But since we invalidate
154 the next time we enable the cache it doesn't really matter.
155 Don't do this unless you accomodate all processor variations.
156 The bit moved on the 7450.....
157 ****/
158
159BEGIN_FTR_SECTION
160 /* Disable L2 prefetch on some 745x and try to ensure
161 * L2 prefetch engines are idle. As explained by errata
162 * text, we can't be sure they are, we just hope very hard
163 * that well be enough (sic !). At least I noticed Apple
164 * doesn't even bother doing the dcbf's here...
165 */
166 mfspr r4,SPRN_MSSCR0
167 rlwinm r4,r4,0,0,29
168 sync
169 mtspr SPRN_MSSCR0,r4
170 sync
171 isync
172 lis r4,KERNELBASE@h
173 dcbf 0,r4
174 dcbf 0,r4
175 dcbf 0,r4
176 dcbf 0,r4
177END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
178
179 /* TODO: use HW flush assist when available */
180
181 lis r4,0x0002
182 mtctr r4
183 li r4,0
1841:
185 lwzx r0,r0,r4
186 addi r4,r4,32 /* Go to start of next cache line */
187 bdnz 1b
188 isync
189
190 /* Now, flush the first 4MB of memory */
191 lis r4,0x0002
192 mtctr r4
193 li r4,0
194 sync
1951:
196 dcbf 0,r4
197 addi r4,r4,32 /* Go to start of next cache line */
198 bdnz 1b
199
2002:
201 /* Set up the L2CR configuration bits (and switch L2 off) */
202 /* CPU errata: Make sure the mtspr below is already in the
203 * L1 icache
204 */
205 b 20f
206 .balign L1_CACHE_BYTES
20722:
208 sync
209 mtspr SPRN_L2CR,r3
210 sync
211 b 23f
21220:
213 b 21f
21421: sync
215 isync
216 b 22b
217
21823:
219 /* Perform a global invalidation */
220 oris r3,r3,0x0020
221 sync
222 mtspr SPRN_L2CR,r3
223 sync
224 isync /* For errata */
225
226BEGIN_FTR_SECTION
227 /* On the 7450, we wait for the L2I bit to clear......
228 */
22910: mfspr r3,SPRN_L2CR
230 andis. r4,r3,0x0020
231 bne 10b
232 b 11f
233END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
234
235 /* Wait for the invalidation to complete */
2363: mfspr r3,SPRN_L2CR
237 rlwinm. r4,r3,0,31,31
238 bne 3b
239
24011: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */
241 sync
242 mtspr SPRN_L2CR,r3
243 sync
244
245 /* See if we need to enable the cache */
246 cmplwi r5,0
247 beq 4f
248
249 /* Enable the cache */
250 oris r3,r3,0x8000
251 mtspr SPRN_L2CR,r3
252 sync
253
254 /* Enable L2 HW prefetch on 744x/745x */
255BEGIN_FTR_SECTION
256 mfspr r3,SPRN_MSSCR0
257 ori r3,r3,3
258 sync
259 mtspr SPRN_MSSCR0,r3
260 sync
261 isync
262END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
2634:
264
265 /* Restore HID0[DPM] to whatever it was before */
266 sync
267 mtspr 1008,r8
268 sync
269
270 /* Restore MSR (restores EE and DR bits to original state) */
271 SYNC
272 mtmsr r7
273 isync
274
275 mtlr r9
276 blr
277
278_GLOBAL(_get_L2CR)
279 /* Return the L2CR contents */
280 li r3,0
281BEGIN_FTR_SECTION
282 mfspr r3,SPRN_L2CR
283END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
284 blr
285
286
287/*
288 * Here is a similar routine for dealing with the L3 cache
289 * on the 745x family of chips
290 */
291
292_GLOBAL(_set_L3CR)
293 /* Make sure this is a 745x chip */
294BEGIN_FTR_SECTION
295 li r3,-1
296 blr
297END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
298
299 /* Turn off interrupts and data relocation. */
300 mfmsr r7 /* Save MSR in r7 */
301 rlwinm r4,r7,0,17,15
302 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
303 sync
304 mtmsr r4
305 isync
306
307 /* Stop DST streams */
308 DSSALL
309 sync
310
311 /* Get the current enable bit of the L3CR into r4 */
312 mfspr r4,SPRN_L3CR
313
314 /* Tweak some bits */
315 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
316 rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */
317 rlwinm r3,r3,0,2,31 /* Turn off the enable & PE bits */
318 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
319 /* Check to see if we need to flush */
320 rlwinm. r4,r4,0,0,0
321 beq 2f
322
323 /* Flush the cache.
324 */
325
326 /* TODO: use HW flush assist */
327
328 lis r4,0x0008
329 mtctr r4
330 li r4,0
3311:
332 lwzx r0,r0,r4
333 dcbf 0,r4
334 addi r4,r4,32 /* Go to start of next cache line */
335 bdnz 1b
336
3372:
338 /* Set up the L3CR configuration bits (and switch L3 off) */
339 sync
340 mtspr SPRN_L3CR,r3
341 sync
342
343 oris r3,r3,L3CR_L3RES@h /* Set reserved bit 5 */
344 mtspr SPRN_L3CR,r3
345 sync
346 oris r3,r3,L3CR_L3CLKEN@h /* Set clken */
347 mtspr SPRN_L3CR,r3
348 sync
349
350 /* Wait for stabilize */
351 li r0,256
352 mtctr r0
3531: bdnz 1b
354
355 /* Perform a global invalidation */
356 ori r3,r3,0x0400
357 sync
358 mtspr SPRN_L3CR,r3
359 sync
360 isync
361
362 /* We wait for the L3I bit to clear...... */
36310: mfspr r3,SPRN_L3CR
364 andi. r4,r3,0x0400
365 bne 10b
366
367 /* Clear CLKEN */
368 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
369 mtspr SPRN_L3CR,r3
370 sync
371
372 /* Wait for stabilize */
373 li r0,256
374 mtctr r0
3751: bdnz 1b
376
377 /* See if we need to enable the cache */
378 cmplwi r5,0
379 beq 4f
380
381 /* Enable the cache */
382 oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
383 mtspr SPRN_L3CR,r3
384 sync
385
386 /* Wait for stabilize */
387 li r0,256
388 mtctr r0
3891: bdnz 1b
390
391 /* Restore MSR (restores EE and DR bits to original state) */
3924: SYNC
393 mtmsr r7
394 isync
395 blr
396
397_GLOBAL(_get_L3CR)
398 /* Return the L3CR contents */
399 li r3,0
400BEGIN_FTR_SECTION
401 mfspr r3,SPRN_L3CR
402END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
403 blr
404
405/* --- End of PowerLogix code ---
406 */
407
408
409/* flush_disable_L1() - Flush and disable L1 cache
410 *
411 * clobbers r0, r3, ctr, cr0
412 * Must be called with interrupts disabled and MMU enabled.
413 */
414_GLOBAL(__flush_disable_L1)
415 /* Stop pending alitvec streams and memory accesses */
416BEGIN_FTR_SECTION
417 DSSALL
418END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
419 sync
420
421 /* Load counter to 0x4000 cache lines (512k) and
422 * load cache with datas
423 */
424 li r3,0x4000 /* 512kB / 32B */
425 mtctr r3
426 lis r3,KERNELBASE@h
4271:
428 lwz r0,0(r3)
429 addi r3,r3,0x0020 /* Go to start of next cache line */
430 bdnz 1b
431 isync
432 sync
433
434 /* Now flush those cache lines */
435 li r3,0x4000 /* 512kB / 32B */
436 mtctr r3
437 lis r3,KERNELBASE@h
4381:
439 dcbf 0,r3
440 addi r3,r3,0x0020 /* Go to start of next cache line */
441 bdnz 1b
442 sync
443
444 /* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
445 mfspr r3,SPRN_HID0
446 rlwinm r3,r3,0,18,15
447 mtspr SPRN_HID0,r3
448 sync
449 isync
450 blr
451
452/* inval_enable_L1 - Invalidate and enable L1 cache
453 *
454 * Assumes L1 is already disabled and MSR:EE is off
455 *
456 * clobbers r3
457 */
458_GLOBAL(__inval_enable_L1)
459 /* Enable and then Flash inval the instruction & data cache */
460 mfspr r3,SPRN_HID0
461 ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
462 sync
463 isync
464 mtspr SPRN_HID0,r3
465 xori r3,r3, HID0_ICFI|HID0_DCI
466 mtspr SPRN_HID0,r3
467 sync
468
469 blr
470
471
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index c7a799a09516..6e67b5b49ba1 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -37,7 +37,7 @@ static int legacy_serial_console = -1;
37static int __init add_legacy_port(struct device_node *np, int want_index, 37static int __init add_legacy_port(struct device_node *np, int want_index,
38 int iotype, phys_addr_t base, 38 int iotype, phys_addr_t base,
39 phys_addr_t taddr, unsigned long irq, 39 phys_addr_t taddr, unsigned long irq,
40 unsigned int flags) 40 upf_t flags)
41{ 41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16; 42 u32 *clk, *spd, clock = BASE_BAUD * 16;
43 int index; 43 int index;
@@ -113,7 +113,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
113{ 113{
114 phys_addr_t addr; 114 phys_addr_t addr;
115 u32 *addrp; 115 u32 *addrp;
116 unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 116 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
117 117
118 /* We only support ports that have a clock frequency properly 118 /* We only support ports that have a clock frequency properly
119 * encoded in the device-tree. 119 * encoded in the device-tree.
@@ -236,6 +236,23 @@ static int __init add_legacy_pci_port(struct device_node *np,
236} 236}
237#endif 237#endif
238 238
239static void __init setup_legacy_serial_console(int console)
240{
241 struct legacy_serial_info *info =
242 &legacy_serial_infos[console];
243 void __iomem *addr;
244
245 if (info->taddr == 0)
246 return;
247 addr = ioremap(info->taddr, 0x1000);
248 if (addr == NULL)
249 return;
250 if (info->speed == 0)
251 info->speed = udbg_probe_uart_speed(addr, info->clock);
252 DBG("default console speed = %d\n", info->speed);
253 udbg_init_uart(addr, info->speed, info->clock);
254}
255
239/* 256/*
240 * This is called very early, as part of setup_system() or eventually 257 * This is called very early, as part of setup_system() or eventually
241 * setup_arch(), basically before anything else in this file. This function 258 * setup_arch(), basically before anything else in this file. This function
@@ -318,25 +335,8 @@ void __init find_legacy_serial_ports(void)
318#endif 335#endif
319 336
320 DBG("legacy_serial_console = %d\n", legacy_serial_console); 337 DBG("legacy_serial_console = %d\n", legacy_serial_console);
321 338 if (legacy_serial_console >= 0)
322 /* udbg is 64 bits only for now, that will change soon though ... */ 339 setup_legacy_serial_console(legacy_serial_console);
323 while (legacy_serial_console >= 0) {
324 struct legacy_serial_info *info =
325 &legacy_serial_infos[legacy_serial_console];
326 void __iomem *addr;
327
328 if (info->taddr == 0)
329 break;
330 addr = ioremap(info->taddr, 0x1000);
331 if (addr == NULL)
332 break;
333 if (info->speed == 0)
334 info->speed = udbg_probe_uart_speed(addr, info->clock);
335 DBG("default console speed = %d\n", info->speed);
336 udbg_init_uart(addr, info->speed, info->clock);
337 break;
338 }
339
340 DBG(" <- find_legacy_serial_port()\n"); 340 DBG(" <- find_legacy_serial_port()\n");
341} 341}
342 342
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index e789fef4eb8a..1b73508ecb2b 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -56,7 +56,7 @@ static unsigned long get_purr(void)
56 unsigned long sum_purr = 0; 56 unsigned long sum_purr = 0;
57 int cpu; 57 int cpu;
58 58
59 for_each_cpu(cpu) { 59 for_each_possible_cpu(cpu) {
60 sum_purr += lppaca[cpu].emulated_time_base; 60 sum_purr += lppaca[cpu].emulated_time_base;
61 61
62#ifdef PURR_DEBUG 62#ifdef PURR_DEBUG
@@ -222,7 +222,7 @@ static unsigned long get_purr(void)
222 int cpu; 222 int cpu;
223 struct cpu_usage *cu; 223 struct cpu_usage *cu;
224 224
225 for_each_cpu(cpu) { 225 for_each_possible_cpu(cpu) {
226 cu = &per_cpu(cpu_usage_array, cpu); 226 cu = &per_cpu(cpu_usage_array, cpu);
227 sum_purr += cu->current_tb; 227 sum_purr += cu->current_tb;
228 } 228 }
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
new file mode 100644
index 000000000000..92f4e5f64f02
--- /dev/null
+++ b/arch/powerpc/kernel/module_32.c
@@ -0,0 +1,320 @@
1/* Kernel module help for PPC.
2 Copyright (C) 2001 Rusty Russell.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18#include <linux/module.h>
19#include <linux/moduleloader.h>
20#include <linux/elf.h>
21#include <linux/vmalloc.h>
22#include <linux/fs.h>
23#include <linux/string.h>
24#include <linux/kernel.h>
25#include <linux/cache.h>
26
27#if 0
28#define DEBUGP printk
29#else
30#define DEBUGP(fmt , ...)
31#endif
32
33LIST_HEAD(module_bug_list);
34
35void *module_alloc(unsigned long size)
36{
37 if (size == 0)
38 return NULL;
39 return vmalloc(size);
40}
41
42/* Free memory returned from module_alloc */
43void module_free(struct module *mod, void *module_region)
44{
45 vfree(module_region);
46 /* FIXME: If module_region == mod->init_region, trim exception
47 table entries. */
48}
49
50/* Count how many different relocations (different symbol, different
51 addend) */
52static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
53{
54 unsigned int i, j, ret = 0;
55
56 /* Sure, this is order(n^2), but it's usually short, and not
57 time critical */
58 for (i = 0; i < num; i++) {
59 for (j = 0; j < i; j++) {
60 /* If this addend appeared before, it's
61 already been counted */
62 if (ELF32_R_SYM(rela[i].r_info)
63 == ELF32_R_SYM(rela[j].r_info)
64 && rela[i].r_addend == rela[j].r_addend)
65 break;
66 }
67 if (j == i) ret++;
68 }
69 return ret;
70}
71
72/* Get the potential trampolines size required of the init and
73 non-init sections */
74static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
75 const Elf32_Shdr *sechdrs,
76 const char *secstrings,
77 int is_init)
78{
79 unsigned long ret = 0;
80 unsigned i;
81
82 /* Everything marked ALLOC (this includes the exported
83 symbols) */
84 for (i = 1; i < hdr->e_shnum; i++) {
85 /* If it's called *.init*, and we're not init, we're
86 not interested */
87 if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
88 != is_init)
89 continue;
90
91 /* We don't want to look at debug sections. */
92 if (strstr(secstrings + sechdrs[i].sh_name, ".debug") != 0)
93 continue;
94
95 if (sechdrs[i].sh_type == SHT_RELA) {
96 DEBUGP("Found relocations in section %u\n", i);
97 DEBUGP("Ptr: %p. Number: %u\n",
98 (void *)hdr + sechdrs[i].sh_offset,
99 sechdrs[i].sh_size / sizeof(Elf32_Rela));
100 ret += count_relocs((void *)hdr
101 + sechdrs[i].sh_offset,
102 sechdrs[i].sh_size
103 / sizeof(Elf32_Rela))
104 * sizeof(struct ppc_plt_entry);
105 }
106 }
107
108 return ret;
109}
110
111int module_frob_arch_sections(Elf32_Ehdr *hdr,
112 Elf32_Shdr *sechdrs,
113 char *secstrings,
114 struct module *me)
115{
116 unsigned int i;
117
118 /* Find .plt and .init.plt sections */
119 for (i = 0; i < hdr->e_shnum; i++) {
120 if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0)
121 me->arch.init_plt_section = i;
122 else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
123 me->arch.core_plt_section = i;
124 }
125 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
126 printk("Module doesn't contain .plt or .init.plt sections.\n");
127 return -ENOEXEC;
128 }
129
130 /* Override their sizes */
131 sechdrs[me->arch.core_plt_section].sh_size
132 = get_plt_size(hdr, sechdrs, secstrings, 0);
133 sechdrs[me->arch.init_plt_section].sh_size
134 = get_plt_size(hdr, sechdrs, secstrings, 1);
135 return 0;
136}
137
138int apply_relocate(Elf32_Shdr *sechdrs,
139 const char *strtab,
140 unsigned int symindex,
141 unsigned int relsec,
142 struct module *module)
143{
144 printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n",
145 module->name);
146 return -ENOEXEC;
147}
148
149static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val)
150{
151 if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16)
152 && entry->jump[1] == 0x396b0000 + (val & 0xffff))
153 return 1;
154 return 0;
155}
156
157/* Set up a trampoline in the PLT to bounce us to the distant function */
158static uint32_t do_plt_call(void *location,
159 Elf32_Addr val,
160 Elf32_Shdr *sechdrs,
161 struct module *mod)
162{
163 struct ppc_plt_entry *entry;
164
165 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
166 /* Init, or core PLT? */
167 if (location >= mod->module_core
168 && location < mod->module_core + mod->core_size)
169 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
170 else
171 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
172
173 /* Find this entry, or if that fails, the next avail. entry */
174 while (entry->jump[0]) {
175 if (entry_matches(entry, val)) return (uint32_t)entry;
176 entry++;
177 }
178
179 /* Stolen from Paul Mackerras as well... */
180 entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */
181 entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/
182 entry->jump[2] = 0x7d6903a6; /* mtctr r11 */
183 entry->jump[3] = 0x4e800420; /* bctr */
184
185 DEBUGP("Initialized plt for 0x%x at %p\n", val, entry);
186 return (uint32_t)entry;
187}
188
189int apply_relocate_add(Elf32_Shdr *sechdrs,
190 const char *strtab,
191 unsigned int symindex,
192 unsigned int relsec,
193 struct module *module)
194{
195 unsigned int i;
196 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
197 Elf32_Sym *sym;
198 uint32_t *location;
199 uint32_t value;
200
201 DEBUGP("Applying ADD relocate section %u to %u\n", relsec,
202 sechdrs[relsec].sh_info);
203 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
204 /* This is where to make the change */
205 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
206 + rela[i].r_offset;
207 /* This is the symbol it is referring to. Note that all
208 undefined symbols have been resolved. */
209 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
210 + ELF32_R_SYM(rela[i].r_info);
211 /* `Everything is relative'. */
212 value = sym->st_value + rela[i].r_addend;
213
214 switch (ELF32_R_TYPE(rela[i].r_info)) {
215 case R_PPC_ADDR32:
216 /* Simply set it */
217 *(uint32_t *)location = value;
218 break;
219
220 case R_PPC_ADDR16_LO:
221 /* Low half of the symbol */
222 *(uint16_t *)location = value;
223 break;
224
225 case R_PPC_ADDR16_HA:
226 /* Sign-adjusted lower 16 bits: PPC ELF ABI says:
227 (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF.
228 This is the same, only sane.
229 */
230 *(uint16_t *)location = (value + 0x8000) >> 16;
231 break;
232
233 case R_PPC_REL24:
234 if ((int)(value - (uint32_t)location) < -0x02000000
235 || (int)(value - (uint32_t)location) >= 0x02000000)
236 value = do_plt_call(location, value,
237 sechdrs, module);
238
239 /* Only replace bits 2 through 26 */
240 DEBUGP("REL24 value = %08X. location = %08X\n",
241 value, (uint32_t)location);
242 DEBUGP("Location before: %08X.\n",
243 *(uint32_t *)location);
244 *(uint32_t *)location
245 = (*(uint32_t *)location & ~0x03fffffc)
246 | ((value - (uint32_t)location)
247 & 0x03fffffc);
248 DEBUGP("Location after: %08X.\n",
249 *(uint32_t *)location);
250 DEBUGP("ie. jump to %08X+%08X = %08X\n",
251 *(uint32_t *)location & 0x03fffffc,
252 (uint32_t)location,
253 (*(uint32_t *)location & 0x03fffffc)
254 + (uint32_t)location);
255 break;
256
257 case R_PPC_REL32:
258 /* 32-bit relative jump. */
259 *(uint32_t *)location = value - (uint32_t)location;
260 break;
261
262 default:
263 printk("%s: unknown ADD relocation: %u\n",
264 module->name,
265 ELF32_R_TYPE(rela[i].r_info));
266 return -ENOEXEC;
267 }
268 }
269 return 0;
270}
271
272int module_finalize(const Elf_Ehdr *hdr,
273 const Elf_Shdr *sechdrs,
274 struct module *me)
275{
276 char *secstrings;
277 unsigned int i;
278
279 me->arch.bug_table = NULL;
280 me->arch.num_bugs = 0;
281
282 /* Find the __bug_table section, if present */
283 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
284 for (i = 1; i < hdr->e_shnum; i++) {
285 if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
286 continue;
287 me->arch.bug_table = (void *) sechdrs[i].sh_addr;
288 me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
289 break;
290 }
291
292 /*
293 * Strictly speaking this should have a spinlock to protect against
294 * traversals, but since we only traverse on BUG()s, a spinlock
295 * could potentially lead to deadlock and thus be counter-productive.
296 */
297 list_add(&me->arch.bug_list, &module_bug_list);
298
299 return 0;
300}
301
302void module_arch_cleanup(struct module *mod)
303{
304 list_del(&mod->arch.bug_list);
305}
306
307struct bug_entry *module_find_bug(unsigned long bugaddr)
308{
309 struct mod_arch_specific *mod;
310 unsigned int i;
311 struct bug_entry *bug;
312
313 list_for_each_entry(mod, &module_bug_list, bug_list) {
314 bug = mod->bug_table;
315 for (i = 0; i < mod->num_bugs; ++i, ++bug)
316 if (bugaddr == bug->bug_addr)
317 return bug;
318 }
319 return NULL;
320}
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index fd7db8d542db..ada50aa5b600 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
160 case IOC_NVRAM_GET_OFFSET: { 160 case IOC_NVRAM_GET_OFFSET: {
161 int part, offset; 161 int part, offset;
162 162
163 if (_machine != PLATFORM_POWERMAC) 163 if (!machine_is(powermac))
164 return -EINVAL; 164 return -EINVAL;
165 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 165 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
166 return -EFAULT; 166 return -EFAULT;
@@ -174,8 +174,9 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
174 return 0; 174 return 0;
175 } 175 }
176#endif /* CONFIG_PPC_PMAC */ 176#endif /* CONFIG_PPC_PMAC */
177 default:
178 return -EINVAL;
177 } 179 }
178 return -EINVAL;
179} 180}
180 181
181struct file_operations nvram_fops = { 182struct file_operations nvram_fops = {
@@ -443,7 +444,7 @@ static int nvram_setup_partition(void)
443 * in our nvram, as Apple defined partitions use pretty much 444 * in our nvram, as Apple defined partitions use pretty much
444 * all of the space 445 * all of the space
445 */ 446 */
446 if (_machine == PLATFORM_POWERMAC) 447 if (machine_is(powermac))
447 return -ENOSPC; 448 return -ENOSPC;
448 449
449 /* see if we have an OS partition that meets our needs. 450 /* see if we have an OS partition that meets our needs.
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 22d83d4d1af5..9feeeef5a875 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -147,15 +147,12 @@ postcore_initcall(of_bus_driver_init);
147 147
148int of_register_driver(struct of_platform_driver *drv) 148int of_register_driver(struct of_platform_driver *drv)
149{ 149{
150 int count = 0;
151
152 /* initialize common driver fields */ 150 /* initialize common driver fields */
153 drv->driver.name = drv->name; 151 drv->driver.name = drv->name;
154 drv->driver.bus = &of_platform_bus_type; 152 drv->driver.bus = &of_platform_bus_type;
155 153
156 /* register with core */ 154 /* register with core */
157 count = driver_register(&drv->driver); 155 return driver_register(&drv->driver);
158 return count ? count : 1;
159} 156}
160 157
161void of_unregister_driver(struct of_platform_driver *drv) 158void of_unregister_driver(struct of_platform_driver *drv)
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5d1b708086bd..f505a8827e3e 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -56,14 +56,11 @@ struct lppaca lppaca[] = {
56 * processors. The processor VPD array needs one entry per physical 56 * processors. The processor VPD array needs one entry per physical
57 * processor (not thread). 57 * processor (not thread).
58 */ 58 */
59#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 59#define PACA_INIT_COMMON(number) \
60 .lppaca_ptr = &lppaca[number], \ 60 .lppaca_ptr = &lppaca[number], \
61 .lock_token = 0x8000, \ 61 .lock_token = 0x8000, \
62 .paca_index = (number), /* Paca Index */ \ 62 .paca_index = (number), /* Paca Index */ \
63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
64 .stab_real = (asrr), /* Real pointer to segment table */ \
65 .stab_addr = (asrv), /* Virt pointer to segment table */ \
66 .cpu_start = (start), /* Processor start */ \
67 .hw_cpu_id = 0xffff, 64 .hw_cpu_id = 0xffff,
68 65
69#ifdef CONFIG_PPC_ISERIES 66#ifdef CONFIG_PPC_ISERIES
@@ -72,30 +69,20 @@ struct lppaca lppaca[] = {
72 69
73#define PACA_INIT(number) \ 70#define PACA_INIT(number) \
74{ \ 71{ \
75 PACA_INIT_COMMON(number, 0, 0, 0) \ 72 PACA_INIT_COMMON(number) \
76 PACA_INIT_ISERIES(number) \
77}
78
79#define BOOTCPU_PACA_INIT(number) \
80{ \
81 PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \
82 PACA_INIT_ISERIES(number) \ 73 PACA_INIT_ISERIES(number) \
83} 74}
84 75
85#else 76#else
86#define PACA_INIT(number) \ 77#define PACA_INIT(number) \
87{ \ 78{ \
88 PACA_INIT_COMMON(number, 0, 0, 0) \ 79 PACA_INIT_COMMON(number) \
89} 80}
90 81
91#define BOOTCPU_PACA_INIT(number) \
92{ \
93 PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \
94}
95#endif 82#endif
96 83
97struct paca_struct paca[] = { 84struct paca_struct paca[] = {
98 BOOTCPU_PACA_INIT(0), 85 PACA_INIT(0),
99#if NR_CPUS > 1 86#if NR_CPUS > 1
100 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), 87 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3),
101#if NR_CPUS > 4 88#if NR_CPUS > 4
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 704c846b2b0f..b129d2e4b759 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
787 * fix has to be done by making the remapping per-host and always 787 * fix has to be done by making the remapping per-host and always
788 * filling the pci_to_OF map. --BenH 788 * filling the pci_to_OF map. --BenH
789 */ 789 */
790 if (_machine == _MACH_Pmac && busnr >= 0xf0) 790 if (machine_is(powermac) && busnr >= 0xf0)
791 busnr -= 0xf0; 791 busnr -= 0xf0;
792 else 792 else
793#endif 793#endif
@@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
1728 * (bus 0 is HT root), we return the AGP one instead. 1728 * (bus 0 is HT root), we return the AGP one instead.
1729 */ 1729 */
1730#ifdef CONFIG_PPC_PMAC 1730#ifdef CONFIG_PPC_PMAC
1731 if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) 1731 if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
1732 if (bus == 0) 1732 if (bus == 0)
1733 bus = 0xf0; 1733 bus = 0xf0;
1734#endif /* CONFIG_PPC_PMAC */ 1734#endif /* CONFIG_PPC_PMAC */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index c367520bc1c3..4c4449be81ce 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -78,6 +78,7 @@ int global_phb_number; /* Global phb counter */
78 78
79/* Cached ISA bridge dev. */ 79/* Cached ISA bridge dev. */
80struct pci_dev *ppc64_isabridge_dev = NULL; 80struct pci_dev *ppc64_isabridge_dev = NULL;
81EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
81 82
82static void fixup_broken_pcnet32(struct pci_dev* dev) 83static void fixup_broken_pcnet32(struct pci_dev* dev)
83{ 84{
@@ -589,7 +590,6 @@ void __devinit scan_phb(struct pci_controller *hose)
589#endif /* CONFIG_PPC_MULTIPLATFORM */ 590#endif /* CONFIG_PPC_MULTIPLATFORM */
590 if (mode == PCI_PROBE_NORMAL) 591 if (mode == PCI_PROBE_NORMAL)
591 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 592 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
592 pci_bus_add_devices(bus);
593} 593}
594 594
595static int __init pcibios_init(void) 595static int __init pcibios_init(void)
@@ -608,8 +608,10 @@ static int __init pcibios_init(void)
608 printk("PCI: Probing PCI hardware\n"); 608 printk("PCI: Probing PCI hardware\n");
609 609
610 /* Scan all of the recorded PCI controllers. */ 610 /* Scan all of the recorded PCI controllers. */
611 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) 611 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
612 scan_phb(hose); 612 scan_phb(hose);
613 pci_bus_add_devices(hose->bus);
614 }
613 615
614#ifndef CONFIG_PPC_ISERIES 616#ifndef CONFIG_PPC_ISERIES
615 if (pci_probe_only) 617 if (pci_probe_only)
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
index bdf15dbbf4f0..c336f3e31cff 100644
--- a/arch/powerpc/kernel/pci_iommu.c
+++ b/arch/powerpc/kernel/pci_iommu.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/pci_iommu.c
3 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
4 * 3 *
5 * Rewrite, cleanup, new allocation schemes: 4 * Rewrite, cleanup, new allocation schemes:
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
new file mode 100644
index 000000000000..32455dfcc36b
--- /dev/null
+++ b/arch/powerpc/kernel/perfmon_fsl_booke.c
@@ -0,0 +1,222 @@
1/* kernel/perfmon_fsl_booke.c
2 * Freescale Book-E Performance Monitor code
3 *
4 * Author: Andy Fleming
5 * Copyright (c) 2004 Freescale Semiconductor, Inc
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/errno.h>
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/mm.h>
17#include <linux/stddef.h>
18#include <linux/unistd.h>
19#include <linux/ptrace.h>
20#include <linux/slab.h>
21#include <linux/user.h>
22#include <linux/a.out.h>
23#include <linux/interrupt.h>
24#include <linux/config.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/prctl.h>
28
29#include <asm/pgtable.h>
30#include <asm/uaccess.h>
31#include <asm/system.h>
32#include <asm/io.h>
33#include <asm/reg.h>
34#include <asm/xmon.h>
35#include <asm/pmc.h>
36
37static inline u32 get_pmlca(int ctr);
38static inline void set_pmlca(int ctr, u32 pmlca);
39
40static inline u32 get_pmlca(int ctr)
41{
42 u32 pmlca;
43
44 switch (ctr) {
45 case 0:
46 pmlca = mfpmr(PMRN_PMLCA0);
47 break;
48 case 1:
49 pmlca = mfpmr(PMRN_PMLCA1);
50 break;
51 case 2:
52 pmlca = mfpmr(PMRN_PMLCA2);
53 break;
54 case 3:
55 pmlca = mfpmr(PMRN_PMLCA3);
56 break;
57 default:
58 panic("Bad ctr number\n");
59 }
60
61 return pmlca;
62}
63
64static inline void set_pmlca(int ctr, u32 pmlca)
65{
66 switch (ctr) {
67 case 0:
68 mtpmr(PMRN_PMLCA0, pmlca);
69 break;
70 case 1:
71 mtpmr(PMRN_PMLCA1, pmlca);
72 break;
73 case 2:
74 mtpmr(PMRN_PMLCA2, pmlca);
75 break;
76 case 3:
77 mtpmr(PMRN_PMLCA3, pmlca);
78 break;
79 default:
80 panic("Bad ctr number\n");
81 }
82}
83
84void init_pmc_stop(int ctr)
85{
86 u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
87 PMLCA_FCM1 | PMLCA_FCM0);
88 u32 pmlcb = 0;
89
90 switch (ctr) {
91 case 0:
92 mtpmr(PMRN_PMLCA0, pmlca);
93 mtpmr(PMRN_PMLCB0, pmlcb);
94 break;
95 case 1:
96 mtpmr(PMRN_PMLCA1, pmlca);
97 mtpmr(PMRN_PMLCB1, pmlcb);
98 break;
99 case 2:
100 mtpmr(PMRN_PMLCA2, pmlca);
101 mtpmr(PMRN_PMLCB2, pmlcb);
102 break;
103 case 3:
104 mtpmr(PMRN_PMLCA3, pmlca);
105 mtpmr(PMRN_PMLCB3, pmlcb);
106 break;
107 default:
108 panic("Bad ctr number!\n");
109 }
110}
111
112void set_pmc_event(int ctr, int event)
113{
114 u32 pmlca;
115
116 pmlca = get_pmlca(ctr);
117
118 pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
119 ((event << PMLCA_EVENT_SHIFT) &
120 PMLCA_EVENT_MASK);
121
122 set_pmlca(ctr, pmlca);
123}
124
125void set_pmc_user_kernel(int ctr, int user, int kernel)
126{
127 u32 pmlca;
128
129 pmlca = get_pmlca(ctr);
130
131 if(user)
132 pmlca &= ~PMLCA_FCU;
133 else
134 pmlca |= PMLCA_FCU;
135
136 if(kernel)
137 pmlca &= ~PMLCA_FCS;
138 else
139 pmlca |= PMLCA_FCS;
140
141 set_pmlca(ctr, pmlca);
142}
143
144void set_pmc_marked(int ctr, int mark0, int mark1)
145{
146 u32 pmlca = get_pmlca(ctr);
147
148 if(mark0)
149 pmlca &= ~PMLCA_FCM0;
150 else
151 pmlca |= PMLCA_FCM0;
152
153 if(mark1)
154 pmlca &= ~PMLCA_FCM1;
155 else
156 pmlca |= PMLCA_FCM1;
157
158 set_pmlca(ctr, pmlca);
159}
160
161void pmc_start_ctr(int ctr, int enable)
162{
163 u32 pmlca = get_pmlca(ctr);
164
165 pmlca &= ~PMLCA_FC;
166
167 if (enable)
168 pmlca |= PMLCA_CE;
169 else
170 pmlca &= ~PMLCA_CE;
171
172 set_pmlca(ctr, pmlca);
173}
174
175void pmc_start_ctrs(int enable)
176{
177 u32 pmgc0 = mfpmr(PMRN_PMGC0);
178
179 pmgc0 &= ~PMGC0_FAC;
180 pmgc0 |= PMGC0_FCECE;
181
182 if (enable)
183 pmgc0 |= PMGC0_PMIE;
184 else
185 pmgc0 &= ~PMGC0_PMIE;
186
187 mtpmr(PMRN_PMGC0, pmgc0);
188}
189
190void pmc_stop_ctrs(void)
191{
192 u32 pmgc0 = mfpmr(PMRN_PMGC0);
193
194 pmgc0 |= PMGC0_FAC;
195
196 pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
197
198 mtpmr(PMRN_PMGC0, pmgc0);
199}
200
201void dump_pmcs(void)
202{
203 printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
204 printk("pmc\t\tpmlca\t\tpmlcb\n");
205 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
206 mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
207 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
208 mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
209 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
210 mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
211 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
212 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
213}
214
215EXPORT_SYMBOL(init_pmc_stop);
216EXPORT_SYMBOL(set_pmc_event);
217EXPORT_SYMBOL(set_pmc_user_kernel);
218EXPORT_SYMBOL(set_pmc_marked);
219EXPORT_SYMBOL(pmc_start_ctr);
220EXPORT_SYMBOL(pmc_start_ctrs);
221EXPORT_SYMBOL(pmc_stop_ctrs);
222EXPORT_SYMBOL(dump_pmcs);
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 8a731ea877b7..dfa5398ab3c8 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -57,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
57extern void alignment_exception(struct pt_regs *regs); 57extern void alignment_exception(struct pt_regs *regs);
58extern void program_check_exception(struct pt_regs *regs); 58extern void program_check_exception(struct pt_regs *regs);
59extern void single_step_exception(struct pt_regs *regs); 59extern void single_step_exception(struct pt_regs *regs);
60extern int pmac_newworld;
61extern int sys_sigreturn(struct pt_regs *regs); 60extern int sys_sigreturn(struct pt_regs *regs);
62 61
63EXPORT_SYMBOL(clear_pages); 62EXPORT_SYMBOL(clear_pages);
@@ -110,15 +109,6 @@ EXPORT_SYMBOL(_insw_ns);
110EXPORT_SYMBOL(_outsw_ns); 109EXPORT_SYMBOL(_outsw_ns);
111EXPORT_SYMBOL(_insl_ns); 110EXPORT_SYMBOL(_insl_ns);
112EXPORT_SYMBOL(_outsl_ns); 111EXPORT_SYMBOL(_outsl_ns);
113EXPORT_SYMBOL(ioremap);
114#ifdef CONFIG_44x
115EXPORT_SYMBOL(ioremap64);
116#endif
117EXPORT_SYMBOL(__ioremap);
118EXPORT_SYMBOL(iounmap);
119#ifdef CONFIG_PPC32
120EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
121#endif
122 112
123#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) 113#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
124EXPORT_SYMBOL(ppc_ide_md); 114EXPORT_SYMBOL(ppc_ide_md);
@@ -161,7 +151,6 @@ EXPORT_SYMBOL(__flush_icache_range);
161EXPORT_SYMBOL(flush_dcache_range); 151EXPORT_SYMBOL(flush_dcache_range);
162 152
163#ifdef CONFIG_SMP 153#ifdef CONFIG_SMP
164EXPORT_SYMBOL(smp_call_function);
165#ifdef CONFIG_PPC32 154#ifdef CONFIG_PPC32
166EXPORT_SYMBOL(smp_hw_index); 155EXPORT_SYMBOL(smp_hw_index);
167#endif 156#endif
diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
index 7ba42a405f41..3c2cf661f6d9 100644
--- a/arch/powerpc/kernel/proc_ppc64.c
+++ b/arch/powerpc/kernel/proc_ppc64.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25 25
26#include <asm/machdep.h>
26#include <asm/vdso_datapage.h> 27#include <asm/vdso_datapage.h>
27#include <asm/rtas.h> 28#include <asm/rtas.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
@@ -51,7 +52,7 @@ static int __init proc_ppc64_create(void)
51 if (!root) 52 if (!root)
52 return 1; 53 return 1;
53 54
54 if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) 55 if (!machine_is(pseries) && !machine_is(cell))
55 return 0; 56 return 0;
56 57
57 if (!proc_mkdir("rtas", root)) 58 if (!proc_mkdir("rtas", root))
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c225cf154bfe..2dd47d2dd998 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/process.c
3 *
4 * Derived from "arch/i386/kernel/process.c" 2 * Derived from "arch/i386/kernel/process.c"
5 * Copyright (C) 1995 Linus Torvalds 3 * Copyright (C) 1995 Linus Torvalds
6 * 4 *
@@ -37,7 +35,6 @@
37#include <linux/mqueue.h> 35#include <linux/mqueue.h>
38#include <linux/hardirq.h> 36#include <linux/hardirq.h>
39#include <linux/utsname.h> 37#include <linux/utsname.h>
40#include <linux/kprobes.h>
41 38
42#include <asm/pgtable.h> 39#include <asm/pgtable.h>
43#include <asm/uaccess.h> 40#include <asm/uaccess.h>
@@ -47,9 +44,10 @@
47#include <asm/mmu.h> 44#include <asm/mmu.h>
48#include <asm/prom.h> 45#include <asm/prom.h>
49#include <asm/machdep.h> 46#include <asm/machdep.h>
47#include <asm/time.h>
48#include <asm/syscalls.h>
50#ifdef CONFIG_PPC64 49#ifdef CONFIG_PPC64
51#include <asm/firmware.h> 50#include <asm/firmware.h>
52#include <asm/time.h>
53#endif 51#endif
54 52
55extern unsigned long _get_SP(void); 53extern unsigned long _get_SP(void);
@@ -330,6 +328,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
330#endif 328#endif
331 329
332 local_irq_save(flags); 330 local_irq_save(flags);
331
332 account_system_vtime(current);
333 account_process_vtime(current);
334 calculate_steal_time();
335
333 last = _switch(old_thread, new_thread); 336 last = _switch(old_thread, new_thread);
334 337
335 local_irq_restore(flags); 338 local_irq_restore(flags);
@@ -360,7 +363,11 @@ static void show_instructions(struct pt_regs *regs)
360 if (!(i % 8)) 363 if (!(i % 8))
361 printk("\n"); 364 printk("\n");
362 365
363 if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) { 366 /* We use __get_user here *only* to avoid an OOPS on a
367 * bad address because the pc *should* only be a
368 * kernel address.
369 */
370 if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) {
364 printk("XXXXXXXX "); 371 printk("XXXXXXXX ");
365 } else { 372 } else {
366 if (regs->nip == pc) 373 if (regs->nip == pc)
@@ -457,7 +464,6 @@ void show_regs(struct pt_regs * regs)
457 464
458void exit_thread(void) 465void exit_thread(void)
459{ 466{
460 kprobe_flush_task(current);
461 discard_lazy_cpu_state(); 467 discard_lazy_cpu_state();
462} 468}
463 469
@@ -764,7 +770,7 @@ out:
764 return error; 770 return error;
765} 771}
766 772
767static int validate_sp(unsigned long sp, struct task_struct *p, 773int validate_sp(unsigned long sp, struct task_struct *p,
768 unsigned long nbytes) 774 unsigned long nbytes)
769{ 775{
770 unsigned long stack_page = (unsigned long)task_stack_page(p); 776 unsigned long stack_page = (unsigned long)task_stack_page(p);
@@ -802,6 +808,8 @@ static int validate_sp(unsigned long sp, struct task_struct *p,
802#define FRAME_MARKER 2 808#define FRAME_MARKER 2
803#endif 809#endif
804 810
811EXPORT_SYMBOL(validate_sp);
812
805unsigned long get_wchan(struct task_struct *p) 813unsigned long get_wchan(struct task_struct *p)
806{ 814{
807 unsigned long ip, sp; 815 unsigned long ip, sp;
@@ -826,7 +834,6 @@ unsigned long get_wchan(struct task_struct *p)
826 } while (count++ < 16); 834 } while (count++ < 16);
827 return 0; 835 return 0;
828} 836}
829EXPORT_SYMBOL(get_wchan);
830 837
831static int kstack_depth_to_print = 64; 838static int kstack_depth_to_print = 64;
832 839
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6dbd21726770..4336390bcf34 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np,
383 /* Apple uses bits in there in a different way, let's 383 /* Apple uses bits in there in a different way, let's
384 * only keep the real sense bit on macs 384 * only keep the real sense bit on macs
385 */ 385 */
386 if (_machine == PLATFORM_POWERMAC) 386 if (machine_is(powermac))
387 sense &= 0x1; 387 sense &= 0x1;
388 np->intrs[intrcount].sense = map_mpic_senses[sense]; 388 np->intrs[intrcount].sense = map_mpic_senses[sense];
389 } 389 }
390 390
391#ifdef CONFIG_PPC64 391#ifdef CONFIG_PPC64
392 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ 392 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
393 if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { 393 if (machine_is(powermac) && ic && ic->parent) {
394 char *name = get_property(ic->parent, "name", NULL); 394 char *name = get_property(ic->parent, "name", NULL);
395 if (name && !strcmp(name, "u3")) 395 if (name && !strcmp(name, "u3"))
396 np->intrs[intrcount].line += 128; 396 np->intrs[intrcount].line += 128;
@@ -570,6 +570,18 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
570 return rc; 570 return rc;
571} 571}
572 572
573unsigned long __init of_get_flat_dt_root(void)
574{
575 unsigned long p = ((unsigned long)initial_boot_params) +
576 initial_boot_params->off_dt_struct;
577
578 while(*((u32 *)p) == OF_DT_NOP)
579 p += 4;
580 BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE);
581 p += 4;
582 return _ALIGN(p + strlen((char *)p) + 1, 4);
583}
584
573/** 585/**
574 * This function can be used within scan_flattened_dt callback to get 586 * This function can be used within scan_flattened_dt callback to get
575 * access to properties 587 * access to properties
@@ -612,6 +624,25 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
612 } while(1); 624 } while(1);
613} 625}
614 626
627int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
628{
629 const char* cp;
630 unsigned long cplen, l;
631
632 cp = of_get_flat_dt_prop(node, "compatible", &cplen);
633 if (cp == NULL)
634 return 0;
635 while (cplen > 0) {
636 if (strncasecmp(cp, compat, strlen(compat)) == 0)
637 return 1;
638 l = strlen(cp) + 1;
639 cp += l;
640 cplen -= l;
641 }
642
643 return 0;
644}
645
615static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, 646static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
616 unsigned long align) 647 unsigned long align)
617{ 648{
@@ -686,7 +717,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
686#ifdef DEBUG 717#ifdef DEBUG
687 if ((strlen(p) + l + 1) != allocl) { 718 if ((strlen(p) + l + 1) != allocl) {
688 DBG("%s: p: %d, l: %d, a: %d\n", 719 DBG("%s: p: %d, l: %d, a: %d\n",
689 pathp, strlen(p), l, allocl); 720 pathp, (int)strlen(p), l, allocl);
690 } 721 }
691#endif 722#endif
692 p += strlen(p); 723 p += strlen(p);
@@ -829,10 +860,6 @@ void __init unflatten_device_tree(void)
829 860
830 /* Allocate memory for the expanded device tree */ 861 /* Allocate memory for the expanded device tree */
831 mem = lmb_alloc(size + 4, __alignof__(struct device_node)); 862 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
832 if (!mem) {
833 DBG("Couldn't allocate memory with lmb_alloc()!\n");
834 panic("Couldn't allocate memory with lmb_alloc()!\n");
835 }
836 mem = (unsigned long) __va(mem); 863 mem = (unsigned long) __va(mem);
837 864
838 ((u32 *)mem)[size / 4] = 0xdeadbeef; 865 ((u32 *)mem)[size / 4] = 0xdeadbeef;
@@ -858,35 +885,73 @@ void __init unflatten_device_tree(void)
858 DBG(" <- unflatten_device_tree()\n"); 885 DBG(" <- unflatten_device_tree()\n");
859} 886}
860 887
861
862static int __init early_init_dt_scan_cpus(unsigned long node, 888static int __init early_init_dt_scan_cpus(unsigned long node,
863 const char *uname, int depth, void *data) 889 const char *uname, int depth,
890 void *data)
864{ 891{
892 static int logical_cpuid = 0;
893 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
894#ifdef CONFIG_ALTIVEC
865 u32 *prop; 895 u32 *prop;
866 unsigned long size; 896#endif
867 char *type = of_get_flat_dt_prop(node, "device_type", &size); 897 u32 *intserv;
898 int i, nthreads;
899 unsigned long len;
900 int found = 0;
868 901
869 /* We are scanning "cpu" nodes only */ 902 /* We are scanning "cpu" nodes only */
870 if (type == NULL || strcmp(type, "cpu") != 0) 903 if (type == NULL || strcmp(type, "cpu") != 0)
871 return 0; 904 return 0;
872 905
873 boot_cpuid = 0; 906 /* Get physical cpuid */
874 boot_cpuid_phys = 0; 907 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
875 if (initial_boot_params && initial_boot_params->version >= 2) { 908 if (intserv) {
876 /* version 2 of the kexec param format adds the phys cpuid 909 nthreads = len / sizeof(int);
877 * of booted proc.
878 */
879 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
880 } else { 910 } else {
881 /* Check if it's the boot-cpu, set it's hw index now */ 911 intserv = of_get_flat_dt_prop(node, "reg", NULL);
882 if (of_get_flat_dt_prop(node, 912 nthreads = 1;
913 }
914
915 /*
916 * Now see if any of these threads match our boot cpu.
917 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
918 */
919 for (i = 0; i < nthreads; i++) {
920 /*
921 * version 2 of the kexec param format adds the phys cpuid of
922 * booted proc.
923 */
924 if (initial_boot_params && initial_boot_params->version >= 2) {
925 if (intserv[i] ==
926 initial_boot_params->boot_cpuid_phys) {
927 found = 1;
928 break;
929 }
930 } else {
931 /*
932 * Check if it's the boot-cpu, set it's hw index now,
933 * unfortunately this format did not support booting
934 * off secondary threads.
935 */
936 if (of_get_flat_dt_prop(node,
883 "linux,boot-cpu", NULL) != NULL) { 937 "linux,boot-cpu", NULL) != NULL) {
884 prop = of_get_flat_dt_prop(node, "reg", NULL); 938 found = 1;
885 if (prop != NULL) 939 break;
886 boot_cpuid_phys = *prop; 940 }
887 } 941 }
942
943#ifdef CONFIG_SMP
944 /* logical cpu id is always 0 on UP kernels */
945 logical_cpuid++;
946#endif
947 }
948
949 if (found) {
950 DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
951 intserv[i]);
952 boot_cpuid = logical_cpuid;
953 set_hard_smp_processor_id(boot_cpuid, intserv[i]);
888 } 954 }
889 set_hard_smp_processor_id(0, boot_cpuid_phys);
890 955
891#ifdef CONFIG_ALTIVEC 956#ifdef CONFIG_ALTIVEC
892 /* Check if we have a VMX and eventually update CPU features */ 957 /* Check if we have a VMX and eventually update CPU features */
@@ -905,16 +970,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
905#endif /* CONFIG_ALTIVEC */ 970#endif /* CONFIG_ALTIVEC */
906 971
907#ifdef CONFIG_PPC_PSERIES 972#ifdef CONFIG_PPC_PSERIES
908 /* 973 if (nthreads > 1)
909 * Check for an SMT capable CPU and set the CPU feature. We do
910 * this by looking at the size of the ibm,ppc-interrupt-server#s
911 * property
912 */
913 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
914 &size);
915 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
916 if (prop && ((size / sizeof(u32)) > 1))
917 cur_cpu_spec->cpu_features |= CPU_FTR_SMT; 974 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
975 else
976 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
918#endif 977#endif
919 978
920 return 0; 979 return 0;
@@ -923,7 +982,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
923static int __init early_init_dt_scan_chosen(unsigned long node, 982static int __init early_init_dt_scan_chosen(unsigned long node,
924 const char *uname, int depth, void *data) 983 const char *uname, int depth, void *data)
925{ 984{
926 u32 *prop;
927 unsigned long *lprop; 985 unsigned long *lprop;
928 unsigned long l; 986 unsigned long l;
929 char *p; 987 char *p;
@@ -934,14 +992,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
934 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) 992 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
935 return 0; 993 return 0;
936 994
937 /* get platform type */
938 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
939 if (prop == NULL)
940 return 0;
941#ifdef CONFIG_PPC_MULTIPLATFORM
942 _machine = *prop;
943#endif
944
945#ifdef CONFIG_PPC64 995#ifdef CONFIG_PPC64
946 /* check if iommu is forced on or off */ 996 /* check if iommu is forced on or off */
947 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) 997 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -968,15 +1018,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
968 * set of RTAS infos now if available 1018 * set of RTAS infos now if available
969 */ 1019 */
970 { 1020 {
971 u64 *basep, *entryp; 1021 u64 *basep, *entryp, *sizep;
972 1022
973 basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); 1023 basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
974 entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); 1024 entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
975 prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); 1025 sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
976 if (basep && entryp && prop) { 1026 if (basep && entryp && sizep) {
977 rtas.base = *basep; 1027 rtas.base = *basep;
978 rtas.entry = *entryp; 1028 rtas.entry = *entryp;
979 rtas.size = *prop; 1029 rtas.size = *sizep;
980 } 1030 }
981 } 1031 }
982#endif /* CONFIG_PPC_RTAS */ 1032#endif /* CONFIG_PPC_RTAS */
@@ -1005,25 +1055,13 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1005 1055
1006 if (strstr(cmd_line, "mem=")) { 1056 if (strstr(cmd_line, "mem=")) {
1007 char *p, *q; 1057 char *p, *q;
1008 unsigned long maxmem = 0;
1009 1058
1010 for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { 1059 for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
1011 q = p + 4; 1060 q = p + 4;
1012 if (p > cmd_line && p[-1] != ' ') 1061 if (p > cmd_line && p[-1] != ' ')
1013 continue; 1062 continue;
1014 maxmem = simple_strtoul(q, &q, 0); 1063 memory_limit = memparse(q, &q);
1015 if (*q == 'k' || *q == 'K') {
1016 maxmem <<= 10;
1017 ++q;
1018 } else if (*q == 'm' || *q == 'M') {
1019 maxmem <<= 20;
1020 ++q;
1021 } else if (*q == 'g' || *q == 'G') {
1022 maxmem <<= 30;
1023 ++q;
1024 }
1025 } 1064 }
1026 memory_limit = maxmem;
1027 } 1065 }
1028 1066
1029 /* break now */ 1067 /* break now */
@@ -1759,7 +1797,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1759 /* We don't support that function on PowerMac, at least 1797 /* We don't support that function on PowerMac, at least
1760 * not yet 1798 * not yet
1761 */ 1799 */
1762 if (_machine == PLATFORM_POWERMAC) 1800 if (machine_is(powermac))
1763 return -ENODEV; 1801 return -ENODEV;
1764 1802
1765 /* fix up new node's linux_phandle field */ 1803 /* fix up new node's linux_phandle field */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 813c2cd194c2..d66c5e77fcff 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -180,6 +180,16 @@ static unsigned long __initdata prom_tce_alloc_start;
180static unsigned long __initdata prom_tce_alloc_end; 180static unsigned long __initdata prom_tce_alloc_end;
181#endif 181#endif
182 182
183/* Platforms codes are now obsolete in the kernel. Now only used within this
184 * file and ultimately gone too. Feel free to change them if you need, they
185 * are not shared with anything outside of this file anymore
186 */
187#define PLATFORM_PSERIES 0x0100
188#define PLATFORM_PSERIES_LPAR 0x0101
189#define PLATFORM_LPAR 0x0001
190#define PLATFORM_POWERMAC 0x0400
191#define PLATFORM_GENERIC 0x0500
192
183static int __initdata of_platform; 193static int __initdata of_platform;
184 194
185static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; 195static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
@@ -397,6 +407,11 @@ static void __init __attribute__((noreturn)) prom_panic(const char *reason)
397 reason = PTRRELOC(reason); 407 reason = PTRRELOC(reason);
398#endif 408#endif
399 prom_print(reason); 409 prom_print(reason);
410 /* Do not call exit because it clears the screen on pmac
411 * it also causes some sort of double-fault on early pmacs */
412 if (RELOC(of_platform) == PLATFORM_POWERMAC)
413 asm("trap\n");
414
400 /* ToDo: should put up an SRC here on p/iSeries */ 415 /* ToDo: should put up an SRC here on p/iSeries */
401 call_prom("exit", 0, 0); 416 call_prom("exit", 0, 0);
402 417
@@ -1487,7 +1502,10 @@ static int __init prom_find_machine_type(void)
1487 int len, i = 0; 1502 int len, i = 0;
1488#ifdef CONFIG_PPC64 1503#ifdef CONFIG_PPC64
1489 phandle rtas; 1504 phandle rtas;
1505 int x;
1490#endif 1506#endif
1507
1508 /* Look for a PowerMac */
1491 len = prom_getprop(_prom->root, "compatible", 1509 len = prom_getprop(_prom->root, "compatible",
1492 compat, sizeof(compat)-1); 1510 compat, sizeof(compat)-1);
1493 if (len > 0) { 1511 if (len > 0) {
@@ -1500,28 +1518,36 @@ static int __init prom_find_machine_type(void)
1500 if (strstr(p, RELOC("Power Macintosh")) || 1518 if (strstr(p, RELOC("Power Macintosh")) ||
1501 strstr(p, RELOC("MacRISC"))) 1519 strstr(p, RELOC("MacRISC")))
1502 return PLATFORM_POWERMAC; 1520 return PLATFORM_POWERMAC;
1503#ifdef CONFIG_PPC64
1504 if (strstr(p, RELOC("Momentum,Maple")))
1505 return PLATFORM_MAPLE;
1506 if (strstr(p, RELOC("IBM,CPB")))
1507 return PLATFORM_CELL;
1508#endif
1509 i += sl + 1; 1521 i += sl + 1;
1510 } 1522 }
1511 } 1523 }
1512#ifdef CONFIG_PPC64 1524#ifdef CONFIG_PPC64
1525 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1526 * PAPR compliant platform. We assume it is if :
1527 * - /device_type is "chrp" (please, do NOT use that for future
1528 * non-IBM designs !
1529 * - it has /rtas
1530 */
1531 len = prom_getprop(_prom->root, "model",
1532 compat, sizeof(compat)-1);
1533 if (len <= 0)
1534 return PLATFORM_GENERIC;
1535 compat[len] = 0;
1536 if (strcmp(compat, "chrp"))
1537 return PLATFORM_GENERIC;
1538
1513 /* Default to pSeries. We need to know if we are running LPAR */ 1539 /* Default to pSeries. We need to know if we are running LPAR */
1514 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); 1540 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1515 if (PHANDLE_VALID(rtas)) { 1541 if (!PHANDLE_VALID(rtas))
1516 int x = prom_getproplen(rtas, "ibm,hypertas-functions"); 1542 return PLATFORM_GENERIC;
1517 if (x != PROM_ERROR) { 1543 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1518 prom_printf("Hypertas detected, assuming LPAR !\n"); 1544 if (x != PROM_ERROR) {
1519 return PLATFORM_PSERIES_LPAR; 1545 prom_printf("Hypertas detected, assuming LPAR !\n");
1520 } 1546 return PLATFORM_PSERIES_LPAR;
1521 } 1547 }
1522 return PLATFORM_PSERIES; 1548 return PLATFORM_PSERIES;
1523#else 1549#else
1524 return PLATFORM_CHRP; 1550 return PLATFORM_GENERIC;
1525#endif 1551#endif
1526} 1552}
1527 1553
@@ -2029,7 +2055,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2029{ 2055{
2030 struct prom_t *_prom; 2056 struct prom_t *_prom;
2031 unsigned long hdr; 2057 unsigned long hdr;
2032 u32 getprop_rval;
2033 unsigned long offset = reloc_offset(); 2058 unsigned long offset = reloc_offset();
2034 2059
2035#ifdef CONFIG_PPC32 2060#ifdef CONFIG_PPC32
@@ -2060,6 +2085,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2060 */ 2085 */
2061 prom_init_stdout(); 2086 prom_init_stdout();
2062 2087
2088 /*
2089 * Get default machine type. At this point, we do not differentiate
2090 * between pSeries SMP and pSeries LPAR
2091 */
2092 RELOC(of_platform) = prom_find_machine_type();
2093
2063 /* Bail if this is a kdump kernel. */ 2094 /* Bail if this is a kdump kernel. */
2064 if (PHYSICAL_START > 0) 2095 if (PHYSICAL_START > 0)
2065 prom_panic("Error: You can't boot a kdump kernel from OF!\n"); 2096 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
@@ -2069,15 +2100,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2069 */ 2100 */
2070 prom_check_initrd(r3, r4); 2101 prom_check_initrd(r3, r4);
2071 2102
2072 /*
2073 * Get default machine type. At this point, we do not differentiate
2074 * between pSeries SMP and pSeries LPAR
2075 */
2076 RELOC(of_platform) = prom_find_machine_type();
2077 getprop_rval = RELOC(of_platform);
2078 prom_setprop(_prom->chosen, "/chosen", "linux,platform",
2079 &getprop_rval, sizeof(getprop_rval));
2080
2081#ifdef CONFIG_PPC_PSERIES 2103#ifdef CONFIG_PPC_PSERIES
2082 /* 2104 /*
2083 * On pSeries, inform the firmware about our capabilities 2105 * On pSeries, inform the firmware about our capabilities
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index 5ccbdbe0d5c9..c42a860c8d25 100644
--- a/arch/powerpc/kernel/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/ptrace-common.h
3 *
4 * Copyright (c) 2002 Stephen Rothwell, IBM Coproration 2 * Copyright (c) 2002 Stephen Rothwell, IBM Coproration
5 * Extracted from ptrace.c and ptrace32.c 3 * Extracted from ptrace.c and ptrace32.c
6 * 4 *
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 7a95b8a28354..456286cf1d14 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/rtas-proc.c
3 * Copyright (C) 2000 Tilmann Bitterberg 2 * Copyright (C) 2000 Tilmann Bitterberg
4 * (tilmann@bitterberg.de) 3 * (tilmann@bitterberg.de)
5 * 4 *
@@ -258,7 +257,7 @@ static int __init proc_rtas_init(void)
258{ 257{
259 struct proc_dir_entry *entry; 258 struct proc_dir_entry *entry;
260 259
261 if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) 260 if (!machine_is(pseries))
262 return 1; 261 return 1;
263 262
264 rtas_node = of_find_node_by_name(NULL, "rtas"); 263 rtas_node = of_find_node_by_name(NULL, "rtas");
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
index 635d3b9a8811..34d073fb6091 100644
--- a/arch/powerpc/kernel/rtas-rtc.c
+++ b/arch/powerpc/kernel/rtas-rtc.c
@@ -52,7 +52,7 @@ void rtas_get_rtc_time(struct rtc_time *rtc_tm)
52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { 53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
54 if (in_interrupt() && printk_ratelimit()) { 54 if (in_interrupt() && printk_ratelimit()) {
55 memset(&rtc_tm, 0, sizeof(struct rtc_time)); 55 memset(rtc_tm, 0, sizeof(struct rtc_time));
56 printk(KERN_WARNING "error: reading clock" 56 printk(KERN_WARNING "error: reading clock"
57 " would delay interrupt\n"); 57 " would delay interrupt\n");
58 return; /* delay not allowed */ 58 return; /* delay not allowed */
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index b5b2add7ad1e..06636c927a7e 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -25,6 +25,7 @@
25#include <asm/hvcall.h> 25#include <asm/hvcall.h>
26#include <asm/semaphore.h> 26#include <asm/semaphore.h>
27#include <asm/machdep.h> 27#include <asm/machdep.h>
28#include <asm/firmware.h>
28#include <asm/page.h> 29#include <asm/page.h>
29#include <asm/param.h> 30#include <asm/param.h>
30#include <asm/system.h> 31#include <asm/system.h>
@@ -32,6 +33,7 @@
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/lmb.h> 34#include <asm/lmb.h>
34#include <asm/udbg.h> 35#include <asm/udbg.h>
36#include <asm/syscalls.h>
35 37
36struct rtas_t rtas = { 38struct rtas_t rtas = {
37 .lock = SPIN_LOCK_UNLOCKED 39 .lock = SPIN_LOCK_UNLOCKED
@@ -591,7 +593,7 @@ static void rtas_percpu_suspend_me(void *info)
591 data->waiting = 0; 593 data->waiting = 0;
592 data->args->args[data->args->nargs] = 594 data->args->args[data->args->nargs] =
593 rtas_call(ibm_suspend_me_token, 0, 1, NULL); 595 rtas_call(ibm_suspend_me_token, 0, 1, NULL);
594 for_each_cpu(i) 596 for_each_possible_cpu(i)
595 plpar_hcall_norets(H_PROD,i); 597 plpar_hcall_norets(H_PROD,i);
596 } else { 598 } else {
597 data->waiting = -EBUSY; 599 data->waiting = -EBUSY;
@@ -624,7 +626,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
624 /* Prod each CPU. This won't hurt, and will wake 626 /* Prod each CPU. This won't hurt, and will wake
625 * anyone we successfully put to sleep with H_Join 627 * anyone we successfully put to sleep with H_Join
626 */ 628 */
627 for_each_cpu(i) 629 for_each_possible_cpu(i)
628 plpar_hcall_norets(H_PROD, i); 630 plpar_hcall_norets(H_PROD, i);
629 631
630 return data.waiting; 632 return data.waiting;
@@ -767,7 +769,7 @@ void __init rtas_initialize(void)
767 * the stop-self token if any 769 * the stop-self token if any
768 */ 770 */
769#ifdef CONFIG_PPC64 771#ifdef CONFIG_PPC64
770 if (_machine == PLATFORM_PSERIES_LPAR) { 772 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
771 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); 773 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
772 ibm_suspend_me_token = rtas_token("ibm,suspend-me"); 774 ibm_suspend_me_token = rtas_token("ibm,suspend-me");
773 } 775 }
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 5579f6559912..57b539a03fa9 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/rtas_pci.c
3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 4 *
@@ -280,8 +278,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
280 return 0; 278 return 0;
281} 279}
282 280
283static int __devinit setup_phb(struct device_node *dev, 281int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
284 struct pci_controller *phb)
285{ 282{
286 if (is_python(dev)) 283 if (is_python(dev))
287 python_countermeasures(dev); 284 python_countermeasures(dev);
@@ -359,27 +356,6 @@ unsigned long __init find_and_init_phbs(void)
359 return 0; 356 return 0;
360} 357}
361 358
362struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
363{
364 struct pci_controller *phb;
365 int primary;
366
367 primary = list_empty(&hose_list);
368 phb = pcibios_alloc_controller(dn);
369 if (!phb)
370 return NULL;
371 setup_phb(dn, phb);
372 pci_process_bridge_OF_ranges(phb, dn, primary);
373
374 pci_setup_phb_io_dynamic(phb, primary);
375
376 pci_devs_phb_init_dynamic(phb);
377 scan_phb(phb);
378
379 return phb;
380}
381EXPORT_SYMBOL(init_phb_dynamic);
382
383/* RPA-specific bits for removing PHBs */ 359/* RPA-specific bits for removing PHBs */
384int pcibios_remove_root_bus(struct pci_controller *phb) 360int pcibios_remove_root_bus(struct pci_controller *phb)
385{ 361{
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index fc89d009d18d..1d93e73a7003 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -9,6 +9,9 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12
13#undef DEBUG
14
12#include <linux/config.h> 15#include <linux/config.h>
13#include <linux/module.h> 16#include <linux/module.h>
14#include <linux/string.h> 17#include <linux/string.h>
@@ -42,6 +45,7 @@
42#include <asm/time.h> 45#include <asm/time.h>
43#include <asm/cputable.h> 46#include <asm/cputable.h>
44#include <asm/sections.h> 47#include <asm/sections.h>
48#include <asm/firmware.h>
45#include <asm/btext.h> 49#include <asm/btext.h>
46#include <asm/nvram.h> 50#include <asm/nvram.h>
47#include <asm/setup.h> 51#include <asm/setup.h>
@@ -57,8 +61,6 @@
57 61
58#include "setup.h" 62#include "setup.h"
59 63
60#undef DEBUG
61
62#ifdef DEBUG 64#ifdef DEBUG
63#include <asm/udbg.h> 65#include <asm/udbg.h>
64#define DBG(fmt...) udbg_printf(fmt) 66#define DBG(fmt...) udbg_printf(fmt)
@@ -66,10 +68,12 @@
66#define DBG(fmt...) 68#define DBG(fmt...)
67#endif 69#endif
68 70
69#ifdef CONFIG_PPC_MULTIPLATFORM 71/* The main machine-dep calls structure
70int _machine = 0; 72 */
71EXPORT_SYMBOL(_machine); 73struct machdep_calls ppc_md;
72#endif 74EXPORT_SYMBOL(ppc_md);
75struct machdep_calls *machine_id;
76EXPORT_SYMBOL(machine_id);
73 77
74unsigned long klimit = (unsigned long) _end; 78unsigned long klimit = (unsigned long) _end;
75 79
@@ -163,14 +167,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
163#if defined(CONFIG_SMP) && defined(CONFIG_PPC32) 167#if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
164 unsigned long bogosum = 0; 168 unsigned long bogosum = 0;
165 int i; 169 int i;
166 for (i = 0; i < NR_CPUS; ++i) 170 for_each_online_cpu(i)
167 if (cpu_online(i)) 171 bogosum += loops_per_jiffy;
168 bogosum += loops_per_jiffy;
169 seq_printf(m, "total bogomips\t: %lu.%02lu\n", 172 seq_printf(m, "total bogomips\t: %lu.%02lu\n",
170 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); 173 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
171#endif /* CONFIG_SMP && CONFIG_PPC32 */ 174#endif /* CONFIG_SMP && CONFIG_PPC32 */
172 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); 175 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
173 176 if (ppc_md.name)
177 seq_printf(m, "platform\t: %s\n", ppc_md.name);
174 if (ppc_md.show_cpuinfo != NULL) 178 if (ppc_md.show_cpuinfo != NULL)
175 ppc_md.show_cpuinfo(m); 179 ppc_md.show_cpuinfo(m);
176 180
@@ -354,12 +358,13 @@ void __init check_for_initrd(void)
354 * must be called before using this. 358 * must be called before using this.
355 * 359 *
356 * While we're here, we may as well set the "physical" cpu ids in the paca. 360 * While we're here, we may as well set the "physical" cpu ids in the paca.
361 *
362 * NOTE: This must match the parsing done in early_init_dt_scan_cpus.
357 */ 363 */
358void __init smp_setup_cpu_maps(void) 364void __init smp_setup_cpu_maps(void)
359{ 365{
360 struct device_node *dn = NULL; 366 struct device_node *dn = NULL;
361 int cpu = 0; 367 int cpu = 0;
362 int swap_cpuid = 0;
363 368
364 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 369 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
365 int *intserv; 370 int *intserv;
@@ -378,30 +383,17 @@ void __init smp_setup_cpu_maps(void)
378 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { 383 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
379 cpu_set(cpu, cpu_present_map); 384 cpu_set(cpu, cpu_present_map);
380 set_hard_smp_processor_id(cpu, intserv[j]); 385 set_hard_smp_processor_id(cpu, intserv[j]);
381
382 if (intserv[j] == boot_cpuid_phys)
383 swap_cpuid = cpu;
384 cpu_set(cpu, cpu_possible_map); 386 cpu_set(cpu, cpu_possible_map);
385 cpu++; 387 cpu++;
386 } 388 }
387 } 389 }
388 390
389 /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
390 * boot cpu is logical 0.
391 */
392 if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
393 u32 tmp;
394 tmp = get_hard_smp_processor_id(0);
395 set_hard_smp_processor_id(0, boot_cpuid_phys);
396 set_hard_smp_processor_id(swap_cpuid, tmp);
397 }
398
399#ifdef CONFIG_PPC64 391#ifdef CONFIG_PPC64
400 /* 392 /*
401 * On pSeries LPAR, we need to know how many cpus 393 * On pSeries LPAR, we need to know how many cpus
402 * could possibly be added to this partition. 394 * could possibly be added to this partition.
403 */ 395 */
404 if (_machine == PLATFORM_PSERIES_LPAR && 396 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
405 (dn = of_find_node_by_path("/rtas"))) { 397 (dn = of_find_node_by_path("/rtas"))) {
406 int num_addr_cell, num_size_cell, maxcpus; 398 int num_addr_cell, num_size_cell, maxcpus;
407 unsigned int *ireg; 399 unsigned int *ireg;
@@ -440,7 +432,7 @@ void __init smp_setup_cpu_maps(void)
440 /* 432 /*
441 * Do the sibling map; assume only two threads per processor. 433 * Do the sibling map; assume only two threads per processor.
442 */ 434 */
443 for_each_cpu(cpu) { 435 for_each_possible_cpu(cpu) {
444 cpu_set(cpu, cpu_sibling_map[cpu]); 436 cpu_set(cpu, cpu_sibling_map[cpu]);
445 if (cpu_has_feature(CPU_FTR_SMT)) 437 if (cpu_has_feature(CPU_FTR_SMT))
446 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); 438 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
@@ -493,3 +485,34 @@ static __init int add_pcspkr(void)
493 return ret; 485 return ret;
494} 486}
495device_initcall(add_pcspkr); 487device_initcall(add_pcspkr);
488
489void probe_machine(void)
490{
491 extern struct machdep_calls __machine_desc_start;
492 extern struct machdep_calls __machine_desc_end;
493
494 /*
495 * Iterate all ppc_md structures until we find the proper
496 * one for the current machine type
497 */
498 DBG("Probing machine type ...\n");
499
500 for (machine_id = &__machine_desc_start;
501 machine_id < &__machine_desc_end;
502 machine_id++) {
503 DBG(" %s ...", machine_id->name);
504 memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
505 if (ppc_md.probe()) {
506 DBG(" match !\n");
507 break;
508 }
509 DBG("\n");
510 }
511 /* What can we do if we didn't find ? */
512 if (machine_id >= &__machine_desc_end) {
513 DBG("No suitable machine found !\n");
514 for (;;);
515 }
516
517 printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
518}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index db72a92943bf..a72bf5dceeee 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -53,9 +53,6 @@
53extern void platform_init(void); 53extern void platform_init(void);
54extern void bootx_init(unsigned long r4, unsigned long phys); 54extern void bootx_init(unsigned long r4, unsigned long phys);
55 55
56extern void ppc6xx_idle(void);
57extern void power4_idle(void);
58
59boot_infos_t *boot_infos; 56boot_infos_t *boot_infos;
60struct ide_machdep_calls ppc_ide_md; 57struct ide_machdep_calls ppc_ide_md;
61 58
@@ -70,10 +67,6 @@ unsigned int DMA_MODE_WRITE;
70int have_of = 1; 67int have_of = 1;
71 68
72#ifdef CONFIG_PPC_MULTIPLATFORM 69#ifdef CONFIG_PPC_MULTIPLATFORM
73extern void prep_init(void);
74extern void pmac_init(void);
75extern void chrp_init(void);
76
77dev_t boot_dev; 70dev_t boot_dev;
78#endif /* CONFIG_PPC_MULTIPLATFORM */ 71#endif /* CONFIG_PPC_MULTIPLATFORM */
79 72
@@ -85,9 +78,6 @@ unsigned long SYSRQ_KEY = 0x54;
85unsigned long vgacon_remap_base; 78unsigned long vgacon_remap_base;
86#endif 79#endif
87 80
88struct machdep_calls ppc_md;
89EXPORT_SYMBOL(ppc_md);
90
91/* 81/*
92 * These are used in binfmt_elf.c to put aux entries on the stack 82 * These are used in binfmt_elf.c to put aux entries on the stack
93 * for each elf executable being started. 83 * for each elf executable being started.
@@ -111,7 +101,7 @@ unsigned long __init early_init(unsigned long dt_ptr)
111 101
112 /* First zero the BSS -- use memset_io, some platforms don't have 102 /* First zero the BSS -- use memset_io, some platforms don't have
113 * caches on yet */ 103 * caches on yet */
114 memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); 104 memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, _end - __bss_start);
115 105
116 /* 106 /*
117 * Identify the CPU type and fix up code sections 107 * Identify the CPU type and fix up code sections
@@ -123,48 +113,6 @@ unsigned long __init early_init(unsigned long dt_ptr)
123 return KERNELBASE + offset; 113 return KERNELBASE + offset;
124} 114}
125 115
126#ifdef CONFIG_PPC_MULTIPLATFORM
127/*
128 * The PPC_MULTIPLATFORM version of platform_init...
129 */
130void __init platform_init(void)
131{
132 /* if we didn't get any bootinfo telling us what we are... */
133 if (_machine == 0) {
134 /* prep boot loader tells us if we're prep or not */
135 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
136 _machine = _MACH_prep;
137 }
138
139#ifdef CONFIG_PPC_PREP
140 /* not much more to do here, if prep */
141 if (_machine == _MACH_prep) {
142 prep_init();
143 return;
144 }
145#endif
146
147#ifdef CONFIG_ADB
148 if (strstr(cmd_line, "adb_sync")) {
149 extern int __adb_probe_sync;
150 __adb_probe_sync = 1;
151 }
152#endif /* CONFIG_ADB */
153
154 switch (_machine) {
155#ifdef CONFIG_PPC_PMAC
156 case _MACH_Pmac:
157 pmac_init();
158 break;
159#endif
160#ifdef CONFIG_PPC_CHRP
161 case _MACH_chrp:
162 chrp_init();
163 break;
164#endif
165 }
166}
167#endif
168 116
169/* 117/*
170 * Find out what kind of machine we're on and save any data we need 118 * Find out what kind of machine we're on and save any data we need
@@ -190,11 +138,17 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
190 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 138 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
191#endif /* CONFIG_CMDLINE */ 139#endif /* CONFIG_CMDLINE */
192 140
193 /* Base init based on machine type */ 141#ifdef CONFIG_PPC_MULTIPLATFORM
142 probe_machine();
143#else
144 /* Base init based on machine type. Obsoloete, please kill ! */
194 platform_init(); 145 platform_init();
146#endif
195 147
196#ifdef CONFIG_6xx 148#ifdef CONFIG_6xx
197 ppc_md.power_save = ppc6xx_idle; 149 if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
150 cpu_has_feature(CPU_FTR_CAN_NAP))
151 ppc_md.power_save = ppc6xx_idle;
198#endif 152#endif
199 153
200 if (ppc_md.progress) 154 if (ppc_md.progress)
@@ -272,9 +226,8 @@ int __init ppc_init(void)
272 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 226 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
273 227
274 /* register CPU devices */ 228 /* register CPU devices */
275 for (i = 0; i < NR_CPUS; i++) 229 for_each_possible_cpu(i)
276 if (cpu_possible(i)) 230 register_cpu(&cpu_devices[i], i, NULL);
277 register_cpu(&cpu_devices[i], i, NULL);
278 231
279 /* call platform init */ 232 /* call platform init */
280 if (ppc_md.init != NULL) { 233 if (ppc_md.init != NULL) {
@@ -353,12 +306,6 @@ void __init setup_arch(char **cmdline_p)
353 do_init_bootmem(); 306 do_init_bootmem();
354 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 307 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
355 308
356#ifdef CONFIG_PPC_OCP
357 /* Initialize OCP device list */
358 ocp_early_init();
359 if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
360#endif
361
362#ifdef CONFIG_DUMMY_CONSOLE 309#ifdef CONFIG_DUMMY_CONSOLE
363 conswitchp = &dummy_con; 310 conswitchp = &dummy_con;
364#endif 311#endif
@@ -367,7 +314,4 @@ void __init setup_arch(char **cmdline_p)
367 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 314 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
368 315
369 paging_init(); 316 paging_init();
370
371 /* this is for modules since _machine can be a define -- Cort */
372 ppc_md.ppc_machine = _machine;
373} 317}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index f96c49b03ba0..59aa92cd6fa4 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -73,7 +73,6 @@
73 73
74int have_of = 1; 74int have_of = 1;
75int boot_cpuid = 0; 75int boot_cpuid = 0;
76int boot_cpuid_phys = 0;
77dev_t boot_dev; 76dev_t boot_dev;
78u64 ppc64_pft_size; 77u64 ppc64_pft_size;
79 78
@@ -96,11 +95,6 @@ int dcache_bsize;
96int icache_bsize; 95int icache_bsize;
97int ucache_bsize; 96int ucache_bsize;
98 97
99/* The main machine-dep calls structure
100 */
101struct machdep_calls ppc_md;
102EXPORT_SYMBOL(ppc_md);
103
104#ifdef CONFIG_MAGIC_SYSRQ 98#ifdef CONFIG_MAGIC_SYSRQ
105unsigned long SYSRQ_KEY; 99unsigned long SYSRQ_KEY;
106#endif /* CONFIG_MAGIC_SYSRQ */ 100#endif /* CONFIG_MAGIC_SYSRQ */
@@ -161,32 +155,6 @@ early_param("smt-enabled", early_smt_enabled);
161#define check_smt_enabled() 155#define check_smt_enabled()
162#endif /* CONFIG_SMP */ 156#endif /* CONFIG_SMP */
163 157
164extern struct machdep_calls pSeries_md;
165extern struct machdep_calls pmac_md;
166extern struct machdep_calls maple_md;
167extern struct machdep_calls cell_md;
168extern struct machdep_calls iseries_md;
169
170/* Ultimately, stuff them in an elf section like initcalls... */
171static struct machdep_calls __initdata *machines[] = {
172#ifdef CONFIG_PPC_PSERIES
173 &pSeries_md,
174#endif /* CONFIG_PPC_PSERIES */
175#ifdef CONFIG_PPC_PMAC
176 &pmac_md,
177#endif /* CONFIG_PPC_PMAC */
178#ifdef CONFIG_PPC_MAPLE
179 &maple_md,
180#endif /* CONFIG_PPC_MAPLE */
181#ifdef CONFIG_PPC_CELL
182 &cell_md,
183#endif
184#ifdef CONFIG_PPC_ISERIES
185 &iseries_md,
186#endif
187 NULL
188};
189
190/* 158/*
191 * Early initialization entry point. This is called by head.S 159 * Early initialization entry point. This is called by head.S
192 * with MMU translation disabled. We rely on the "feature" of 160 * with MMU translation disabled. We rely on the "feature" of
@@ -208,13 +176,10 @@ static struct machdep_calls __initdata *machines[] = {
208 176
209void __init early_setup(unsigned long dt_ptr) 177void __init early_setup(unsigned long dt_ptr)
210{ 178{
211 struct paca_struct *lpaca = get_paca();
212 static struct machdep_calls **mach;
213
214 /* Enable early debugging if any specified (see udbg.h) */ 179 /* Enable early debugging if any specified (see udbg.h) */
215 udbg_early_init(); 180 udbg_early_init();
216 181
217 DBG(" -> early_setup()\n"); 182 DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
218 183
219 /* 184 /*
220 * Do early initializations using the flattened device 185 * Do early initializations using the flattened device
@@ -223,22 +188,16 @@ void __init early_setup(unsigned long dt_ptr)
223 */ 188 */
224 early_init_devtree(__va(dt_ptr)); 189 early_init_devtree(__va(dt_ptr));
225 190
226 /* 191 /* Now we know the logical id of our boot cpu, setup the paca. */
227 * Iterate all ppc_md structures until we find the proper 192 setup_boot_paca();
228 * one for the current machine type
229 */
230 DBG("Probing machine type for platform %x...\n", _machine);
231 193
232 for (mach = machines; *mach; mach++) { 194 /* Fix up paca fields required for the boot cpu */
233 if ((*mach)->probe(_machine)) 195 get_paca()->cpu_start = 1;
234 break; 196 get_paca()->stab_real = __pa((u64)&initial_stab);
235 } 197 get_paca()->stab_addr = (u64)&initial_stab;
236 /* What can we do if we didn't find ? */ 198
237 if (*mach == NULL) { 199 /* Probe the machine type */
238 DBG("No suitable machine found !\n"); 200 probe_machine();
239 for (;;);
240 }
241 ppc_md = **mach;
242 201
243#ifdef CONFIG_CRASH_DUMP 202#ifdef CONFIG_CRASH_DUMP
244 kdump_setup(); 203 kdump_setup();
@@ -260,7 +219,7 @@ void __init early_setup(unsigned long dt_ptr)
260 if (cpu_has_feature(CPU_FTR_SLB)) 219 if (cpu_has_feature(CPU_FTR_SLB))
261 slb_initialize(); 220 slb_initialize();
262 else 221 else
263 stab_initialize(lpaca->stab_real); 222 stab_initialize(get_paca()->stab_real);
264 } 223 }
265 224
266 DBG(" <- early_setup()\n"); 225 DBG(" <- early_setup()\n");
@@ -340,7 +299,7 @@ static void __init initialize_cache_info(void)
340 const char *dc, *ic; 299 const char *dc, *ic;
341 300
342 /* Then read cache informations */ 301 /* Then read cache informations */
343 if (_machine == PLATFORM_POWERMAC) { 302 if (machine_is(powermac)) {
344 dc = "d-cache-block-size"; 303 dc = "d-cache-block-size";
345 ic = "i-cache-block-size"; 304 ic = "i-cache-block-size";
346 } else { 305 } else {
@@ -484,7 +443,6 @@ void __init setup_system(void)
484 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); 443 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
485 printk("ppc64_interrupt_controller = 0x%ld\n", 444 printk("ppc64_interrupt_controller = 0x%ld\n",
486 ppc64_interrupt_controller); 445 ppc64_interrupt_controller);
487 printk("platform = 0x%x\n", _machine);
488 printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); 446 printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
489 printk("ppc64_caches.dcache_line_size = 0x%x\n", 447 printk("ppc64_caches.dcache_line_size = 0x%x\n",
490 ppc64_caches.dline_size); 448 ppc64_caches.dline_size);
@@ -497,8 +455,6 @@ void __init setup_system(void)
497#endif 455#endif
498 printk("-----------------------------------------------------\n"); 456 printk("-----------------------------------------------------\n");
499 457
500 mm_init_ppc64();
501
502 DBG(" <- setup_system()\n"); 458 DBG(" <- setup_system()\n");
503} 459}
504 460
@@ -518,7 +474,7 @@ static void __init irqstack_early_init(void)
518 * interrupt stacks must be under 256MB, we cannot afford to take 474 * interrupt stacks must be under 256MB, we cannot afford to take
519 * SLB misses on them. 475 * SLB misses on them.
520 */ 476 */
521 for_each_cpu(i) { 477 for_each_possible_cpu(i) {
522 softirq_ctx[i] = (struct thread_info *) 478 softirq_ctx[i] = (struct thread_info *)
523 __va(lmb_alloc_base(THREAD_SIZE, 479 __va(lmb_alloc_base(THREAD_SIZE,
524 THREAD_SIZE, 0x10000000)); 480 THREAD_SIZE, 0x10000000));
@@ -551,7 +507,7 @@ static void __init emergency_stack_init(void)
551 */ 507 */
552 limit = min(0x10000000UL, lmb.rmo_size); 508 limit = min(0x10000000UL, lmb.rmo_size);
553 509
554 for_each_cpu(i) 510 for_each_possible_cpu(i)
555 paca[i].emergency_sp = 511 paca[i].emergency_sp =
556 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE; 512 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
557} 513}
@@ -581,7 +537,8 @@ void __init setup_arch(char **cmdline_p)
581 panic_timeout = 180; 537 panic_timeout = 180;
582 538
583 if (ppc_md.panic) 539 if (ppc_md.panic)
584 notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); 540 atomic_notifier_chain_register(&panic_notifier_list,
541 &ppc64_panic_block);
585 542
586 init_mm.start_code = PAGE_OFFSET; 543 init_mm.start_code = PAGE_OFFSET;
587 init_mm.end_code = (unsigned long) _etext; 544 init_mm.end_code = (unsigned long) _etext;
@@ -603,12 +560,6 @@ void __init setup_arch(char **cmdline_p)
603 560
604 ppc_md.setup_arch(); 561 ppc_md.setup_arch();
605 562
606 /* Use the default idle loop if the platform hasn't provided one. */
607 if (NULL == ppc_md.idle_loop) {
608 ppc_md.idle_loop = default_idle;
609 printk(KERN_INFO "Using default idle loop\n");
610 }
611
612 paging_init(); 563 paging_init();
613 ppc64_boot_msg(0x15, "Setup Done"); 564 ppc64_boot_msg(0x15, "Setup Done");
614} 565}
@@ -673,7 +624,7 @@ void __init setup_per_cpu_areas(void)
673 size = PERCPU_ENOUGH_ROOM; 624 size = PERCPU_ENOUGH_ROOM;
674#endif 625#endif
675 626
676 for_each_cpu(i) { 627 for_each_possible_cpu(i) {
677 ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); 628 ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
678 if (!ptr) 629 if (!ptr)
679 panic("Cannot allocate cpu data for CPU %d\n", i); 630 panic("Cannot allocate cpu data for CPU %d\n", i);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d7a4e814974d..01e3c08cb550 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -42,6 +42,7 @@
42 42
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
45#include <asm/syscalls.h>
45#include <asm/sigcontext.h> 46#include <asm/sigcontext.h>
46#include <asm/vdso.h> 47#include <asm/vdso.h>
47#ifdef CONFIG_PPC64 48#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 4324f8a8ba24..27f65b95184d 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/signal.c
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -35,6 +33,7 @@
35#include <asm/pgtable.h> 33#include <asm/pgtable.h>
36#include <asm/unistd.h> 34#include <asm/unistd.h>
37#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
36#include <asm/syscalls.h>
38#include <asm/vdso.h> 37#include <asm/vdso.h>
39 38
40#define DEBUG_SIG 0 39#define DEBUG_SIG 0
@@ -213,7 +212,7 @@ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs
213 /* Default to using normal stack */ 212 /* Default to using normal stack */
214 newsp = regs->gpr[1]; 213 newsp = regs->gpr[1];
215 214
216 if (ka->sa.sa_flags & SA_ONSTACK) { 215 if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
217 if (! on_sig_stack(regs->gpr[1])) 216 if (! on_sig_stack(regs->gpr[1]))
218 newsp = (current->sas_ss_sp + current->sas_ss_size); 217 newsp = (current->sas_ss_sp + current->sas_ss_size);
219 } 218 }
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 13595a64f013..530f7dba0bd2 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -362,7 +362,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
362 362
363 smp_space_timers(max_cpus); 363 smp_space_timers(max_cpus);
364 364
365 for_each_cpu(cpu) 365 for_each_possible_cpu(cpu)
366 if (cpu != boot_cpuid) 366 if (cpu != boot_cpuid)
367 smp_create_idle(cpu); 367 smp_create_idle(cpu);
368} 368}
@@ -541,7 +541,7 @@ int __devinit start_secondary(void *unused)
541 smp_ops->take_timebase(); 541 smp_ops->take_timebase();
542 542
543 if (system_state > SYSTEM_BOOTING) 543 if (system_state > SYSTEM_BOOTING)
544 per_cpu(last_jiffy, cpu) = get_tb(); 544 snapshot_timebase();
545 545
546 spin_lock(&call_lock); 546 spin_lock(&call_lock);
547 cpu_set(cpu, cpu_online_map); 547 cpu_set(cpu, cpu_online_map);
@@ -573,6 +573,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
573 573
574 set_cpus_allowed(current, old_mask); 574 set_cpus_allowed(current, old_mask);
575 575
576 snapshot_timebases();
577
576 dump_numa_cpu_topology(); 578 dump_numa_cpu_topology();
577} 579}
578 580
diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S
new file mode 100644
index 000000000000..69773cc1a85f
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -0,0 +1,349 @@
1#include <linux/config.h>
2#include <linux/threads.h>
3#include <asm/processor.h>
4#include <asm/page.h>
5#include <asm/cputable.h>
6#include <asm/thread_info.h>
7#include <asm/ppc_asm.h>
8#include <asm/asm-offsets.h>
9
10
11/*
12 * Structure for storing CPU registers on the save area.
13 */
14#define SL_SP 0
15#define SL_PC 4
16#define SL_MSR 8
17#define SL_SDR1 0xc
18#define SL_SPRG0 0x10 /* 4 sprg's */
19#define SL_DBAT0 0x20
20#define SL_IBAT0 0x28
21#define SL_DBAT1 0x30
22#define SL_IBAT1 0x38
23#define SL_DBAT2 0x40
24#define SL_IBAT2 0x48
25#define SL_DBAT3 0x50
26#define SL_IBAT3 0x58
27#define SL_TB 0x60
28#define SL_R2 0x68
29#define SL_CR 0x6c
30#define SL_LR 0x70
31#define SL_R12 0x74 /* r12 to r31 */
32#define SL_SIZE (SL_R12 + 80)
33
34 .section .data
35 .align 5
36
37_GLOBAL(swsusp_save_area)
38 .space SL_SIZE
39
40
41 .section .text
42 .align 5
43
44_GLOBAL(swsusp_arch_suspend)
45
46 lis r11,swsusp_save_area@h
47 ori r11,r11,swsusp_save_area@l
48
49 mflr r0
50 stw r0,SL_LR(r11)
51 mfcr r0
52 stw r0,SL_CR(r11)
53 stw r1,SL_SP(r11)
54 stw r2,SL_R2(r11)
55 stmw r12,SL_R12(r11)
56
57 /* Save MSR & SDR1 */
58 mfmsr r4
59 stw r4,SL_MSR(r11)
60 mfsdr1 r4
61 stw r4,SL_SDR1(r11)
62
63 /* Get a stable timebase and save it */
641: mftbu r4
65 stw r4,SL_TB(r11)
66 mftb r5
67 stw r5,SL_TB+4(r11)
68 mftbu r3
69 cmpw r3,r4
70 bne 1b
71
72 /* Save SPRGs */
73 mfsprg r4,0
74 stw r4,SL_SPRG0(r11)
75 mfsprg r4,1
76 stw r4,SL_SPRG0+4(r11)
77 mfsprg r4,2
78 stw r4,SL_SPRG0+8(r11)
79 mfsprg r4,3
80 stw r4,SL_SPRG0+12(r11)
81
82 /* Save BATs */
83 mfdbatu r4,0
84 stw r4,SL_DBAT0(r11)
85 mfdbatl r4,0
86 stw r4,SL_DBAT0+4(r11)
87 mfdbatu r4,1
88 stw r4,SL_DBAT1(r11)
89 mfdbatl r4,1
90 stw r4,SL_DBAT1+4(r11)
91 mfdbatu r4,2
92 stw r4,SL_DBAT2(r11)
93 mfdbatl r4,2
94 stw r4,SL_DBAT2+4(r11)
95 mfdbatu r4,3
96 stw r4,SL_DBAT3(r11)
97 mfdbatl r4,3
98 stw r4,SL_DBAT3+4(r11)
99 mfibatu r4,0
100 stw r4,SL_IBAT0(r11)
101 mfibatl r4,0
102 stw r4,SL_IBAT0+4(r11)
103 mfibatu r4,1
104 stw r4,SL_IBAT1(r11)
105 mfibatl r4,1
106 stw r4,SL_IBAT1+4(r11)
107 mfibatu r4,2
108 stw r4,SL_IBAT2(r11)
109 mfibatl r4,2
110 stw r4,SL_IBAT2+4(r11)
111 mfibatu r4,3
112 stw r4,SL_IBAT3(r11)
113 mfibatl r4,3
114 stw r4,SL_IBAT3+4(r11)
115
116#if 0
117 /* Backup various CPU config stuffs */
118 bl __save_cpu_setup
119#endif
120 /* Call the low level suspend stuff (we should probably have made
121 * a stackframe...
122 */
123 bl swsusp_save
124
125 /* Restore LR from the save area */
126 lis r11,swsusp_save_area@h
127 ori r11,r11,swsusp_save_area@l
128 lwz r0,SL_LR(r11)
129 mtlr r0
130
131 blr
132
133
134/* Resume code */
135_GLOBAL(swsusp_arch_resume)
136
137 /* Stop pending alitvec streams and memory accesses */
138BEGIN_FTR_SECTION
139 DSSALL
140END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
141 sync
142
143 /* Disable MSR:DR to make sure we don't take a TLB or
144 * hash miss during the copy, as our hash table will
145 * for a while be unuseable. For .text, we assume we are
146 * covered by a BAT. This works only for non-G5 at this
147 * point. G5 will need a better approach, possibly using
148 * a small temporary hash table filled with large mappings,
149 * disabling the MMU completely isn't a good option for
150 * performance reasons.
151 * (Note that 750's may have the same performance issue as
152 * the G5 in this case, we should investigate using moving
153 * BATs for these CPUs)
154 */
155 mfmsr r0
156 sync
157 rlwinm r0,r0,0,28,26 /* clear MSR_DR */
158 mtmsr r0
159 sync
160 isync
161
162 /* Load ptr the list of pages to copy in r3 */
163 lis r11,(pagedir_nosave - KERNELBASE)@h
164 ori r11,r11,pagedir_nosave@l
165 lwz r10,0(r11)
166
167 /* Copy the pages. This is a very basic implementation, to
168 * be replaced by something more cache efficient */
1691:
170 tophys(r3,r10)
171 li r0,256
172 mtctr r0
173 lwz r11,pbe_address(r3) /* source */
174 tophys(r5,r11)
175 lwz r10,pbe_orig_address(r3) /* destination */
176 tophys(r6,r10)
1772:
178 lwz r8,0(r5)
179 lwz r9,4(r5)
180 lwz r10,8(r5)
181 lwz r11,12(r5)
182 addi r5,r5,16
183 stw r8,0(r6)
184 stw r9,4(r6)
185 stw r10,8(r6)
186 stw r11,12(r6)
187 addi r6,r6,16
188 bdnz 2b
189 lwz r10,pbe_next(r3)
190 cmpwi 0,r10,0
191 bne 1b
192
193 /* Do a very simple cache flush/inval of the L1 to ensure
194 * coherency of the icache
195 */
196 lis r3,0x0002
197 mtctr r3
198 li r3, 0
1991:
200 lwz r0,0(r3)
201 addi r3,r3,0x0020
202 bdnz 1b
203 isync
204 sync
205
206 /* Now flush those cache lines */
207 lis r3,0x0002
208 mtctr r3
209 li r3, 0
2101:
211 dcbf 0,r3
212 addi r3,r3,0x0020
213 bdnz 1b
214 sync
215
216 /* Ok, we are now running with the kernel data of the old
217 * kernel fully restored. We can get to the save area
218 * easily now. As for the rest of the code, it assumes the
219 * loader kernel and the booted one are exactly identical
220 */
221 lis r11,swsusp_save_area@h
222 ori r11,r11,swsusp_save_area@l
223 tophys(r11,r11)
224
225#if 0
226 /* Restore various CPU config stuffs */
227 bl __restore_cpu_setup
228#endif
229 /* Restore the BATs, and SDR1. Then we can turn on the MMU.
230 * This is a bit hairy as we are running out of those BATs,
231 * but first, our code is probably in the icache, and we are
232 * writing the same value to the BAT, so that should be fine,
233 * though a better solution will have to be found long-term
234 */
235 lwz r4,SL_SDR1(r11)
236 mtsdr1 r4
237 lwz r4,SL_SPRG0(r11)
238 mtsprg 0,r4
239 lwz r4,SL_SPRG0+4(r11)
240 mtsprg 1,r4
241 lwz r4,SL_SPRG0+8(r11)
242 mtsprg 2,r4
243 lwz r4,SL_SPRG0+12(r11)
244 mtsprg 3,r4
245
246#if 0
247 lwz r4,SL_DBAT0(r11)
248 mtdbatu 0,r4
249 lwz r4,SL_DBAT0+4(r11)
250 mtdbatl 0,r4
251 lwz r4,SL_DBAT1(r11)
252 mtdbatu 1,r4
253 lwz r4,SL_DBAT1+4(r11)
254 mtdbatl 1,r4
255 lwz r4,SL_DBAT2(r11)
256 mtdbatu 2,r4
257 lwz r4,SL_DBAT2+4(r11)
258 mtdbatl 2,r4
259 lwz r4,SL_DBAT3(r11)
260 mtdbatu 3,r4
261 lwz r4,SL_DBAT3+4(r11)
262 mtdbatl 3,r4
263 lwz r4,SL_IBAT0(r11)
264 mtibatu 0,r4
265 lwz r4,SL_IBAT0+4(r11)
266 mtibatl 0,r4
267 lwz r4,SL_IBAT1(r11)
268 mtibatu 1,r4
269 lwz r4,SL_IBAT1+4(r11)
270 mtibatl 1,r4
271 lwz r4,SL_IBAT2(r11)
272 mtibatu 2,r4
273 lwz r4,SL_IBAT2+4(r11)
274 mtibatl 2,r4
275 lwz r4,SL_IBAT3(r11)
276 mtibatu 3,r4
277 lwz r4,SL_IBAT3+4(r11)
278 mtibatl 3,r4
279#endif
280
281BEGIN_FTR_SECTION
282 li r4,0
283 mtspr SPRN_DBAT4U,r4
284 mtspr SPRN_DBAT4L,r4
285 mtspr SPRN_DBAT5U,r4
286 mtspr SPRN_DBAT5L,r4
287 mtspr SPRN_DBAT6U,r4
288 mtspr SPRN_DBAT6L,r4
289 mtspr SPRN_DBAT7U,r4
290 mtspr SPRN_DBAT7L,r4
291 mtspr SPRN_IBAT4U,r4
292 mtspr SPRN_IBAT4L,r4
293 mtspr SPRN_IBAT5U,r4
294 mtspr SPRN_IBAT5L,r4
295 mtspr SPRN_IBAT6U,r4
296 mtspr SPRN_IBAT6L,r4
297 mtspr SPRN_IBAT7U,r4
298 mtspr SPRN_IBAT7L,r4
299END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
300
301 /* Flush all TLBs */
302 lis r4,0x1000
3031: addic. r4,r4,-0x1000
304 tlbie r4
305 blt 1b
306 sync
307
308 /* restore the MSR and turn on the MMU */
309 lwz r3,SL_MSR(r11)
310 bl turn_on_mmu
311 tovirt(r11,r11)
312
313 /* Restore TB */
314 li r3,0
315 mttbl r3
316 lwz r3,SL_TB(r11)
317 lwz r4,SL_TB+4(r11)
318 mttbu r3
319 mttbl r4
320
321 /* Kick decrementer */
322 li r0,1
323 mtdec r0
324
325 /* Restore the callee-saved registers and return */
326 lwz r0,SL_CR(r11)
327 mtcr r0
328 lwz r2,SL_R2(r11)
329 lmw r12,SL_R12(r11)
330 lwz r1,SL_SP(r11)
331 lwz r0,SL_LR(r11)
332 mtlr r0
333
334 // XXX Note: we don't really need to call swsusp_resume
335
336 li r3,0
337 blr
338
339/* FIXME:This construct is actually not useful since we don't shut
340 * down the instruction MMU, we could just flip back MSR-DR on.
341 */
342turn_on_mmu:
343 mflr r4
344 mtsrr0 r4
345 mtsrr1 r3
346 sync
347 isync
348 rfi
349
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index cd75ab2908fa..ec274e688816 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -24,7 +24,6 @@
24#include <linux/resource.h> 24#include <linux/resource.h>
25#include <linux/times.h> 25#include <linux/times.h>
26#include <linux/utsname.h> 26#include <linux/utsname.h>
27#include <linux/timex.h>
28#include <linux/smp.h> 27#include <linux/smp.h>
29#include <linux/smp_lock.h> 28#include <linux/smp_lock.h>
30#include <linux/sem.h> 29#include <linux/sem.h>
@@ -161,78 +160,6 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
161 return sys_sysfs((int)option, arg1, arg2); 160 return sys_sysfs((int)option, arg1, arg2);
162} 161}
163 162
164/* Handle adjtimex compatibility. */
165struct timex32 {
166 u32 modes;
167 s32 offset, freq, maxerror, esterror;
168 s32 status, constant, precision, tolerance;
169 struct compat_timeval time;
170 s32 tick;
171 s32 ppsfreq, jitter, shift, stabil;
172 s32 jitcnt, calcnt, errcnt, stbcnt;
173 s32 :32; s32 :32; s32 :32; s32 :32;
174 s32 :32; s32 :32; s32 :32; s32 :32;
175 s32 :32; s32 :32; s32 :32; s32 :32;
176};
177
178extern int do_adjtimex(struct timex *);
179
180asmlinkage long compat_sys_adjtimex(struct timex32 __user *utp)
181{
182 struct timex txc;
183 int ret;
184
185 memset(&txc, 0, sizeof(struct timex));
186
187 if(get_user(txc.modes, &utp->modes) ||
188 __get_user(txc.offset, &utp->offset) ||
189 __get_user(txc.freq, &utp->freq) ||
190 __get_user(txc.maxerror, &utp->maxerror) ||
191 __get_user(txc.esterror, &utp->esterror) ||
192 __get_user(txc.status, &utp->status) ||
193 __get_user(txc.constant, &utp->constant) ||
194 __get_user(txc.precision, &utp->precision) ||
195 __get_user(txc.tolerance, &utp->tolerance) ||
196 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
197 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
198 __get_user(txc.tick, &utp->tick) ||
199 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
200 __get_user(txc.jitter, &utp->jitter) ||
201 __get_user(txc.shift, &utp->shift) ||
202 __get_user(txc.stabil, &utp->stabil) ||
203 __get_user(txc.jitcnt, &utp->jitcnt) ||
204 __get_user(txc.calcnt, &utp->calcnt) ||
205 __get_user(txc.errcnt, &utp->errcnt) ||
206 __get_user(txc.stbcnt, &utp->stbcnt))
207 return -EFAULT;
208
209 ret = do_adjtimex(&txc);
210
211 if(put_user(txc.modes, &utp->modes) ||
212 __put_user(txc.offset, &utp->offset) ||
213 __put_user(txc.freq, &utp->freq) ||
214 __put_user(txc.maxerror, &utp->maxerror) ||
215 __put_user(txc.esterror, &utp->esterror) ||
216 __put_user(txc.status, &utp->status) ||
217 __put_user(txc.constant, &utp->constant) ||
218 __put_user(txc.precision, &utp->precision) ||
219 __put_user(txc.tolerance, &utp->tolerance) ||
220 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
221 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
222 __put_user(txc.tick, &utp->tick) ||
223 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
224 __put_user(txc.jitter, &utp->jitter) ||
225 __put_user(txc.shift, &utp->shift) ||
226 __put_user(txc.stabil, &utp->stabil) ||
227 __put_user(txc.jitcnt, &utp->jitcnt) ||
228 __put_user(txc.calcnt, &utp->calcnt) ||
229 __put_user(txc.errcnt, &utp->errcnt) ||
230 __put_user(txc.stbcnt, &utp->stbcnt))
231 ret = -EFAULT;
232
233 return ret;
234}
235
236asmlinkage long compat_sys_pause(void) 163asmlinkage long compat_sys_pause(void)
237{ 164{
238 current->state = TASK_INTERRUPTIBLE; 165 current->state = TASK_INTERRUPTIBLE;
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index ad895c99813b..9b69d99a9103 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -40,6 +40,7 @@
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <asm/ipc.h> 41#include <asm/ipc.h>
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43#include <asm/syscalls.h>
43#include <asm/time.h> 44#include <asm/time.h>
44#include <asm/unistd.h> 45#include <asm/unistd.h>
45 46
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 0f0c3a9ae2e5..73560ef6f802 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -65,20 +65,20 @@ static int __init smt_setup(void)
65 unsigned int cpu; 65 unsigned int cpu;
66 66
67 if (!cpu_has_feature(CPU_FTR_SMT)) 67 if (!cpu_has_feature(CPU_FTR_SMT))
68 return 1; 68 return -ENODEV;
69 69
70 options = find_path_device("/options"); 70 options = find_path_device("/options");
71 if (!options) 71 if (!options)
72 return 1; 72 return -ENODEV;
73 73
74 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", 74 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
75 NULL); 75 NULL);
76 if (!smt_snooze_cmdline && val) { 76 if (!smt_snooze_cmdline && val) {
77 for_each_cpu(cpu) 77 for_each_possible_cpu(cpu)
78 per_cpu(smt_snooze_delay, cpu) = *val; 78 per_cpu(smt_snooze_delay, cpu) = *val;
79 } 79 }
80 80
81 return 1; 81 return 0;
82} 82}
83__initcall(smt_setup); 83__initcall(smt_setup);
84 84
@@ -93,7 +93,7 @@ static int __init setup_smt_snooze_delay(char *str)
93 smt_snooze_cmdline = 1; 93 smt_snooze_cmdline = 1;
94 94
95 if (get_option(&str, &snooze)) { 95 if (get_option(&str, &snooze)) {
96 for_each_cpu(cpu) 96 for_each_possible_cpu(cpu)
97 per_cpu(smt_snooze_delay, cpu) = snooze; 97 per_cpu(smt_snooze_delay, cpu) = snooze;
98 } 98 }
99 99
@@ -347,7 +347,7 @@ static int __init topology_init(void)
347 347
348 register_cpu_notifier(&sysfs_cpu_nb); 348 register_cpu_notifier(&sysfs_cpu_nb);
349 349
350 for_each_cpu(cpu) { 350 for_each_possible_cpu(cpu) {
351 struct cpu *c = &per_cpu(cpu_devices, cpu); 351 struct cpu *c = &per_cpu(cpu_devices, cpu);
352 352
353#ifdef CONFIG_NUMA 353#ifdef CONFIG_NUMA
diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
new file mode 100644
index 000000000000..26bd8ea35a4e
--- /dev/null
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -0,0 +1,271 @@
1/*
2 * temp.c Thermal management for cpu's with Thermal Assist Units
3 *
4 * Written by Troy Benjegerdes <hozer@drgw.net>
5 *
6 * TODO:
7 * dynamic power management to limit peak CPU temp (using ICTC)
8 * calibration???
9 *
10 * Silly, crazy ideas: use cpu load (from scheduler) and ICTC to extend battery
11 * life in portables, and add a 'performance/watt' metric somewhere in /proc
12 */
13
14#include <linux/config.h>
15#include <linux/errno.h>
16#include <linux/jiffies.h>
17#include <linux/kernel.h>
18#include <linux/param.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/interrupt.h>
22#include <linux/init.h>
23
24#include <asm/io.h>
25#include <asm/reg.h>
26#include <asm/nvram.h>
27#include <asm/cache.h>
28#include <asm/8xx_immap.h>
29#include <asm/machdep.h>
30
31static struct tau_temp
32{
33 int interrupts;
34 unsigned char low;
35 unsigned char high;
36 unsigned char grew;
37} tau[NR_CPUS];
38
39struct timer_list tau_timer;
40
41#undef DEBUG
42
43/* TODO: put these in a /proc interface, with some sanity checks, and maybe
44 * dynamic adjustment to minimize # of interrupts */
45/* configurable values for step size and how much to expand the window when
46 * we get an interrupt. These are based on the limit that was out of range */
47#define step_size 2 /* step size when temp goes out of range */
48#define window_expand 1 /* expand the window by this much */
49/* configurable values for shrinking the window */
50#define shrink_timer 2*HZ /* period between shrinking the window */
51#define min_window 2 /* minimum window size, degrees C */
52
53void set_thresholds(unsigned long cpu)
54{
55#ifdef CONFIG_TAU_INT
56 /*
57 * setup THRM1,
58 * threshold, valid bit, enable interrupts, interrupt when below threshold
59 */
60 mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID);
61
62 /* setup THRM2,
63 * threshold, valid bit, enable interrupts, interrupt when above threshhold
64 */
65 mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE);
66#else
67 /* same thing but don't enable interrupts */
68 mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TID);
69 mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V);
70#endif
71}
72
73void TAUupdate(int cpu)
74{
75 unsigned thrm;
76
77#ifdef DEBUG
78 printk("TAUupdate ");
79#endif
80
81 /* if both thresholds are crossed, the step_sizes cancel out
82 * and the window winds up getting expanded twice. */
83 if((thrm = mfspr(SPRN_THRM1)) & THRM1_TIV){ /* is valid? */
84 if(thrm & THRM1_TIN){ /* crossed low threshold */
85 if (tau[cpu].low >= step_size){
86 tau[cpu].low -= step_size;
87 tau[cpu].high -= (step_size - window_expand);
88 }
89 tau[cpu].grew = 1;
90#ifdef DEBUG
91 printk("low threshold crossed ");
92#endif
93 }
94 }
95 if((thrm = mfspr(SPRN_THRM2)) & THRM1_TIV){ /* is valid? */
96 if(thrm & THRM1_TIN){ /* crossed high threshold */
97 if (tau[cpu].high <= 127-step_size){
98 tau[cpu].low += (step_size - window_expand);
99 tau[cpu].high += step_size;
100 }
101 tau[cpu].grew = 1;
102#ifdef DEBUG
103 printk("high threshold crossed ");
104#endif
105 }
106 }
107
108#ifdef DEBUG
109 printk("grew = %d\n", tau[cpu].grew);
110#endif
111
112#ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */
113 set_thresholds(cpu);
114#endif
115
116}
117
118#ifdef CONFIG_TAU_INT
119/*
120 * TAU interrupts - called when we have a thermal assist unit interrupt
121 * with interrupts disabled
122 */
123
124void TAUException(struct pt_regs * regs)
125{
126 int cpu = smp_processor_id();
127
128 irq_enter();
129 tau[cpu].interrupts++;
130
131 TAUupdate(cpu);
132
133 irq_exit();
134}
135#endif /* CONFIG_TAU_INT */
136
137static void tau_timeout(void * info)
138{
139 int cpu;
140 unsigned long flags;
141 int size;
142 int shrink;
143
144 /* disabling interrupts *should* be okay */
145 local_irq_save(flags);
146 cpu = smp_processor_id();
147
148#ifndef CONFIG_TAU_INT
149 TAUupdate(cpu);
150#endif
151
152 size = tau[cpu].high - tau[cpu].low;
153 if (size > min_window && ! tau[cpu].grew) {
154 /* do an exponential shrink of half the amount currently over size */
155 shrink = (2 + size - min_window) / 4;
156 if (shrink) {
157 tau[cpu].low += shrink;
158 tau[cpu].high -= shrink;
159 } else { /* size must have been min_window + 1 */
160 tau[cpu].low += 1;
161#if 1 /* debug */
162 if ((tau[cpu].high - tau[cpu].low) != min_window){
163 printk(KERN_ERR "temp.c: line %d, logic error\n", __LINE__);
164 }
165#endif
166 }
167 }
168
169 tau[cpu].grew = 0;
170
171 set_thresholds(cpu);
172
173 /*
174 * Do the enable every time, since otherwise a bunch of (relatively)
175 * complex sleep code needs to be added. One mtspr every time
176 * tau_timeout is called is probably not a big deal.
177 *
178 * Enable thermal sensor and set up sample interval timer
179 * need 20 us to do the compare.. until a nice 'cpu_speed' function
180 * call is implemented, just assume a 500 mhz clock. It doesn't really
181 * matter if we take too long for a compare since it's all interrupt
182 * driven anyway.
183 *
184 * use a extra long time.. (60 us @ 500 mhz)
185 */
186 mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E);
187
188 local_irq_restore(flags);
189}
190
191static void tau_timeout_smp(unsigned long unused)
192{
193
194 /* schedule ourselves to be run again */
195 mod_timer(&tau_timer, jiffies + shrink_timer) ;
196 on_each_cpu(tau_timeout, NULL, 1, 0);
197}
198
199/*
200 * setup the TAU
201 *
202 * Set things up to use THRM1 as a temperature lower bound, and THRM2 as an upper bound.
203 * Start off at zero
204 */
205
206int tau_initialized = 0;
207
208void __init TAU_init_smp(void * info)
209{
210 unsigned long cpu = smp_processor_id();
211
212 /* set these to a reasonable value and let the timer shrink the
213 * window */
214 tau[cpu].low = 5;
215 tau[cpu].high = 120;
216
217 set_thresholds(cpu);
218}
219
220int __init TAU_init(void)
221{
222 /* We assume in SMP that if one CPU has TAU support, they
223 * all have it --BenH
224 */
225 if (!cpu_has_feature(CPU_FTR_TAU)) {
226 printk("Thermal assist unit not available\n");
227 tau_initialized = 0;
228 return 1;
229 }
230
231
232 /* first, set up the window shrinking timer */
233 init_timer(&tau_timer);
234 tau_timer.function = tau_timeout_smp;
235 tau_timer.expires = jiffies + shrink_timer;
236 add_timer(&tau_timer);
237
238 on_each_cpu(TAU_init_smp, NULL, 1, 0);
239
240 printk("Thermal assist unit ");
241#ifdef CONFIG_TAU_INT
242 printk("using interrupts, ");
243#else
244 printk("using timers, ");
245#endif
246 printk("shrink_timer: %d jiffies\n", shrink_timer);
247 tau_initialized = 1;
248
249 return 0;
250}
251
252__initcall(TAU_init);
253
254/*
255 * return current temp
256 */
257
258u32 cpu_temp_both(unsigned long cpu)
259{
260 return ((tau[cpu].high << 16) | tau[cpu].low);
261}
262
263int cpu_temp(unsigned long cpu)
264{
265 return ((tau[cpu].high + tau[cpu].low) / 2);
266}
267
268int tau_interrupts(unsigned long cpu)
269{
270 return (tau[cpu].interrupts);
271}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 2a7ddc579379..24e3ad756de0 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -51,6 +51,7 @@
51#include <linux/percpu.h> 51#include <linux/percpu.h>
52#include <linux/rtc.h> 52#include <linux/rtc.h>
53#include <linux/jiffies.h> 53#include <linux/jiffies.h>
54#include <linux/posix-timers.h>
54 55
55#include <asm/io.h> 56#include <asm/io.h>
56#include <asm/processor.h> 57#include <asm/processor.h>
@@ -98,6 +99,7 @@ unsigned long tb_ticks_per_jiffy;
98unsigned long tb_ticks_per_usec = 100; /* sane default */ 99unsigned long tb_ticks_per_usec = 100; /* sane default */
99EXPORT_SYMBOL(tb_ticks_per_usec); 100EXPORT_SYMBOL(tb_ticks_per_usec);
100unsigned long tb_ticks_per_sec; 101unsigned long tb_ticks_per_sec;
102EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */
101u64 tb_to_xs; 103u64 tb_to_xs;
102unsigned tb_to_us; 104unsigned tb_to_us;
103 105
@@ -135,6 +137,224 @@ unsigned long tb_last_stamp;
135 */ 137 */
136DEFINE_PER_CPU(unsigned long, last_jiffy); 138DEFINE_PER_CPU(unsigned long, last_jiffy);
137 139
140#ifdef CONFIG_VIRT_CPU_ACCOUNTING
141/*
142 * Factors for converting from cputime_t (timebase ticks) to
143 * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds).
144 * These are all stored as 0.64 fixed-point binary fractions.
145 */
146u64 __cputime_jiffies_factor;
147EXPORT_SYMBOL(__cputime_jiffies_factor);
148u64 __cputime_msec_factor;
149EXPORT_SYMBOL(__cputime_msec_factor);
150u64 __cputime_sec_factor;
151EXPORT_SYMBOL(__cputime_sec_factor);
152u64 __cputime_clockt_factor;
153EXPORT_SYMBOL(__cputime_clockt_factor);
154
155static void calc_cputime_factors(void)
156{
157 struct div_result res;
158
159 div128_by_32(HZ, 0, tb_ticks_per_sec, &res);
160 __cputime_jiffies_factor = res.result_low;
161 div128_by_32(1000, 0, tb_ticks_per_sec, &res);
162 __cputime_msec_factor = res.result_low;
163 div128_by_32(1, 0, tb_ticks_per_sec, &res);
164 __cputime_sec_factor = res.result_low;
165 div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res);
166 __cputime_clockt_factor = res.result_low;
167}
168
169/*
170 * Read the PURR on systems that have it, otherwise the timebase.
171 */
172static u64 read_purr(void)
173{
174 if (cpu_has_feature(CPU_FTR_PURR))
175 return mfspr(SPRN_PURR);
176 return mftb();
177}
178
179/*
180 * Account time for a transition between system, hard irq
181 * or soft irq state.
182 */
183void account_system_vtime(struct task_struct *tsk)
184{
185 u64 now, delta;
186 unsigned long flags;
187
188 local_irq_save(flags);
189 now = read_purr();
190 delta = now - get_paca()->startpurr;
191 get_paca()->startpurr = now;
192 if (!in_interrupt()) {
193 delta += get_paca()->system_time;
194 get_paca()->system_time = 0;
195 }
196 account_system_time(tsk, 0, delta);
197 local_irq_restore(flags);
198}
199
200/*
201 * Transfer the user and system times accumulated in the paca
202 * by the exception entry and exit code to the generic process
203 * user and system time records.
204 * Must be called with interrupts disabled.
205 */
206void account_process_vtime(struct task_struct *tsk)
207{
208 cputime_t utime;
209
210 utime = get_paca()->user_time;
211 get_paca()->user_time = 0;
212 account_user_time(tsk, utime);
213}
214
215static void account_process_time(struct pt_regs *regs)
216{
217 int cpu = smp_processor_id();
218
219 account_process_vtime(current);
220 run_local_timers();
221 if (rcu_pending(cpu))
222 rcu_check_callbacks(cpu, user_mode(regs));
223 scheduler_tick();
224 run_posix_cpu_timers(current);
225}
226
227#ifdef CONFIG_PPC_SPLPAR
228/*
229 * Stuff for accounting stolen time.
230 */
231struct cpu_purr_data {
232 int initialized; /* thread is running */
233 u64 tb0; /* timebase at origin time */
234 u64 purr0; /* PURR at origin time */
235 u64 tb; /* last TB value read */
236 u64 purr; /* last PURR value read */
237 u64 stolen; /* stolen time so far */
238 spinlock_t lock;
239};
240
241static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
242
243static void snapshot_tb_and_purr(void *data)
244{
245 struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
246
247 p->tb0 = mftb();
248 p->purr0 = mfspr(SPRN_PURR);
249 p->tb = p->tb0;
250 p->purr = 0;
251 wmb();
252 p->initialized = 1;
253}
254
255/*
256 * Called during boot when all cpus have come up.
257 */
258void snapshot_timebases(void)
259{
260 int cpu;
261
262 if (!cpu_has_feature(CPU_FTR_PURR))
263 return;
264 for_each_possible_cpu(cpu)
265 spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
266 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
267}
268
269void calculate_steal_time(void)
270{
271 u64 tb, purr, t0;
272 s64 stolen;
273 struct cpu_purr_data *p0, *pme, *phim;
274 int cpu;
275
276 if (!cpu_has_feature(CPU_FTR_PURR))
277 return;
278 cpu = smp_processor_id();
279 pme = &per_cpu(cpu_purr_data, cpu);
280 if (!pme->initialized)
281 return; /* this can happen in early boot */
282 p0 = &per_cpu(cpu_purr_data, cpu & ~1);
283 phim = &per_cpu(cpu_purr_data, cpu ^ 1);
284 spin_lock(&p0->lock);
285 tb = mftb();
286 purr = mfspr(SPRN_PURR) - pme->purr0;
287 if (!phim->initialized || !cpu_online(cpu ^ 1)) {
288 stolen = (tb - pme->tb) - (purr - pme->purr);
289 } else {
290 t0 = pme->tb0;
291 if (phim->tb0 < t0)
292 t0 = phim->tb0;
293 stolen = phim->tb - t0 - phim->purr - purr - p0->stolen;
294 }
295 if (stolen > 0) {
296 account_steal_time(current, stolen);
297 p0->stolen += stolen;
298 }
299 pme->tb = tb;
300 pme->purr = purr;
301 spin_unlock(&p0->lock);
302}
303
304/*
305 * Must be called before the cpu is added to the online map when
306 * a cpu is being brought up at runtime.
307 */
308static void snapshot_purr(void)
309{
310 int cpu;
311 u64 purr;
312 struct cpu_purr_data *p0, *pme, *phim;
313 unsigned long flags;
314
315 if (!cpu_has_feature(CPU_FTR_PURR))
316 return;
317 cpu = smp_processor_id();
318 pme = &per_cpu(cpu_purr_data, cpu);
319 p0 = &per_cpu(cpu_purr_data, cpu & ~1);
320 phim = &per_cpu(cpu_purr_data, cpu ^ 1);
321 spin_lock_irqsave(&p0->lock, flags);
322 pme->tb = pme->tb0 = mftb();
323 purr = mfspr(SPRN_PURR);
324 if (!phim->initialized) {
325 pme->purr = 0;
326 pme->purr0 = purr;
327 } else {
328 /* set p->purr and p->purr0 for no change in p0->stolen */
329 pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen;
330 pme->purr0 = purr - pme->purr;
331 }
332 pme->initialized = 1;
333 spin_unlock_irqrestore(&p0->lock, flags);
334}
335
336#endif /* CONFIG_PPC_SPLPAR */
337
338#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
339#define calc_cputime_factors()
340#define account_process_time(regs) update_process_times(user_mode(regs))
341#define calculate_steal_time() do { } while (0)
342#endif
343
344#if !(defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR))
345#define snapshot_purr() do { } while (0)
346#endif
347
348/*
349 * Called when a cpu comes up after the system has finished booting,
350 * i.e. as a result of a hotplug cpu action.
351 */
352void snapshot_timebase(void)
353{
354 __get_cpu_var(last_jiffy) = get_tb();
355 snapshot_purr();
356}
357
138void __delay(unsigned long loops) 358void __delay(unsigned long loops)
139{ 359{
140 unsigned long start; 360 unsigned long start;
@@ -283,9 +503,9 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
283 * the two values of tb_update_count match and are even then the 503 * the two values of tb_update_count match and are even then the
284 * tb_to_xs and stamp_xsec values are consistent. If not, then it 504 * tb_to_xs and stamp_xsec values are consistent. If not, then it
285 * loops back and reads them again until this criteria is met. 505 * loops back and reads them again until this criteria is met.
506 * We expect the caller to have done the first increment of
507 * vdso_data->tb_update_count already.
286 */ 508 */
287 ++(vdso_data->tb_update_count);
288 smp_wmb();
289 vdso_data->tb_orig_stamp = new_tb_stamp; 509 vdso_data->tb_orig_stamp = new_tb_stamp;
290 vdso_data->stamp_xsec = new_stamp_xsec; 510 vdso_data->stamp_xsec = new_stamp_xsec;
291 vdso_data->tb_to_xs = new_tb_to_xs; 511 vdso_data->tb_to_xs = new_tb_to_xs;
@@ -310,20 +530,15 @@ static __inline__ void timer_recalc_offset(u64 cur_tb)
310 unsigned long offset; 530 unsigned long offset;
311 u64 new_stamp_xsec; 531 u64 new_stamp_xsec;
312 u64 tlen, t2x; 532 u64 tlen, t2x;
533 u64 tb, xsec_old, xsec_new;
534 struct gettimeofday_vars *varp;
313 535
314 if (__USE_RTC()) 536 if (__USE_RTC())
315 return; 537 return;
316 tlen = current_tick_length(); 538 tlen = current_tick_length();
317 offset = cur_tb - do_gtod.varp->tb_orig_stamp; 539 offset = cur_tb - do_gtod.varp->tb_orig_stamp;
318 if (tlen == last_tick_len && offset < 0x80000000u) { 540 if (tlen == last_tick_len && offset < 0x80000000u)
319 /* check that we're still in sync; if not, resync */ 541 return;
320 struct timeval tv;
321 __do_gettimeofday(&tv, cur_tb);
322 if (tv.tv_sec <= xtime.tv_sec &&
323 (tv.tv_sec < xtime.tv_sec ||
324 tv.tv_usec * 1000 <= xtime.tv_nsec))
325 return;
326 }
327 if (tlen != last_tick_len) { 542 if (tlen != last_tick_len) {
328 t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs); 543 t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs);
329 last_tick_len = tlen; 544 last_tick_len = tlen;
@@ -332,6 +547,21 @@ static __inline__ void timer_recalc_offset(u64 cur_tb)
332 new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; 547 new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
333 do_div(new_stamp_xsec, 1000000000); 548 do_div(new_stamp_xsec, 1000000000);
334 new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; 549 new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
550
551 ++vdso_data->tb_update_count;
552 smp_mb();
553
554 /*
555 * Make sure time doesn't go backwards for userspace gettimeofday.
556 */
557 tb = get_tb();
558 varp = do_gtod.varp;
559 xsec_old = mulhdu(tb - varp->tb_orig_stamp, varp->tb_to_xs)
560 + varp->stamp_xsec;
561 xsec_new = mulhdu(tb - cur_tb, t2x) + new_stamp_xsec;
562 if (xsec_new < xsec_old)
563 new_stamp_xsec += xsec_old - xsec_new;
564
335 update_gtod(cur_tb, new_stamp_xsec, t2x); 565 update_gtod(cur_tb, new_stamp_xsec, t2x);
336} 566}
337 567
@@ -382,6 +612,7 @@ static void iSeries_tb_recal(void)
382 new_tb_ticks_per_jiffy, sign, tick_diff ); 612 new_tb_ticks_per_jiffy, sign, tick_diff );
383 tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; 613 tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
384 tb_ticks_per_sec = new_tb_ticks_per_sec; 614 tb_ticks_per_sec = new_tb_ticks_per_sec;
615 calc_cputime_factors();
385 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); 616 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
386 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 617 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
387 tb_to_xs = divres.result_low; 618 tb_to_xs = divres.result_low;
@@ -430,6 +661,7 @@ void timer_interrupt(struct pt_regs * regs)
430 irq_enter(); 661 irq_enter();
431 662
432 profile_tick(CPU_PROFILING, regs); 663 profile_tick(CPU_PROFILING, regs);
664 calculate_steal_time();
433 665
434#ifdef CONFIG_PPC_ISERIES 666#ifdef CONFIG_PPC_ISERIES
435 get_lppaca()->int_dword.fields.decr_int = 0; 667 get_lppaca()->int_dword.fields.decr_int = 0;
@@ -451,7 +683,7 @@ void timer_interrupt(struct pt_regs * regs)
451 * is the case. 683 * is the case.
452 */ 684 */
453 if (!cpu_is_offline(cpu)) 685 if (!cpu_is_offline(cpu))
454 update_process_times(user_mode(regs)); 686 account_process_time(regs);
455 687
456 /* 688 /*
457 * No need to check whether cpu is offline here; boot_cpuid 689 * No need to check whether cpu is offline here; boot_cpuid
@@ -508,13 +740,27 @@ void wakeup_decrementer(void)
508void __init smp_space_timers(unsigned int max_cpus) 740void __init smp_space_timers(unsigned int max_cpus)
509{ 741{
510 int i; 742 int i;
743 unsigned long half = tb_ticks_per_jiffy / 2;
511 unsigned long offset = tb_ticks_per_jiffy / max_cpus; 744 unsigned long offset = tb_ticks_per_jiffy / max_cpus;
512 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); 745 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
513 746
514 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ 747 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
515 previous_tb -= tb_ticks_per_jiffy; 748 previous_tb -= tb_ticks_per_jiffy;
516 for_each_cpu(i) { 749 /*
517 if (i != boot_cpuid) { 750 * The stolen time calculation for POWER5 shared-processor LPAR
751 * systems works better if the two threads' timebase interrupts
752 * are staggered by half a jiffy with respect to each other.
753 */
754 for_each_possible_cpu(i) {
755 if (i == boot_cpuid)
756 continue;
757 if (i == (boot_cpuid ^ 1))
758 per_cpu(last_jiffy, i) =
759 per_cpu(last_jiffy, boot_cpuid) - half;
760 else if (i & 1)
761 per_cpu(last_jiffy, i) =
762 per_cpu(last_jiffy, i ^ 1) + half;
763 else {
518 previous_tb += offset; 764 previous_tb += offset;
519 per_cpu(last_jiffy, i) = previous_tb; 765 per_cpu(last_jiffy, i) = previous_tb;
520 } 766 }
@@ -564,6 +810,10 @@ int do_settimeofday(struct timespec *tv)
564 } 810 }
565#endif 811#endif
566 812
813 /* Make userspace gettimeofday spin until we're done. */
814 ++vdso_data->tb_update_count;
815 smp_mb();
816
567 /* 817 /*
568 * Subtract off the number of nanoseconds since the 818 * Subtract off the number of nanoseconds since the
569 * beginning of the last tick. 819 * beginning of the last tick.
@@ -706,6 +956,7 @@ void __init time_init(void)
706 tb_ticks_per_sec = ppc_tb_freq; 956 tb_ticks_per_sec = ppc_tb_freq;
707 tb_ticks_per_usec = ppc_tb_freq / 1000000; 957 tb_ticks_per_usec = ppc_tb_freq / 1000000;
708 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); 958 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
959 calc_cputime_factors();
709 960
710 /* 961 /*
711 * Calculate the length of each tick in ns. It will not be 962 * Calculate the length of each tick in ns. It will not be
@@ -724,10 +975,16 @@ void __init time_init(void)
724 * It is computed as: 975 * It is computed as:
725 * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9) 976 * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9)
726 * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT 977 * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT
727 * so as to give the result as a 0.64 fixed-point fraction. 978 * which turns out to be N = 51 - SHIFT_HZ.
979 * This gives the result as a 0.64 fixed-point fraction.
980 * That value is reduced by an offset amounting to 1 xsec per
981 * 2^31 timebase ticks to avoid problems with time going backwards
982 * by 1 xsec when we do timer_recalc_offset due to losing the
983 * fractional xsec. That offset is equal to ppc_tb_freq/2^51
984 * since there are 2^20 xsec in a second.
728 */ 985 */
729 div128_by_32(1ULL << (64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT), 0, 986 div128_by_32((1ULL << 51) - ppc_tb_freq, 0,
730 tb_ticks_per_jiffy, &res); 987 tb_ticks_per_jiffy << SHIFT_HZ, &res);
731 div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res); 988 div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res);
732 ticklen_to_xs = res.result_low; 989 ticklen_to_xs = res.result_low;
733 990
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 98660aedeeb7..4cbde211eb69 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -74,19 +74,19 @@ EXPORT_SYMBOL(__debugger_dabr_match);
74EXPORT_SYMBOL(__debugger_fault_handler); 74EXPORT_SYMBOL(__debugger_fault_handler);
75#endif 75#endif
76 76
77struct notifier_block *powerpc_die_chain; 77ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
78static DEFINE_SPINLOCK(die_notifier_lock);
79 78
80int register_die_notifier(struct notifier_block *nb) 79int register_die_notifier(struct notifier_block *nb)
81{ 80{
82 int err = 0; 81 return atomic_notifier_chain_register(&powerpc_die_chain, nb);
83 unsigned long flags; 82}
83EXPORT_SYMBOL(register_die_notifier);
84 84
85 spin_lock_irqsave(&die_notifier_lock, flags); 85int unregister_die_notifier(struct notifier_block *nb)
86 err = notifier_chain_register(&powerpc_die_chain, nb); 86{
87 spin_unlock_irqrestore(&die_notifier_lock, flags); 87 return atomic_notifier_chain_unregister(&powerpc_die_chain, nb);
88 return err;
89} 88}
89EXPORT_SYMBOL(unregister_die_notifier);
90 90
91/* 91/*
92 * Trap & Exception support 92 * Trap & Exception support
@@ -97,7 +97,6 @@ static DEFINE_SPINLOCK(die_lock);
97int die(const char *str, struct pt_regs *regs, long err) 97int die(const char *str, struct pt_regs *regs, long err)
98{ 98{
99 static int die_counter, crash_dump_start = 0; 99 static int die_counter, crash_dump_start = 0;
100 int nl = 0;
101 100
102 if (debugger(regs)) 101 if (debugger(regs))
103 return 1; 102 return 1;
@@ -106,7 +105,7 @@ int die(const char *str, struct pt_regs *regs, long err)
106 spin_lock_irq(&die_lock); 105 spin_lock_irq(&die_lock);
107 bust_spinlocks(1); 106 bust_spinlocks(1);
108#ifdef CONFIG_PMAC_BACKLIGHT 107#ifdef CONFIG_PMAC_BACKLIGHT
109 if (_machine == _MACH_Pmac) { 108 if (machine_is(powermac)) {
110 set_backlight_enable(1); 109 set_backlight_enable(1);
111 set_backlight_level(BACKLIGHT_MAX); 110 set_backlight_level(BACKLIGHT_MAX);
112 } 111 }
@@ -114,46 +113,18 @@ int die(const char *str, struct pt_regs *regs, long err)
114 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); 113 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
115#ifdef CONFIG_PREEMPT 114#ifdef CONFIG_PREEMPT
116 printk("PREEMPT "); 115 printk("PREEMPT ");
117 nl = 1;
118#endif 116#endif
119#ifdef CONFIG_SMP 117#ifdef CONFIG_SMP
120 printk("SMP NR_CPUS=%d ", NR_CPUS); 118 printk("SMP NR_CPUS=%d ", NR_CPUS);
121 nl = 1;
122#endif 119#endif
123#ifdef CONFIG_DEBUG_PAGEALLOC 120#ifdef CONFIG_DEBUG_PAGEALLOC
124 printk("DEBUG_PAGEALLOC "); 121 printk("DEBUG_PAGEALLOC ");
125 nl = 1;
126#endif 122#endif
127#ifdef CONFIG_NUMA 123#ifdef CONFIG_NUMA
128 printk("NUMA "); 124 printk("NUMA ");
129 nl = 1;
130#endif 125#endif
131#ifdef CONFIG_PPC64 126 printk("%s\n", ppc_md.name ? "" : ppc_md.name);
132 switch (_machine) { 127
133 case PLATFORM_PSERIES:
134 printk("PSERIES ");
135 nl = 1;
136 break;
137 case PLATFORM_PSERIES_LPAR:
138 printk("PSERIES LPAR ");
139 nl = 1;
140 break;
141 case PLATFORM_ISERIES_LPAR:
142 printk("ISERIES LPAR ");
143 nl = 1;
144 break;
145 case PLATFORM_POWERMAC:
146 printk("POWERMAC ");
147 nl = 1;
148 break;
149 case PLATFORM_CELL:
150 printk("CELL ");
151 nl = 1;
152 break;
153 }
154#endif
155 if (nl)
156 printk("\n");
157 print_modules(); 128 print_modules();
158 show_regs(regs); 129 show_regs(regs);
159 bust_spinlocks(0); 130 bust_spinlocks(0);
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 04f7df39ffbb..573afb68d69e 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/vdso.c
3 *
4 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. 2 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org> 3 * <benh@kernel.crashing.org>
6 * 4 *
@@ -35,6 +33,7 @@
35#include <asm/machdep.h> 33#include <asm/machdep.h>
36#include <asm/cputable.h> 34#include <asm/cputable.h>
37#include <asm/sections.h> 35#include <asm/sections.h>
36#include <asm/firmware.h>
38#include <asm/vdso.h> 37#include <asm/vdso.h>
39#include <asm/vdso_datapage.h> 38#include <asm/vdso_datapage.h>
40 39
@@ -669,7 +668,13 @@ void __init vdso_init(void)
669 vdso_data->version.major = SYSTEMCFG_MAJOR; 668 vdso_data->version.major = SYSTEMCFG_MAJOR;
670 vdso_data->version.minor = SYSTEMCFG_MINOR; 669 vdso_data->version.minor = SYSTEMCFG_MINOR;
671 vdso_data->processor = mfspr(SPRN_PVR); 670 vdso_data->processor = mfspr(SPRN_PVR);
672 vdso_data->platform = _machine; 671 /*
672 * Fake the old platform number for pSeries and iSeries and add
673 * in LPAR bit if necessary
674 */
675 vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100;
676 if (firmware_has_feature(FW_FEATURE_LPAR))
677 vdso_data->platform |= 1;
673 vdso_data->physicalMemorySize = lmb_phys_mem_size(); 678 vdso_data->physicalMemorySize = lmb_phys_mem_size();
674 vdso_data->dcache_size = ppc64_caches.dsize; 679 vdso_data->dcache_size = ppc64_caches.dsize;
675 vdso_data->dcache_line_size = ppc64_caches.dline_size; 680 vdso_data->dcache_line_size = ppc64_caches.dline_size;
diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S
index e04642781917..0c6a37b29dde 100644
--- a/arch/powerpc/kernel/vdso32/sigtramp.S
+++ b/arch/powerpc/kernel/vdso32/sigtramp.S
@@ -261,7 +261,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt32)
261.Lcie_start: 261.Lcie_start:
262 .long 0 /* CIE ID */ 262 .long 0 /* CIE ID */
263 .byte 1 /* Version number */ 263 .byte 1 /* Version number */
264 .string "zR" /* NUL-terminated augmentation string */ 264 .string "zRS" /* NUL-terminated augmentation string */
265 .uleb128 4 /* Code alignment factor */ 265 .uleb128 4 /* Code alignment factor */
266 .sleb128 -4 /* Data alignment factor */ 266 .sleb128 -4 /* Data alignment factor */
267 .byte 67 /* Return address register column, ap */ 267 .byte 67 /* Return address register column, ap */
diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 31b604ab56de..7479edb101b8 100644
--- a/arch/powerpc/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
@@ -263,7 +263,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
263.Lcie_start: 263.Lcie_start:
264 .long 0 /* CIE ID */ 264 .long 0 /* CIE ID */
265 .byte 1 /* Version number */ 265 .byte 1 /* Version number */
266 .string "zR" /* NUL-terminated augmentation string */ 266 .string "zRS" /* NUL-terminated augmentation string */
267 .uleb128 4 /* Code alignment factor */ 267 .uleb128 4 /* Code alignment factor */
268 .sleb128 -8 /* Data alignment factor */ 268 .sleb128 -8 /* Data alignment factor */
269 .byte 67 /* Return address register column, ap */ 269 .byte 67 /* Return address register column, ap */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 7fa7b15fd8e6..fe79c2584cb0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -1,9 +1,11 @@
1#include <linux/config.h> 1#include <linux/config.h>
2#ifdef CONFIG_PPC64 2#ifdef CONFIG_PPC64
3#include <asm/page.h> 3#include <asm/page.h>
4#define PROVIDE32(x) PROVIDE(__unused__##x)
4#else 5#else
5#define PAGE_SIZE 4096 6#define PAGE_SIZE 4096
6#define KERNELBASE CONFIG_KERNEL_START 7#define KERNELBASE CONFIG_KERNEL_START
8#define PROVIDE32(x) PROVIDE(x)
7#endif 9#endif
8#include <asm-generic/vmlinux.lds.h> 10#include <asm-generic/vmlinux.lds.h>
9 11
@@ -18,43 +20,42 @@ jiffies = jiffies_64 + 4;
18#endif 20#endif
19SECTIONS 21SECTIONS
20{ 22{
21 /* Sections to be discarded. */ 23 /* Sections to be discarded. */
22 /DISCARD/ : { 24 /DISCARD/ : {
23 *(.exitcall.exit) 25 *(.exitcall.exit)
24 *(.exit.data) 26 *(.exit.data)
25 } 27 }
26
27 . = KERNELBASE;
28
29 /* Read-only sections, merged into text segment: */
30 .text : {
31 *(.text .text.*)
32 SCHED_TEXT
33 LOCK_TEXT
34 KPROBES_TEXT
35 *(.fixup)
36#ifdef CONFIG_PPC32
37 *(.got1)
38 __got2_start = .;
39 *(.got2)
40 __got2_end = .;
41#else
42 . = ALIGN(PAGE_SIZE);
43 _etext = .;
44#endif
45 }
46#ifdef CONFIG_PPC32
47 _etext = .;
48 PROVIDE (etext = .);
49 28
50 RODATA 29 . = KERNELBASE;
51 .fini : { *(.fini) } =0
52 .ctors : { *(.ctors) }
53 .dtors : { *(.dtors) }
54 30
55 .fixup : { *(.fixup) } 31/*
56#endif 32 * Text, read only data and other permanent read-only sections
33 */
34
35 /* Text and gots */
36 .text : {
37 *(.text .text.*)
38 SCHED_TEXT
39 LOCK_TEXT
40 KPROBES_TEXT
41 *(.fixup)
57 42
43#ifdef CONFIG_PPC32
44 *(.got1)
45 __got2_start = .;
46 *(.got2)
47 __got2_end = .;
48#endif /* CONFIG_PPC32 */
49
50 . = ALIGN(PAGE_SIZE);
51 _etext = .;
52 PROVIDE32 (etext = .);
53 }
54
55 /* Read-only data */
56 RODATA
57
58 /* Exception & bug tables */
58 __ex_table : { 59 __ex_table : {
59 __start___ex_table = .; 60 __start___ex_table = .;
60 *(__ex_table) 61 *(__ex_table)
@@ -67,192 +68,172 @@ SECTIONS
67 __stop___bug_table = .; 68 __stop___bug_table = .;
68 } 69 }
69 70
70#ifdef CONFIG_PPC64 71/*
72 * Init sections discarded at runtime
73 */
74 . = ALIGN(PAGE_SIZE);
75 __init_begin = .;
76
77 .init.text : {
78 _sinittext = .;
79 *(.init.text)
80 _einittext = .;
81 }
82
83 /* .exit.text is discarded at runtime, not link time,
84 * to deal with references from __bug_table
85 */
86 .exit.text : { *(.exit.text) }
87
88 .init.data : {
89 *(.init.data);
90 __vtop_table_begin = .;
91 *(.vtop_fixup);
92 __vtop_table_end = .;
93 __ptov_table_begin = .;
94 *(.ptov_fixup);
95 __ptov_table_end = .;
96 }
97
98 . = ALIGN(16);
99 .init.setup : {
100 __setup_start = .;
101 *(.init.setup)
102 __setup_end = .;
103 }
104
105 .initcall.init : {
106 __initcall_start = .;
107 *(.initcall1.init)
108 *(.initcall2.init)
109 *(.initcall3.init)
110 *(.initcall4.init)
111 *(.initcall5.init)
112 *(.initcall6.init)
113 *(.initcall7.init)
114 __initcall_end = .;
115 }
116
117 .con_initcall.init : {
118 __con_initcall_start = .;
119 *(.con_initcall.init)
120 __con_initcall_end = .;
121 }
122
123 SECURITY_INIT
124
125 . = ALIGN(8);
71 __ftr_fixup : { 126 __ftr_fixup : {
72 __start___ftr_fixup = .; 127 __start___ftr_fixup = .;
73 *(__ftr_fixup) 128 *(__ftr_fixup)
74 __stop___ftr_fixup = .; 129 __stop___ftr_fixup = .;
75 } 130 }
76 131
77 RODATA 132 . = ALIGN(PAGE_SIZE);
78#endif 133 .init.ramfs : {
134 __initramfs_start = .;
135 *(.init.ramfs)
136 __initramfs_end = .;
137 }
79 138
80#ifdef CONFIG_PPC32 139#ifdef CONFIG_PPC32
81 /* Read-write section, merged into data segment: */ 140 . = ALIGN(32);
82 . = ALIGN(PAGE_SIZE); 141#else
83 _sdata = .; 142 . = ALIGN(128);
84 .data :
85 {
86 *(.data)
87 *(.data1)
88 *(.sdata)
89 *(.sdata2)
90 *(.got.plt) *(.got)
91 *(.dynamic)
92 CONSTRUCTORS
93 }
94
95 . = ALIGN(PAGE_SIZE);
96 __nosave_begin = .;
97 .data_nosave : { *(.data.nosave) }
98 . = ALIGN(PAGE_SIZE);
99 __nosave_end = .;
100
101 . = ALIGN(32);
102 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
103
104 _edata = .;
105 PROVIDE (edata = .);
106
107 . = ALIGN(8192);
108 .data.init_task : { *(.data.init_task) }
109#endif 143#endif
144 .data.percpu : {
145 __per_cpu_start = .;
146 *(.data.percpu)
147 __per_cpu_end = .;
148 }
110 149
111 /* will be freed after init */ 150 . = ALIGN(8);
112 . = ALIGN(PAGE_SIZE); 151 .machine.desc : {
113 __init_begin = .; 152 __machine_desc_start = . ;
114 .init.text : { 153 *(.machine.desc)
115 _sinittext = .; 154 __machine_desc_end = . ;
116 *(.init.text) 155 }
117 _einittext = .; 156
118 } 157 /* freed after init ends here */
119#ifdef CONFIG_PPC32 158 . = ALIGN(PAGE_SIZE);
120 /* .exit.text is discarded at runtime, not link time, 159 __init_end = .;
121 to deal with references from __bug_table */ 160
122 .exit.text : { *(.exit.text) } 161/*
123#endif 162 * And now the various read/write data
124 .init.data : { 163 */
125 *(.init.data); 164
126 __vtop_table_begin = .; 165 . = ALIGN(PAGE_SIZE);
127 *(.vtop_fixup); 166 _sdata = .;
128 __vtop_table_end = .;
129 __ptov_table_begin = .;
130 *(.ptov_fixup);
131 __ptov_table_end = .;
132 }
133
134 . = ALIGN(16);
135 .init.setup : {
136 __setup_start = .;
137 *(.init.setup)
138 __setup_end = .;
139 }
140
141 .initcall.init : {
142 __initcall_start = .;
143 *(.initcall1.init)
144 *(.initcall2.init)
145 *(.initcall3.init)
146 *(.initcall4.init)
147 *(.initcall5.init)
148 *(.initcall6.init)
149 *(.initcall7.init)
150 __initcall_end = .;
151 }
152
153 .con_initcall.init : {
154 __con_initcall_start = .;
155 *(.con_initcall.init)
156 __con_initcall_end = .;
157 }
158
159 SECURITY_INIT
160 167
161#ifdef CONFIG_PPC32 168#ifdef CONFIG_PPC32
162 __start___ftr_fixup = .; 169 .data :
163 __ftr_fixup : { *(__ftr_fixup) } 170 {
164 __stop___ftr_fixup = .; 171 *(.data)
172 *(.sdata)
173 *(.got.plt) *(.got)
174 }
165#else 175#else
166 . = ALIGN(PAGE_SIZE); 176 .data : {
167 .init.ramfs : { 177 *(.data .data.rel* .toc1)
168 __initramfs_start = .; 178 *(.branch_lt)
169 *(.init.ramfs) 179 }
170 __initramfs_end = .;
171 }
172#endif
173 180
174#ifdef CONFIG_PPC32 181 .opd : {
175 . = ALIGN(32); 182 *(.opd)
183 }
184
185 .got : {
186 __toc_start = .;
187 *(.got)
188 *(.toc)
189 }
176#endif 190#endif
177 .data.percpu : {
178 __per_cpu_start = .;
179 *(.data.percpu)
180 __per_cpu_end = .;
181 }
182 191
183 . = ALIGN(PAGE_SIZE); 192 . = ALIGN(PAGE_SIZE);
184#ifdef CONFIG_PPC64 193 _edata = .;
185 . = ALIGN(16384); 194 PROVIDE32 (edata = .);
186 __init_end = .; 195
187 /* freed after init ends here */ 196 /* The initial task and kernel stack */
188 197#ifdef CONFIG_PPC32
189 /* Read/write sections */ 198 . = ALIGN(8192);
190 . = ALIGN(PAGE_SIZE);
191 . = ALIGN(16384);
192 _sdata = .;
193 /* The initial task and kernel stack */
194 .data.init_task : {
195 *(.data.init_task)
196 }
197
198 . = ALIGN(PAGE_SIZE);
199 .data.page_aligned : {
200 *(.data.page_aligned)
201 }
202
203 .data.cacheline_aligned : {
204 *(.data.cacheline_aligned)
205 }
206
207 .data : {
208 *(.data .data.rel* .toc1)
209 *(.branch_lt)
210 }
211
212 .opd : {
213 *(.opd)
214 }
215
216 .got : {
217 __toc_start = .;
218 *(.got)
219 *(.toc)
220 . = ALIGN(PAGE_SIZE);
221 _edata = .;
222 }
223
224 . = ALIGN(PAGE_SIZE);
225#else 199#else
226 __initramfs_start = .; 200 . = ALIGN(16384);
227 .init.ramfs : { 201#endif
228 *(.init.ramfs) 202 .data.init_task : {
229 } 203 *(.data.init_task)
230 __initramfs_end = .; 204 }
231 205
232 . = ALIGN(4096); 206 . = ALIGN(PAGE_SIZE);
233 __init_end = .; 207 .data.page_aligned : {
208 *(.data.page_aligned)
209 }
234 210
235 . = ALIGN(4096); 211 .data.cacheline_aligned : {
236 _sextratext = .; 212 *(.data.cacheline_aligned)
237 _eextratext = .; 213 }
238 214
239 __bss_start = .; 215 . = ALIGN(PAGE_SIZE);
240#endif 216 __data_nosave : {
217 __nosave_begin = .;
218 *(.data.nosave)
219 . = ALIGN(PAGE_SIZE);
220 __nosave_end = .;
221 }
241 222
242 .bss : { 223/*
243 __bss_start = .; 224 * And finally the bss
244 *(.sbss) *(.scommon) 225 */
245 *(.dynbss) 226
246 *(.bss) 227 .bss : {
247 *(COMMON) 228 __bss_start = .;
248 __bss_stop = .; 229 *(.sbss) *(.scommon)
249 } 230 *(.dynbss)
231 *(.bss)
232 *(COMMON)
233 __bss_stop = .;
234 }
250 235
251#ifdef CONFIG_PPC64 236 . = ALIGN(PAGE_SIZE);
252 . = ALIGN(PAGE_SIZE); 237 _end = . ;
253#endif 238 PROVIDE32 (end = .);
254 _end = . ;
255#ifdef CONFIG_PPC32
256 PROVIDE (end = .);
257#endif
258} 239}
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
index 40523b140109..f9837f44ac0b 100644
--- a/arch/powerpc/lib/copypage_64.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/lib/copypage.S
3 *
4 * Copyright (C) 2002 Paul Mackerras, IBM Corp. 2 * Copyright (C) 2002 Paul Mackerras, IBM Corp.
5 * 3 *
6 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 6d69ef39b7df..a6b54cb97c49 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/lib/copyuser.S
3 *
4 * Copyright (C) 2002 Paul Mackerras, IBM Corp. 2 * Copyright (C) 2002 Paul Mackerras, IBM Corp.
5 * 3 *
6 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c
index d2b834887920..4b72ed8fd50e 100644
--- a/arch/powerpc/lib/e2a.c
+++ b/arch/powerpc/lib/e2a.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * arch/ppc64/lib/e2a.c
3 *
4 * EBCDIC to ASCII conversion 2 * EBCDIC to ASCII conversion
5 * 3 *
6 * This function moved here from arch/ppc64/kernel/viopath.c 4 * This function moved here from arch/powerpc/platforms/iseries/viopath.c
7 * 5 *
8 * (C) Copyright 2000-2004 IBM Corporation 6 * (C) Copyright 2000-2004 IBM Corporation
9 * 7 *
@@ -105,4 +103,14 @@ unsigned char e2a(unsigned char x)
105} 103}
106EXPORT_SYMBOL(e2a); 104EXPORT_SYMBOL(e2a);
107 105
106unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
107{
108 int i;
109
110 n = strnlen(src, n);
108 111
112 for (i = 0; i < n; i++)
113 dest[i] = e2a(src[i]);
114
115 return dest;
116}
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index 9ccacdf5bcb9..fd66acfd3e3e 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/lib/memcpy.S
3 *
4 * Copyright (C) 2002 Paul Mackerras, IBM Corp. 2 * Copyright (C) 2002 Paul Mackerras, IBM Corp.
5 * 3 *
6 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index 42c5de2c898f..31e511856dc5 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/syslib/rheap.c
3 *
4 * A Remote Heap. Remote means that we don't touch the memory that the 2 * A Remote Heap. Remote means that we don't touch the memory that the
5 * heap points to. Normal heap implementations use the memory they manage 3 * heap points to. Normal heap implementations use the memory they manage
6 * to place their list. We cannot do that because the memory we manage may 4 * to place their list. We cannot do that because the memory we manage may
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 666c2aa55016..c251d9936612 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -18,7 +18,7 @@ extern char system_call_common[];
18 18
19#ifdef CONFIG_PPC64 19#ifdef CONFIG_PPC64
20/* Bits in SRR1 that are copied from MSR */ 20/* Bits in SRR1 that are copied from MSR */
21#define MSR_MASK 0xffffffff87c0ffff 21#define MSR_MASK 0xffffffff87c0ffffUL
22#else 22#else
23#define MSR_MASK 0x87c0ffff 23#define MSR_MASK 0x87c0ffff
24#endif 24#endif
diff --git a/arch/powerpc/lib/strcase.c b/arch/powerpc/lib/strcase.c
index 36b521091bbc..f8ec1eba3fdd 100644
--- a/arch/powerpc/lib/strcase.c
+++ b/arch/powerpc/lib/strcase.c
@@ -1,4 +1,6 @@
1#include <linux/types.h>
1#include <linux/ctype.h> 2#include <linux/ctype.h>
3#include <linux/string.h>
2 4
3int strcasecmp(const char *s1, const char *s2) 5int strcasecmp(const char *s1, const char *s2)
4{ 6{
@@ -11,7 +13,7 @@ int strcasecmp(const char *s1, const char *s2)
11 return c1 - c2; 13 return c1 - c2;
12} 14}
13 15
14int strncasecmp(const char *s1, const char *s2, int n) 16int strncasecmp(const char *s1, const char *s2, size_t n)
15{ 17{
16 int c1, c2; 18 int c1, c2;
17 19
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
new file mode 100644
index 000000000000..754143e8936b
--- /dev/null
+++ b/arch/powerpc/math-emu/Makefile
@@ -0,0 +1,13 @@
1
2obj-y := math.o fmr.o lfd.o stfd.o
3
4obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
5 fctiw.o fctiwz.o fdiv.o fdivs.o \
6 fmadd.o fmadds.o fmsub.o fmsubs.o \
7 fmul.o fmuls.o fnabs.o fneg.o types.o \
8 fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
9 fres.o frsp.o frsqrte.o fsel.o lfs.o \
10 fsqrt.o fsqrts.o fsub.o fsubs.o \
11 mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
12 mtfsf.o mtfsfi.o stfiwx.o stfs.o \
13 udivmodti4.o
diff --git a/arch/powerpc/math-emu/double.h b/arch/powerpc/math-emu/double.h
new file mode 100644
index 000000000000..ffba8b67f059
--- /dev/null
+++ b/arch/powerpc/math-emu/double.h
@@ -0,0 +1,129 @@
1/*
2 * Definitions for IEEE Double Precision
3 */
4
5#if _FP_W_TYPE_SIZE < 32
6#error "Here's a nickel kid. Go buy yourself a real computer."
7#endif
8
9#if _FP_W_TYPE_SIZE < 64
10#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE)
11#else
12#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE
13#endif
14
15#define _FP_FRACBITS_D 53
16#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D)
17#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D)
18#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
19#define _FP_EXPBITS_D 11
20#define _FP_EXPBIAS_D 1023
21#define _FP_EXPMAX_D 2047
22
23#define _FP_QNANBIT_D \
24 ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE))
25#define _FP_IMPLBIT_D \
26 ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE))
27#define _FP_OVERFLOW_D \
28 ((_FP_W_TYPE)1 << (_FP_WFRACBITS_D % _FP_W_TYPE_SIZE))
29
30#if _FP_W_TYPE_SIZE < 64
31
32union _FP_UNION_D
33{
34 double flt;
35 struct {
36#if __BYTE_ORDER == __BIG_ENDIAN
37 unsigned sign : 1;
38 unsigned exp : _FP_EXPBITS_D;
39 unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
40 unsigned frac0 : _FP_W_TYPE_SIZE;
41#else
42 unsigned frac0 : _FP_W_TYPE_SIZE;
43 unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
44 unsigned exp : _FP_EXPBITS_D;
45 unsigned sign : 1;
46#endif
47 } bits __attribute__((packed));
48};
49
50#define FP_DECL_D(X) _FP_DECL(2,X)
51#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
52#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X)
53
54#define FP_UNPACK_D(X,val) \
55 do { \
56 _FP_UNPACK_RAW_2(D,X,val); \
57 _FP_UNPACK_CANONICAL(D,2,X); \
58 } while (0)
59
60#define FP_PACK_D(val,X) \
61 do { \
62 _FP_PACK_CANONICAL(D,2,X); \
63 _FP_PACK_RAW_2(D,val,X); \
64 } while (0)
65
66#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X)
67#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y)
68#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y)
69#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y)
70#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y)
71#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X)
72
73#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un)
74#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
75
76#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
77#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
78
79#else
80
81union _FP_UNION_D
82{
83 double flt;
84 struct {
85#if __BYTE_ORDER == __BIG_ENDIAN
86 unsigned sign : 1;
87 unsigned exp : _FP_EXPBITS_D;
88 unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
89#else
90 unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
91 unsigned exp : _FP_EXPBITS_D;
92 unsigned sign : 1;
93#endif
94 } bits __attribute__((packed));
95};
96
97#define FP_DECL_D(X) _FP_DECL(1,X)
98#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
99#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X)
100
101#define FP_UNPACK_D(X,val) \
102 do { \
103 _FP_UNPACK_RAW_1(D,X,val); \
104 _FP_UNPACK_CANONICAL(D,1,X); \
105 } while (0)
106
107#define FP_PACK_D(val,X) \
108 do { \
109 _FP_PACK_CANONICAL(D,1,X); \
110 _FP_PACK_RAW_1(D,val,X); \
111 } while (0)
112
113#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X)
114#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y)
115#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y)
116#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y)
117#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y)
118#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X)
119
120/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
121 the target machine. */
122
123#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
124#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
125
126#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
127#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
128
129#endif /* W_TYPE_SIZE < 64 */
diff --git a/arch/powerpc/math-emu/fabs.c b/arch/powerpc/math-emu/fabs.c
new file mode 100644
index 000000000000..41f0617f3d3a
--- /dev/null
+++ b/arch/powerpc/math-emu/fabs.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6fabs(u32 *frD, u32 *frB)
7{
8 frD[0] = frB[0] & 0x7fffffff;
9 frD[1] = frB[1];
10
11#ifdef DEBUG
12 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
13 dump_double(frD);
14 printk("\n");
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c
new file mode 100644
index 000000000000..fc8836488b64
--- /dev/null
+++ b/arch/powerpc/math-emu/fadd.c
@@ -0,0 +1,38 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fadd(void *frD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 FP_DECL_D(R);
14 int ret = 0;
15
16#ifdef DEBUG
17 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
18#endif
19
20 __FP_UNPACK_D(A, frA);
21 __FP_UNPACK_D(B, frB);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
25 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
26#endif
27
28 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
29 ret |= EFLAG_VXISI;
30
31 FP_ADD_D(R, A, B);
32
33#ifdef DEBUG
34 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
35#endif
36
37 return (ret | __FP_PACK_D(frD, R));
38}
diff --git a/arch/powerpc/math-emu/fadds.c b/arch/powerpc/math-emu/fadds.c
new file mode 100644
index 000000000000..93025b6c8f3c
--- /dev/null
+++ b/arch/powerpc/math-emu/fadds.c
@@ -0,0 +1,39 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fadds(void *frD, void *frA, void *frB)
11{
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(R);
15 int ret = 0;
16
17#ifdef DEBUG
18 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
19#endif
20
21 __FP_UNPACK_D(A, frA);
22 __FP_UNPACK_D(B, frB);
23
24#ifdef DEBUG
25 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
26 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
27#endif
28
29 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
30 ret |= EFLAG_VXISI;
31
32 FP_ADD_D(R, A, B);
33
34#ifdef DEBUG
35 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
36#endif
37
38 return (ret | __FP_PACK_DS(frD, R));
39}
diff --git a/arch/powerpc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c
new file mode 100644
index 000000000000..4efac394b4cb
--- /dev/null
+++ b/arch/powerpc/math-emu/fcmpo.c
@@ -0,0 +1,46 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
14 long cmp;
15 int ret = 0;
16
17#ifdef DEBUG
18 printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
19#endif
20
21 __FP_UNPACK_D(A, frA);
22 __FP_UNPACK_D(B, frB);
23
24#ifdef DEBUG
25 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
26 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
27#endif
28
29 if (A_c == FP_CLS_NAN || B_c == FP_CLS_NAN)
30 ret |= EFLAG_VXVC;
31
32 FP_CMP_D(cmp, A, B, 2);
33 cmp = code[(cmp + 1) & 3];
34
35 __FPU_FPSCR &= ~(0x1f000);
36 __FPU_FPSCR |= (cmp << 12);
37
38 *ccr &= ~(15 << ((7 - crfD) << 2));
39 *ccr |= (cmp << ((7 - crfD) << 2));
40
41#ifdef DEBUG
42 printk("CR: %08x\n", *ccr);
43#endif
44
45 return ret;
46}
diff --git a/arch/powerpc/math-emu/fcmpu.c b/arch/powerpc/math-emu/fcmpu.c
new file mode 100644
index 000000000000..b7e33176e618
--- /dev/null
+++ b/arch/powerpc/math-emu/fcmpu.c
@@ -0,0 +1,42 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
14 long cmp;
15
16#ifdef DEBUG
17 printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
18#endif
19
20 __FP_UNPACK_D(A, frA);
21 __FP_UNPACK_D(B, frB);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
25 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
26#endif
27
28 FP_CMP_D(cmp, A, B, 2);
29 cmp = code[(cmp + 1) & 3];
30
31 __FPU_FPSCR &= ~(0x1f000);
32 __FPU_FPSCR |= (cmp << 12);
33
34 *ccr &= ~(15 << ((7 - crfD) << 2));
35 *ccr |= (cmp << ((7 - crfD) << 2));
36
37#ifdef DEBUG
38 printk("CR: %08x\n", *ccr);
39#endif
40
41 return 0;
42}
diff --git a/arch/powerpc/math-emu/fctiw.c b/arch/powerpc/math-emu/fctiw.c
new file mode 100644
index 000000000000..3b3c98b840cf
--- /dev/null
+++ b/arch/powerpc/math-emu/fctiw.c
@@ -0,0 +1,25 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fctiw(u32 *frD, void *frB)
10{
11 FP_DECL_D(B);
12 unsigned int r;
13
14 __FP_UNPACK_D(B, frB);
15 FP_TO_INT_D(r, B, 32, 1);
16 frD[1] = r;
17
18#ifdef DEBUG
19 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
20 dump_double(frD);
21 printk("\n");
22#endif
23
24 return 0;
25}
diff --git a/arch/powerpc/math-emu/fctiwz.c b/arch/powerpc/math-emu/fctiwz.c
new file mode 100644
index 000000000000..7717eb6fcfb6
--- /dev/null
+++ b/arch/powerpc/math-emu/fctiwz.c
@@ -0,0 +1,32 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fctiwz(u32 *frD, void *frB)
10{
11 FP_DECL_D(B);
12 u32 fpscr;
13 unsigned int r;
14
15 fpscr = __FPU_FPSCR;
16 __FPU_FPSCR &= ~(3);
17 __FPU_FPSCR |= FP_RND_ZERO;
18
19 __FP_UNPACK_D(B, frB);
20 FP_TO_INT_D(r, B, 32, 1);
21 frD[1] = r;
22
23 __FPU_FPSCR = fpscr;
24
25#ifdef DEBUG
26 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
27 dump_double(frD);
28 printk("\n");
29#endif
30
31 return 0;
32}
diff --git a/arch/powerpc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c
new file mode 100644
index 000000000000..f2fba825b2d0
--- /dev/null
+++ b/arch/powerpc/math-emu/fdiv.c
@@ -0,0 +1,53 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fdiv(void *frD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 FP_DECL_D(R);
14 int ret = 0;
15
16#ifdef DEBUG
17 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
18#endif
19
20 __FP_UNPACK_D(A, frA);
21 __FP_UNPACK_D(B, frB);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
25 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
26#endif
27
28 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
29 ret |= EFLAG_VXZDZ;
30#ifdef DEBUG
31 printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
32#endif
33 }
34 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
35 ret |= EFLAG_VXIDI;
36#ifdef DEBUG
37 printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
38#endif
39 }
40
41 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
42 ret |= EFLAG_DIVZERO;
43 if (__FPU_TRAP_P(EFLAG_DIVZERO))
44 return ret;
45 }
46 FP_DIV_D(R, A, B);
47
48#ifdef DEBUG
49 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
50#endif
51
52 return (ret | __FP_PACK_D(frD, R));
53}
diff --git a/arch/powerpc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c
new file mode 100644
index 000000000000..b971196e3175
--- /dev/null
+++ b/arch/powerpc/math-emu/fdivs.c
@@ -0,0 +1,55 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fdivs(void *frD, void *frA, void *frB)
11{
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(R);
15 int ret = 0;
16
17#ifdef DEBUG
18 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
19#endif
20
21 __FP_UNPACK_D(A, frA);
22 __FP_UNPACK_D(B, frB);
23
24#ifdef DEBUG
25 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
26 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
27#endif
28
29 if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
30 ret |= EFLAG_VXZDZ;
31#ifdef DEBUG
32 printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
33#endif
34 }
35 if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
36 ret |= EFLAG_VXIDI;
37#ifdef DEBUG
38 printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
39#endif
40 }
41
42 if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
43 ret |= EFLAG_DIVZERO;
44 if (__FPU_TRAP_P(EFLAG_DIVZERO))
45 return ret;
46 }
47
48 FP_DIV_D(R, A, B);
49
50#ifdef DEBUG
51 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
52#endif
53
54 return (ret | __FP_PACK_DS(frD, R));
55}
diff --git a/arch/powerpc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c
new file mode 100644
index 000000000000..0a1dbce793e9
--- /dev/null
+++ b/arch/powerpc/math-emu/fmadd.c
@@ -0,0 +1,48 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fmadd(void *frD, void *frA, void *frB, void *frC)
10{
11 FP_DECL_D(R);
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(C);
15 FP_DECL_D(T);
16 int ret = 0;
17
18#ifdef DEBUG
19 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
20#endif
21
22 __FP_UNPACK_D(A, frA);
23 __FP_UNPACK_D(B, frB);
24 __FP_UNPACK_D(C, frC);
25
26#ifdef DEBUG
27 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
28 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
29 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
30#endif
31
32 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
33 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
34 ret |= EFLAG_VXIMZ;
35
36 FP_MUL_D(T, A, C);
37
38 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
39 ret |= EFLAG_VXISI;
40
41 FP_ADD_D(R, T, B);
42
43#ifdef DEBUG
44 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
45#endif
46
47 return (ret | __FP_PACK_D(frD, R));
48}
diff --git a/arch/powerpc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c
new file mode 100644
index 000000000000..0f70bba9445e
--- /dev/null
+++ b/arch/powerpc/math-emu/fmadds.c
@@ -0,0 +1,49 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fmadds(void *frD, void *frA, void *frB, void *frC)
11{
12 FP_DECL_D(R);
13 FP_DECL_D(A);
14 FP_DECL_D(B);
15 FP_DECL_D(C);
16 FP_DECL_D(T);
17 int ret = 0;
18
19#ifdef DEBUG
20 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
21#endif
22
23 __FP_UNPACK_D(A, frA);
24 __FP_UNPACK_D(B, frB);
25 __FP_UNPACK_D(C, frC);
26
27#ifdef DEBUG
28 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
29 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
30 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
31#endif
32
33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
35 ret |= EFLAG_VXIMZ;
36
37 FP_MUL_D(T, A, C);
38
39 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
40 ret |= EFLAG_VXISI;
41
42 FP_ADD_D(R, T, B);
43
44#ifdef DEBUG
45 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
46#endif
47
48 return (ret | __FP_PACK_DS(frD, R));
49}
diff --git a/arch/powerpc/math-emu/fmr.c b/arch/powerpc/math-emu/fmr.c
new file mode 100644
index 000000000000..28df700c0c7e
--- /dev/null
+++ b/arch/powerpc/math-emu/fmr.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6fmr(u32 *frD, u32 *frB)
7{
8 frD[0] = frB[0];
9 frD[1] = frB[1];
10
11#ifdef DEBUG
12 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
13 dump_double(frD);
14 printk("\n");
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c
new file mode 100644
index 000000000000..203fd48a6fec
--- /dev/null
+++ b/arch/powerpc/math-emu/fmsub.c
@@ -0,0 +1,51 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fmsub(void *frD, void *frA, void *frB, void *frC)
10{
11 FP_DECL_D(R);
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(C);
15 FP_DECL_D(T);
16 int ret = 0;
17
18#ifdef DEBUG
19 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
20#endif
21
22 __FP_UNPACK_D(A, frA);
23 __FP_UNPACK_D(B, frB);
24 __FP_UNPACK_D(C, frC);
25
26#ifdef DEBUG
27 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
28 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
29 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
30#endif
31
32 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
33 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
34 ret |= EFLAG_VXIMZ;
35
36 FP_MUL_D(T, A, C);
37
38 if (B_c != FP_CLS_NAN)
39 B_s ^= 1;
40
41 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
42 ret |= EFLAG_VXISI;
43
44 FP_ADD_D(R, T, B);
45
46#ifdef DEBUG
47 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
48#endif
49
50 return (ret | __FP_PACK_D(frD, R));
51}
diff --git a/arch/powerpc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c
new file mode 100644
index 000000000000..8ce68624c189
--- /dev/null
+++ b/arch/powerpc/math-emu/fmsubs.c
@@ -0,0 +1,52 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fmsubs(void *frD, void *frA, void *frB, void *frC)
11{
12 FP_DECL_D(R);
13 FP_DECL_D(A);
14 FP_DECL_D(B);
15 FP_DECL_D(C);
16 FP_DECL_D(T);
17 int ret = 0;
18
19#ifdef DEBUG
20 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
21#endif
22
23 __FP_UNPACK_D(A, frA);
24 __FP_UNPACK_D(B, frB);
25 __FP_UNPACK_D(C, frC);
26
27#ifdef DEBUG
28 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
29 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
30 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
31#endif
32
33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
35 ret |= EFLAG_VXIMZ;
36
37 FP_MUL_D(T, A, C);
38
39 if (B_c != FP_CLS_NAN)
40 B_s ^= 1;
41
42 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
43 ret |= EFLAG_VXISI;
44
45 FP_ADD_D(R, T, B);
46
47#ifdef DEBUG
48 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
49#endif
50
51 return (ret | __FP_PACK_DS(frD, R));
52}
diff --git a/arch/powerpc/math-emu/fmul.c b/arch/powerpc/math-emu/fmul.c
new file mode 100644
index 000000000000..66c7e79aae2e
--- /dev/null
+++ b/arch/powerpc/math-emu/fmul.c
@@ -0,0 +1,42 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fmul(void *frD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 FP_DECL_D(R);
14 int ret = 0;
15
16#ifdef DEBUG
17 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
18#endif
19
20 __FP_UNPACK_D(A, frA);
21 __FP_UNPACK_D(B, frB);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
25 A_s, A_f1, A_f0, A_e, A_c, A_f1, A_f0, A_e + 1023);
26 printk("B: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
27 B_s, B_f1, B_f0, B_e, B_c, B_f1, B_f0, B_e + 1023);
28#endif
29
30 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
31 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
32 ret |= EFLAG_VXIMZ;
33
34 FP_MUL_D(R, A, B);
35
36#ifdef DEBUG
37 printk("D: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
38 R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
39#endif
40
41 return (ret | __FP_PACK_D(frD, R));
42}
diff --git a/arch/powerpc/math-emu/fmuls.c b/arch/powerpc/math-emu/fmuls.c
new file mode 100644
index 000000000000..26bc4278271c
--- /dev/null
+++ b/arch/powerpc/math-emu/fmuls.c
@@ -0,0 +1,43 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fmuls(void *frD, void *frA, void *frB)
11{
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(R);
15 int ret = 0;
16
17#ifdef DEBUG
18 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
19#endif
20
21 __FP_UNPACK_D(A, frA);
22 __FP_UNPACK_D(B, frB);
23
24#ifdef DEBUG
25 printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
26 A_s, A_f1, A_f0, A_e, A_c, A_f1, A_f0, A_e + 1023);
27 printk("B: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
28 B_s, B_f1, B_f0, B_e, B_c, B_f1, B_f0, B_e + 1023);
29#endif
30
31 if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
32 (A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
33 ret |= EFLAG_VXIMZ;
34
35 FP_MUL_D(R, A, B);
36
37#ifdef DEBUG
38 printk("D: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
39 R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
40#endif
41
42 return (ret | __FP_PACK_DS(frD, R));
43}
diff --git a/arch/powerpc/math-emu/fnabs.c b/arch/powerpc/math-emu/fnabs.c
new file mode 100644
index 000000000000..c6b913d179e0
--- /dev/null
+++ b/arch/powerpc/math-emu/fnabs.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6fnabs(u32 *frD, u32 *frB)
7{
8 frD[0] = frB[0] | 0x80000000;
9 frD[1] = frB[1];
10
11#ifdef DEBUG
12 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
13 dump_double(frD);
14 printk("\n");
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/fneg.c b/arch/powerpc/math-emu/fneg.c
new file mode 100644
index 000000000000..fe9a98deff69
--- /dev/null
+++ b/arch/powerpc/math-emu/fneg.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6fneg(u32 *frD, u32 *frB)
7{
8 frD[0] = frB[0] ^ 0x80000000;
9 frD[1] = frB[1];
10
11#ifdef DEBUG
12 printk("%s: D %p, B %p: ", __FUNCTION__, frD, frB);
13 dump_double(frD);
14 printk("\n");
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/fnmadd.c b/arch/powerpc/math-emu/fnmadd.c
new file mode 100644
index 000000000000..7f312276d920
--- /dev/null
+++ b/arch/powerpc/math-emu/fnmadd.c
@@ -0,0 +1,51 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fnmadd(void *frD, void *frA, void *frB, void *frC)
10{
11 FP_DECL_D(R);
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(C);
15 FP_DECL_D(T);
16 int ret = 0;
17
18#ifdef DEBUG
19 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
20#endif
21
22 __FP_UNPACK_D(A, frA);
23 __FP_UNPACK_D(B, frB);
24 __FP_UNPACK_D(C, frC);
25
26#ifdef DEBUG
27 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
28 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
29 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
30#endif
31
32 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
33 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
34 ret |= EFLAG_VXIMZ;
35
36 FP_MUL_D(T, A, C);
37
38 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
39 ret |= EFLAG_VXISI;
40
41 FP_ADD_D(R, T, B);
42
43 if (R_c != FP_CLS_NAN)
44 R_s ^= 1;
45
46#ifdef DEBUG
47 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
48#endif
49
50 return (ret | __FP_PACK_D(frD, R));
51}
diff --git a/arch/powerpc/math-emu/fnmadds.c b/arch/powerpc/math-emu/fnmadds.c
new file mode 100644
index 000000000000..65454c9c70bc
--- /dev/null
+++ b/arch/powerpc/math-emu/fnmadds.c
@@ -0,0 +1,52 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fnmadds(void *frD, void *frA, void *frB, void *frC)
11{
12 FP_DECL_D(R);
13 FP_DECL_D(A);
14 FP_DECL_D(B);
15 FP_DECL_D(C);
16 FP_DECL_D(T);
17 int ret = 0;
18
19#ifdef DEBUG
20 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
21#endif
22
23 __FP_UNPACK_D(A, frA);
24 __FP_UNPACK_D(B, frB);
25 __FP_UNPACK_D(C, frC);
26
27#ifdef DEBUG
28 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
29 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
30 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
31#endif
32
33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
35 ret |= EFLAG_VXIMZ;
36
37 FP_MUL_D(T, A, C);
38
39 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
40 ret |= EFLAG_VXISI;
41
42 FP_ADD_D(R, T, B);
43
44 if (R_c != FP_CLS_NAN)
45 R_s ^= 1;
46
47#ifdef DEBUG
48 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
49#endif
50
51 return (ret | __FP_PACK_DS(frD, R));
52}
diff --git a/arch/powerpc/math-emu/fnmsub.c b/arch/powerpc/math-emu/fnmsub.c
new file mode 100644
index 000000000000..f1ca7482b5f0
--- /dev/null
+++ b/arch/powerpc/math-emu/fnmsub.c
@@ -0,0 +1,54 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fnmsub(void *frD, void *frA, void *frB, void *frC)
10{
11 FP_DECL_D(R);
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(C);
15 FP_DECL_D(T);
16 int ret = 0;
17
18#ifdef DEBUG
19 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
20#endif
21
22 __FP_UNPACK_D(A, frA);
23 __FP_UNPACK_D(B, frB);
24 __FP_UNPACK_D(C, frC);
25
26#ifdef DEBUG
27 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
28 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
29 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
30#endif
31
32 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
33 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
34 ret |= EFLAG_VXIMZ;
35
36 FP_MUL_D(T, A, C);
37
38 if (B_c != FP_CLS_NAN)
39 B_s ^= 1;
40
41 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
42 ret |= EFLAG_VXISI;
43
44 FP_ADD_D(R, T, B);
45
46 if (R_c != FP_CLS_NAN)
47 R_s ^= 1;
48
49#ifdef DEBUG
50 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
51#endif
52
53 return (ret | __FP_PACK_D(frD, R));
54}
diff --git a/arch/powerpc/math-emu/fnmsubs.c b/arch/powerpc/math-emu/fnmsubs.c
new file mode 100644
index 000000000000..5c9a09a87dc7
--- /dev/null
+++ b/arch/powerpc/math-emu/fnmsubs.c
@@ -0,0 +1,55 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fnmsubs(void *frD, void *frA, void *frB, void *frC)
11{
12 FP_DECL_D(R);
13 FP_DECL_D(A);
14 FP_DECL_D(B);
15 FP_DECL_D(C);
16 FP_DECL_D(T);
17 int ret = 0;
18
19#ifdef DEBUG
20 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
21#endif
22
23 __FP_UNPACK_D(A, frA);
24 __FP_UNPACK_D(B, frB);
25 __FP_UNPACK_D(C, frC);
26
27#ifdef DEBUG
28 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
29 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
30 printk("C: %ld %lu %lu %ld (%ld)\n", C_s, C_f1, C_f0, C_e, C_c);
31#endif
32
33 if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
34 (A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
35 ret |= EFLAG_VXIMZ;
36
37 FP_MUL_D(T, A, C);
38
39 if (B_c != FP_CLS_NAN)
40 B_s ^= 1;
41
42 if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
43 ret |= EFLAG_VXISI;
44
45 FP_ADD_D(R, T, B);
46
47 if (R_c != FP_CLS_NAN)
48 R_s ^= 1;
49
50#ifdef DEBUG
51 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
52#endif
53
54 return (ret | __FP_PACK_DS(frD, R));
55}
diff --git a/arch/powerpc/math-emu/fres.c b/arch/powerpc/math-emu/fres.c
new file mode 100644
index 000000000000..ec11e46d20af
--- /dev/null
+++ b/arch/powerpc/math-emu/fres.c
@@ -0,0 +1,12 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6fres(void *frD, void *frB)
7{
8#ifdef DEBUG
9 printk("%s: %p %p\n", __FUNCTION__, frD, frB);
10#endif
11 return -ENOSYS;
12}
diff --git a/arch/powerpc/math-emu/frsp.c b/arch/powerpc/math-emu/frsp.c
new file mode 100644
index 000000000000..d879b2a3d0c9
--- /dev/null
+++ b/arch/powerpc/math-emu/frsp.c
@@ -0,0 +1,25 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10frsp(void *frD, void *frB)
11{
12 FP_DECL_D(B);
13
14#ifdef DEBUG
15 printk("%s: D %p, B %p\n", __FUNCTION__, frD, frB);
16#endif
17
18 __FP_UNPACK_D(B, frB);
19
20#ifdef DEBUG
21 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
22#endif
23
24 return __FP_PACK_DS(frD, B);
25}
diff --git a/arch/powerpc/math-emu/frsqrte.c b/arch/powerpc/math-emu/frsqrte.c
new file mode 100644
index 000000000000..a11ae1829850
--- /dev/null
+++ b/arch/powerpc/math-emu/frsqrte.c
@@ -0,0 +1,12 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6frsqrte(void *frD, void *frB)
7{
8#ifdef DEBUG
9 printk("%s: %p %p\n", __FUNCTION__, frD, frB);
10#endif
11 return 0;
12}
diff --git a/arch/powerpc/math-emu/fsel.c b/arch/powerpc/math-emu/fsel.c
new file mode 100644
index 000000000000..e36e6e72819a
--- /dev/null
+++ b/arch/powerpc/math-emu/fsel.c
@@ -0,0 +1,38 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fsel(u32 *frD, void *frA, u32 *frB, u32 *frC)
10{
11 FP_DECL_D(A);
12
13#ifdef DEBUG
14 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
15#endif
16
17 __FP_UNPACK_D(A, frA);
18
19#ifdef DEBUG
20 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
21 printk("B: %08x %08x\n", frB[0], frB[1]);
22 printk("C: %08x %08x\n", frC[0], frC[1]);
23#endif
24
25 if (A_c == FP_CLS_NAN || (A_c != FP_CLS_ZERO && A_s)) {
26 frD[0] = frB[0];
27 frD[1] = frB[1];
28 } else {
29 frD[0] = frC[0];
30 frD[1] = frC[1];
31 }
32
33#ifdef DEBUG
34 printk("D: %08x.%08x\n", frD[0], frD[1]);
35#endif
36
37 return 0;
38}
diff --git a/arch/powerpc/math-emu/fsqrt.c b/arch/powerpc/math-emu/fsqrt.c
new file mode 100644
index 000000000000..6f8319f64a8a
--- /dev/null
+++ b/arch/powerpc/math-emu/fsqrt.c
@@ -0,0 +1,37 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fsqrt(void *frD, void *frB)
10{
11 FP_DECL_D(B);
12 FP_DECL_D(R);
13 int ret = 0;
14
15#ifdef DEBUG
16 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frB);
17#endif
18
19 __FP_UNPACK_D(B, frB);
20
21#ifdef DEBUG
22 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
23#endif
24
25 if (B_s && B_c != FP_CLS_ZERO)
26 ret |= EFLAG_VXSQRT;
27 if (B_c == FP_CLS_NAN)
28 ret |= EFLAG_VXSNAN;
29
30 FP_SQRT_D(R, B);
31
32#ifdef DEBUG
33 printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
34#endif
35
36 return (ret | __FP_PACK_D(frD, R));
37}
diff --git a/arch/powerpc/math-emu/fsqrts.c b/arch/powerpc/math-emu/fsqrts.c
new file mode 100644
index 000000000000..3b2b1cf55c12
--- /dev/null
+++ b/arch/powerpc/math-emu/fsqrts.c
@@ -0,0 +1,38 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fsqrts(void *frD, void *frB)
11{
12 FP_DECL_D(B);
13 FP_DECL_D(R);
14 int ret = 0;
15
16#ifdef DEBUG
17 printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frB);
18#endif
19
20 __FP_UNPACK_D(B, frB);
21
22#ifdef DEBUG
23 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
24#endif
25
26 if (B_s && B_c != FP_CLS_ZERO)
27 ret |= EFLAG_VXSQRT;
28 if (B_c == FP_CLS_NAN)
29 ret |= EFLAG_VXSNAN;
30
31 FP_SQRT_D(R, B);
32
33#ifdef DEBUG
34 printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
35#endif
36
37 return (ret | __FP_PACK_DS(frD, R));
38}
diff --git a/arch/powerpc/math-emu/fsub.c b/arch/powerpc/math-emu/fsub.c
new file mode 100644
index 000000000000..956679042bb2
--- /dev/null
+++ b/arch/powerpc/math-emu/fsub.c
@@ -0,0 +1,41 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7
8int
9fsub(void *frD, void *frA, void *frB)
10{
11 FP_DECL_D(A);
12 FP_DECL_D(B);
13 FP_DECL_D(R);
14 int ret = 0;
15
16#ifdef DEBUG
17 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
18#endif
19
20 __FP_UNPACK_D(A, frA);
21 __FP_UNPACK_D(B, frB);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
25 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
26#endif
27
28 if (B_c != FP_CLS_NAN)
29 B_s ^= 1;
30
31 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
32 ret |= EFLAG_VXISI;
33
34 FP_ADD_D(R, A, B);
35
36#ifdef DEBUG
37 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
38#endif
39
40 return (ret | __FP_PACK_D(frD, R));
41}
diff --git a/arch/powerpc/math-emu/fsubs.c b/arch/powerpc/math-emu/fsubs.c
new file mode 100644
index 000000000000..3428117dfe8c
--- /dev/null
+++ b/arch/powerpc/math-emu/fsubs.c
@@ -0,0 +1,42 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10fsubs(void *frD, void *frA, void *frB)
11{
12 FP_DECL_D(A);
13 FP_DECL_D(B);
14 FP_DECL_D(R);
15 int ret = 0;
16
17#ifdef DEBUG
18 printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
19#endif
20
21 __FP_UNPACK_D(A, frA);
22 __FP_UNPACK_D(B, frB);
23
24#ifdef DEBUG
25 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
26 printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
27#endif
28
29 if (B_c != FP_CLS_NAN)
30 B_s ^= 1;
31
32 if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
33 ret |= EFLAG_VXISI;
34
35 FP_ADD_D(R, A, B);
36
37#ifdef DEBUG
38 printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
39#endif
40
41 return (ret | __FP_PACK_DS(frD, R));
42}
diff --git a/arch/powerpc/math-emu/lfd.c b/arch/powerpc/math-emu/lfd.c
new file mode 100644
index 000000000000..7d38101c329b
--- /dev/null
+++ b/arch/powerpc/math-emu/lfd.c
@@ -0,0 +1,19 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "sfp-machine.h"
6#include "double.h"
7
8int
9lfd(void *frD, void *ea)
10{
11 if (copy_from_user(frD, ea, sizeof(double)))
12 return -EFAULT;
13#ifdef DEBUG
14 printk("%s: D %p, ea %p: ", __FUNCTION__, frD, ea);
15 dump_double(frD);
16 printk("\n");
17#endif
18 return 0;
19}
diff --git a/arch/powerpc/math-emu/lfs.c b/arch/powerpc/math-emu/lfs.c
new file mode 100644
index 000000000000..c86dee3d7655
--- /dev/null
+++ b/arch/powerpc/math-emu/lfs.c
@@ -0,0 +1,37 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10lfs(void *frD, void *ea)
11{
12 FP_DECL_D(R);
13 FP_DECL_S(A);
14 float f;
15
16#ifdef DEBUG
17 printk("%s: D %p, ea %p\n", __FUNCTION__, frD, ea);
18#endif
19
20 if (copy_from_user(&f, ea, sizeof(float)))
21 return -EFAULT;
22
23 __FP_UNPACK_S(A, &f);
24
25#ifdef DEBUG
26 printk("A: %ld %lu %ld (%ld) [%08lx]\n", A_s, A_f, A_e, A_c,
27 *(unsigned long *)&f);
28#endif
29
30 FP_CONV(D, S, 2, 1, R, A);
31
32#ifdef DEBUG
33 printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
34#endif
35
36 return __FP_PACK_D(frD, R);
37}
diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c
new file mode 100644
index 000000000000..589153472761
--- /dev/null
+++ b/arch/powerpc/math-emu/math.c
@@ -0,0 +1,483 @@
1/*
2 * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com)
3 */
4
5#include <linux/config.h>
6#include <linux/types.h>
7#include <linux/sched.h>
8
9#include <asm/uaccess.h>
10#include <asm/reg.h>
11
12#include "sfp-machine.h"
13#include "double.h"
14
15#define FLOATFUNC(x) extern int x(void *, void *, void *, void *)
16
17FLOATFUNC(fadd);
18FLOATFUNC(fadds);
19FLOATFUNC(fdiv);
20FLOATFUNC(fdivs);
21FLOATFUNC(fmul);
22FLOATFUNC(fmuls);
23FLOATFUNC(fsub);
24FLOATFUNC(fsubs);
25
26FLOATFUNC(fmadd);
27FLOATFUNC(fmadds);
28FLOATFUNC(fmsub);
29FLOATFUNC(fmsubs);
30FLOATFUNC(fnmadd);
31FLOATFUNC(fnmadds);
32FLOATFUNC(fnmsub);
33FLOATFUNC(fnmsubs);
34
35FLOATFUNC(fctiw);
36FLOATFUNC(fctiwz);
37FLOATFUNC(frsp);
38
39FLOATFUNC(fcmpo);
40FLOATFUNC(fcmpu);
41
42FLOATFUNC(mcrfs);
43FLOATFUNC(mffs);
44FLOATFUNC(mtfsb0);
45FLOATFUNC(mtfsb1);
46FLOATFUNC(mtfsf);
47FLOATFUNC(mtfsfi);
48
49FLOATFUNC(lfd);
50FLOATFUNC(lfs);
51
52FLOATFUNC(stfd);
53FLOATFUNC(stfs);
54FLOATFUNC(stfiwx);
55
56FLOATFUNC(fabs);
57FLOATFUNC(fmr);
58FLOATFUNC(fnabs);
59FLOATFUNC(fneg);
60
61/* Optional */
62FLOATFUNC(fres);
63FLOATFUNC(frsqrte);
64FLOATFUNC(fsel);
65FLOATFUNC(fsqrt);
66FLOATFUNC(fsqrts);
67
68
69#define OP31 0x1f /* 31 */
70#define LFS 0x30 /* 48 */
71#define LFSU 0x31 /* 49 */
72#define LFD 0x32 /* 50 */
73#define LFDU 0x33 /* 51 */
74#define STFS 0x34 /* 52 */
75#define STFSU 0x35 /* 53 */
76#define STFD 0x36 /* 54 */
77#define STFDU 0x37 /* 55 */
78#define OP59 0x3b /* 59 */
79#define OP63 0x3f /* 63 */
80
81/* Opcode 31: */
82/* X-Form: */
83#define LFSX 0x217 /* 535 */
84#define LFSUX 0x237 /* 567 */
85#define LFDX 0x257 /* 599 */
86#define LFDUX 0x277 /* 631 */
87#define STFSX 0x297 /* 663 */
88#define STFSUX 0x2b7 /* 695 */
89#define STFDX 0x2d7 /* 727 */
90#define STFDUX 0x2f7 /* 759 */
91#define STFIWX 0x3d7 /* 983 */
92
93/* Opcode 59: */
94/* A-Form: */
95#define FDIVS 0x012 /* 18 */
96#define FSUBS 0x014 /* 20 */
97#define FADDS 0x015 /* 21 */
98#define FSQRTS 0x016 /* 22 */
99#define FRES 0x018 /* 24 */
100#define FMULS 0x019 /* 25 */
101#define FMSUBS 0x01c /* 28 */
102#define FMADDS 0x01d /* 29 */
103#define FNMSUBS 0x01e /* 30 */
104#define FNMADDS 0x01f /* 31 */
105
106/* Opcode 63: */
107/* A-Form: */
108#define FDIV 0x012 /* 18 */
109#define FSUB 0x014 /* 20 */
110#define FADD 0x015 /* 21 */
111#define FSQRT 0x016 /* 22 */
112#define FSEL 0x017 /* 23 */
113#define FMUL 0x019 /* 25 */
114#define FRSQRTE 0x01a /* 26 */
115#define FMSUB 0x01c /* 28 */
116#define FMADD 0x01d /* 29 */
117#define FNMSUB 0x01e /* 30 */
118#define FNMADD 0x01f /* 31 */
119
120/* X-Form: */
121#define FCMPU 0x000 /* 0 */
122#define FRSP 0x00c /* 12 */
123#define FCTIW 0x00e /* 14 */
124#define FCTIWZ 0x00f /* 15 */
125#define FCMPO 0x020 /* 32 */
126#define MTFSB1 0x026 /* 38 */
127#define FNEG 0x028 /* 40 */
128#define MCRFS 0x040 /* 64 */
129#define MTFSB0 0x046 /* 70 */
130#define FMR 0x048 /* 72 */
131#define MTFSFI 0x086 /* 134 */
132#define FNABS 0x088 /* 136 */
133#define FABS 0x108 /* 264 */
134#define MFFS 0x247 /* 583 */
135#define MTFSF 0x2c7 /* 711 */
136
137
138#define AB 2
139#define AC 3
140#define ABC 4
141#define D 5
142#define DU 6
143#define X 7
144#define XA 8
145#define XB 9
146#define XCR 11
147#define XCRB 12
148#define XCRI 13
149#define XCRL 16
150#define XE 14
151#define XEU 15
152#define XFLB 10
153
154#ifdef CONFIG_MATH_EMULATION
155static int
156record_exception(struct pt_regs *regs, int eflag)
157{
158 u32 fpscr;
159
160 fpscr = __FPU_FPSCR;
161
162 if (eflag) {
163 fpscr |= FPSCR_FX;
164 if (eflag & EFLAG_OVERFLOW)
165 fpscr |= FPSCR_OX;
166 if (eflag & EFLAG_UNDERFLOW)
167 fpscr |= FPSCR_UX;
168 if (eflag & EFLAG_DIVZERO)
169 fpscr |= FPSCR_ZX;
170 if (eflag & EFLAG_INEXACT)
171 fpscr |= FPSCR_XX;
172 if (eflag & EFLAG_VXSNAN)
173 fpscr |= FPSCR_VXSNAN;
174 if (eflag & EFLAG_VXISI)
175 fpscr |= FPSCR_VXISI;
176 if (eflag & EFLAG_VXIDI)
177 fpscr |= FPSCR_VXIDI;
178 if (eflag & EFLAG_VXZDZ)
179 fpscr |= FPSCR_VXZDZ;
180 if (eflag & EFLAG_VXIMZ)
181 fpscr |= FPSCR_VXIMZ;
182 if (eflag & EFLAG_VXVC)
183 fpscr |= FPSCR_VXVC;
184 if (eflag & EFLAG_VXSOFT)
185 fpscr |= FPSCR_VXSOFT;
186 if (eflag & EFLAG_VXSQRT)
187 fpscr |= FPSCR_VXSQRT;
188 if (eflag & EFLAG_VXCVI)
189 fpscr |= FPSCR_VXCVI;
190 }
191
192 fpscr &= ~(FPSCR_VX);
193 if (fpscr & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI |
194 FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
195 FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI))
196 fpscr |= FPSCR_VX;
197
198 fpscr &= ~(FPSCR_FEX);
199 if (((fpscr & FPSCR_VX) && (fpscr & FPSCR_VE)) ||
200 ((fpscr & FPSCR_OX) && (fpscr & FPSCR_OE)) ||
201 ((fpscr & FPSCR_UX) && (fpscr & FPSCR_UE)) ||
202 ((fpscr & FPSCR_ZX) && (fpscr & FPSCR_ZE)) ||
203 ((fpscr & FPSCR_XX) && (fpscr & FPSCR_XE)))
204 fpscr |= FPSCR_FEX;
205
206 __FPU_FPSCR = fpscr;
207
208 return (fpscr & FPSCR_FEX) ? 1 : 0;
209}
210#endif /* CONFIG_MATH_EMULATION */
211
212int
213do_mathemu(struct pt_regs *regs)
214{
215 void *op0 = 0, *op1 = 0, *op2 = 0, *op3 = 0;
216 unsigned long pc = regs->nip;
217 signed short sdisp;
218 u32 insn = 0;
219 int idx = 0;
220#ifdef CONFIG_MATH_EMULATION
221 int (*func)(void *, void *, void *, void *);
222 int type = 0;
223 int eflag, trap;
224#endif
225
226 if (get_user(insn, (u32 *)pc))
227 return -EFAULT;
228
229#ifndef CONFIG_MATH_EMULATION
230 switch (insn >> 26) {
231 case LFD:
232 idx = (insn >> 16) & 0x1f;
233 sdisp = (insn & 0xffff);
234 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
235 op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
236 lfd(op0, op1, op2, op3);
237 break;
238 case LFDU:
239 idx = (insn >> 16) & 0x1f;
240 sdisp = (insn & 0xffff);
241 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
242 op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
243 lfd(op0, op1, op2, op3);
244 regs->gpr[idx] = (unsigned long)op1;
245 break;
246 case STFD:
247 idx = (insn >> 16) & 0x1f;
248 sdisp = (insn & 0xffff);
249 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
250 op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
251 stfd(op0, op1, op2, op3);
252 break;
253 case STFDU:
254 idx = (insn >> 16) & 0x1f;
255 sdisp = (insn & 0xffff);
256 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
257 op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
258 stfd(op0, op1, op2, op3);
259 regs->gpr[idx] = (unsigned long)op1;
260 break;
261 case OP63:
262 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
263 op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
264 fmr(op0, op1, op2, op3);
265 break;
266 default:
267 goto illegal;
268 }
269#else /* CONFIG_MATH_EMULATION */
270 switch (insn >> 26) {
271 case LFS: func = lfs; type = D; break;
272 case LFSU: func = lfs; type = DU; break;
273 case LFD: func = lfd; type = D; break;
274 case LFDU: func = lfd; type = DU; break;
275 case STFS: func = stfs; type = D; break;
276 case STFSU: func = stfs; type = DU; break;
277 case STFD: func = stfd; type = D; break;
278 case STFDU: func = stfd; type = DU; break;
279
280 case OP31:
281 switch ((insn >> 1) & 0x3ff) {
282 case LFSX: func = lfs; type = XE; break;
283 case LFSUX: func = lfs; type = XEU; break;
284 case LFDX: func = lfd; type = XE; break;
285 case LFDUX: func = lfd; type = XEU; break;
286 case STFSX: func = stfs; type = XE; break;
287 case STFSUX: func = stfs; type = XEU; break;
288 case STFDX: func = stfd; type = XE; break;
289 case STFDUX: func = stfd; type = XEU; break;
290 case STFIWX: func = stfiwx; type = XE; break;
291 default:
292 goto illegal;
293 }
294 break;
295
296 case OP59:
297 switch ((insn >> 1) & 0x1f) {
298 case FDIVS: func = fdivs; type = AB; break;
299 case FSUBS: func = fsubs; type = AB; break;
300 case FADDS: func = fadds; type = AB; break;
301 case FSQRTS: func = fsqrts; type = AB; break;
302 case FRES: func = fres; type = AB; break;
303 case FMULS: func = fmuls; type = AC; break;
304 case FMSUBS: func = fmsubs; type = ABC; break;
305 case FMADDS: func = fmadds; type = ABC; break;
306 case FNMSUBS: func = fnmsubs; type = ABC; break;
307 case FNMADDS: func = fnmadds; type = ABC; break;
308 default:
309 goto illegal;
310 }
311 break;
312
313 case OP63:
314 if (insn & 0x20) {
315 switch ((insn >> 1) & 0x1f) {
316 case FDIV: func = fdiv; type = AB; break;
317 case FSUB: func = fsub; type = AB; break;
318 case FADD: func = fadd; type = AB; break;
319 case FSQRT: func = fsqrt; type = AB; break;
320 case FSEL: func = fsel; type = ABC; break;
321 case FMUL: func = fmul; type = AC; break;
322 case FRSQRTE: func = frsqrte; type = AB; break;
323 case FMSUB: func = fmsub; type = ABC; break;
324 case FMADD: func = fmadd; type = ABC; break;
325 case FNMSUB: func = fnmsub; type = ABC; break;
326 case FNMADD: func = fnmadd; type = ABC; break;
327 default:
328 goto illegal;
329 }
330 break;
331 }
332
333 switch ((insn >> 1) & 0x3ff) {
334 case FCMPU: func = fcmpu; type = XCR; break;
335 case FRSP: func = frsp; type = XB; break;
336 case FCTIW: func = fctiw; type = XB; break;
337 case FCTIWZ: func = fctiwz; type = XB; break;
338 case FCMPO: func = fcmpo; type = XCR; break;
339 case MTFSB1: func = mtfsb1; type = XCRB; break;
340 case FNEG: func = fneg; type = XB; break;
341 case MCRFS: func = mcrfs; type = XCRL; break;
342 case MTFSB0: func = mtfsb0; type = XCRB; break;
343 case FMR: func = fmr; type = XB; break;
344 case MTFSFI: func = mtfsfi; type = XCRI; break;
345 case FNABS: func = fnabs; type = XB; break;
346 case FABS: func = fabs; type = XB; break;
347 case MFFS: func = mffs; type = X; break;
348 case MTFSF: func = mtfsf; type = XFLB; break;
349 default:
350 goto illegal;
351 }
352 break;
353
354 default:
355 goto illegal;
356 }
357
358 switch (type) {
359 case AB:
360 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
361 op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f];
362 op2 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
363 break;
364
365 case AC:
366 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
367 op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f];
368 op2 = (void *)&current->thread.fpr[(insn >> 6) & 0x1f];
369 break;
370
371 case ABC:
372 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
373 op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f];
374 op2 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
375 op3 = (void *)&current->thread.fpr[(insn >> 6) & 0x1f];
376 break;
377
378 case D:
379 idx = (insn >> 16) & 0x1f;
380 sdisp = (insn & 0xffff);
381 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
382 op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
383 break;
384
385 case DU:
386 idx = (insn >> 16) & 0x1f;
387 if (!idx)
388 goto illegal;
389
390 sdisp = (insn & 0xffff);
391 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
392 op1 = (void *)(regs->gpr[idx] + sdisp);
393 break;
394
395 case X:
396 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
397 break;
398
399 case XA:
400 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
401 op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f];
402 break;
403
404 case XB:
405 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
406 op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
407 break;
408
409 case XE:
410 idx = (insn >> 16) & 0x1f;
411 if (!idx)
412 goto illegal;
413
414 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
415 op1 = (void *)(regs->gpr[idx] + regs->gpr[(insn >> 11) & 0x1f]);
416 break;
417
418 case XEU:
419 idx = (insn >> 16) & 0x1f;
420 op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
421 op1 = (void *)((idx ? regs->gpr[idx] : 0)
422 + regs->gpr[(insn >> 11) & 0x1f]);
423 break;
424
425 case XCR:
426 op0 = (void *)&regs->ccr;
427 op1 = (void *)((insn >> 23) & 0x7);
428 op2 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f];
429 op3 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
430 break;
431
432 case XCRL:
433 op0 = (void *)&regs->ccr;
434 op1 = (void *)((insn >> 23) & 0x7);
435 op2 = (void *)((insn >> 18) & 0x7);
436 break;
437
438 case XCRB:
439 op0 = (void *)((insn >> 21) & 0x1f);
440 break;
441
442 case XCRI:
443 op0 = (void *)((insn >> 23) & 0x7);
444 op1 = (void *)((insn >> 12) & 0xf);
445 break;
446
447 case XFLB:
448 op0 = (void *)((insn >> 17) & 0xff);
449 op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f];
450 break;
451
452 default:
453 goto illegal;
454 }
455
456 eflag = func(op0, op1, op2, op3);
457
458 if (insn & 1) {
459 regs->ccr &= ~(0x0f000000);
460 regs->ccr |= (__FPU_FPSCR >> 4) & 0x0f000000;
461 }
462
463 trap = record_exception(regs, eflag);
464 if (trap)
465 return 1;
466
467 switch (type) {
468 case DU:
469 case XEU:
470 regs->gpr[idx] = (unsigned long)op1;
471 break;
472
473 default:
474 break;
475 }
476#endif /* CONFIG_MATH_EMULATION */
477
478 regs->nip += 4;
479 return 0;
480
481illegal:
482 return -ENOSYS;
483}
diff --git a/arch/powerpc/math-emu/mcrfs.c b/arch/powerpc/math-emu/mcrfs.c
new file mode 100644
index 000000000000..106dd912914b
--- /dev/null
+++ b/arch/powerpc/math-emu/mcrfs.c
@@ -0,0 +1,31 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mcrfs(u32 *ccr, u32 crfD, u32 crfS)
9{
10 u32 value, clear;
11
12#ifdef DEBUG
13 printk("%s: %p (%08x) %d %d\n", __FUNCTION__, ccr, *ccr, crfD, crfS);
14#endif
15
16 clear = 15 << ((7 - crfS) << 2);
17 if (!crfS)
18 clear = 0x90000000;
19
20 value = (__FPU_FPSCR >> ((7 - crfS) << 2)) & 15;
21 __FPU_FPSCR &= ~(clear);
22
23 *ccr &= ~(15 << ((7 - crfD) << 2));
24 *ccr |= (value << ((7 - crfD) << 2));
25
26#ifdef DEBUG
27 printk("CR: %08x\n", __FUNCTION__, *ccr);
28#endif
29
30 return 0;
31}
diff --git a/arch/powerpc/math-emu/mffs.c b/arch/powerpc/math-emu/mffs.c
new file mode 100644
index 000000000000..f477c9170e75
--- /dev/null
+++ b/arch/powerpc/math-emu/mffs.c
@@ -0,0 +1,17 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mffs(u32 *frD)
9{
10 frD[1] = __FPU_FPSCR;
11
12#ifdef DEBUG
13 printk("%s: frD %p: %08x.%08x\n", __FUNCTION__, frD, frD[0], frD[1]);
14#endif
15
16 return 0;
17}
diff --git a/arch/powerpc/math-emu/mtfsb0.c b/arch/powerpc/math-emu/mtfsb0.c
new file mode 100644
index 000000000000..99bfd80f4af3
--- /dev/null
+++ b/arch/powerpc/math-emu/mtfsb0.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mtfsb0(int crbD)
9{
10 if ((crbD != 1) && (crbD != 2))
11 __FPU_FPSCR &= ~(1 << (31 - crbD));
12
13#ifdef DEBUG
14 printk("%s: %d %08lx\n", __FUNCTION__, crbD, __FPU_FPSCR);
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/mtfsb1.c b/arch/powerpc/math-emu/mtfsb1.c
new file mode 100644
index 000000000000..3d9e7ed92d2b
--- /dev/null
+++ b/arch/powerpc/math-emu/mtfsb1.c
@@ -0,0 +1,18 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mtfsb1(int crbD)
9{
10 if ((crbD != 1) && (crbD != 2))
11 __FPU_FPSCR |= (1 << (31 - crbD));
12
13#ifdef DEBUG
14 printk("%s: %d %08lx\n", __FUNCTION__, crbD, __FPU_FPSCR);
15#endif
16
17 return 0;
18}
diff --git a/arch/powerpc/math-emu/mtfsf.c b/arch/powerpc/math-emu/mtfsf.c
new file mode 100644
index 000000000000..d70cf714994c
--- /dev/null
+++ b/arch/powerpc/math-emu/mtfsf.c
@@ -0,0 +1,45 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mtfsf(unsigned int FM, u32 *frB)
9{
10 u32 mask;
11
12 if (FM == 0)
13 return 0;
14
15 if (FM == 0xff)
16 mask = 0x9fffffff;
17 else {
18 mask = 0;
19 if (FM & (1 << 0))
20 mask |= 0x90000000;
21 if (FM & (1 << 1))
22 mask |= 0x0f000000;
23 if (FM & (1 << 2))
24 mask |= 0x00f00000;
25 if (FM & (1 << 3))
26 mask |= 0x000f0000;
27 if (FM & (1 << 4))
28 mask |= 0x0000f000;
29 if (FM & (1 << 5))
30 mask |= 0x00000f00;
31 if (FM & (1 << 6))
32 mask |= 0x000000f0;
33 if (FM & (1 << 7))
34 mask |= 0x0000000f;
35 }
36
37 __FPU_FPSCR &= ~(mask);
38 __FPU_FPSCR |= (frB[1] & mask);
39
40#ifdef DEBUG
41 printk("%s: %02x %p: %08lx\n", __FUNCTION__, FM, frB, __FPU_FPSCR);
42#endif
43
44 return 0;
45}
diff --git a/arch/powerpc/math-emu/mtfsfi.c b/arch/powerpc/math-emu/mtfsfi.c
new file mode 100644
index 000000000000..71df854baa7e
--- /dev/null
+++ b/arch/powerpc/math-emu/mtfsfi.c
@@ -0,0 +1,23 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6
7int
8mtfsfi(unsigned int crfD, unsigned int IMM)
9{
10 u32 mask = 0xf;
11
12 if (!crfD)
13 mask = 9;
14
15 __FPU_FPSCR &= ~(mask << ((7 - crfD) << 2));
16 __FPU_FPSCR |= (IMM & 0xf) << ((7 - crfD) << 2);
17
18#ifdef DEBUG
19 printk("%s: %d %x: %08lx\n", __FUNCTION__, crfD, IMM, __FPU_FPSCR);
20#endif
21
22 return 0;
23}
diff --git a/arch/powerpc/math-emu/op-1.h b/arch/powerpc/math-emu/op-1.h
new file mode 100644
index 000000000000..c92fa95f562e
--- /dev/null
+++ b/arch/powerpc/math-emu/op-1.h
@@ -0,0 +1,245 @@
1/*
2 * Basic one-word fraction declaration and manipulation.
3 */
4
5#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f
6#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f)
7#define _FP_FRAC_SET_1(X,I) (X##_f = I)
8#define _FP_FRAC_HIGH_1(X) (X##_f)
9#define _FP_FRAC_LOW_1(X) (X##_f)
10#define _FP_FRAC_WORD_1(X,w) (X##_f)
11
12#define _FP_FRAC_ADDI_1(X,I) (X##_f += I)
13#define _FP_FRAC_SLL_1(X,N) \
14 do { \
15 if (__builtin_constant_p(N) && (N) == 1) \
16 X##_f += X##_f; \
17 else \
18 X##_f <<= (N); \
19 } while (0)
20#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N)
21
22/* Right shift with sticky-lsb. */
23#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
24
25#define __FP_FRAC_SRS_1(X,N,sz) \
26 (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \
27 ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
28
29#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f)
30#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f)
31#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f)
32
33/* Predicates */
34#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0)
35#define _FP_FRAC_ZEROP_1(X) (X##_f == 0)
36#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
37#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f)
38#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f)
39#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f)
40
41#define _FP_ZEROFRAC_1 0
42#define _FP_MINFRAC_1 1
43
44/*
45 * Unpack the raw bits of a native fp value. Do not classify or
46 * normalize the data.
47 */
48
49#define _FP_UNPACK_RAW_1(fs, X, val) \
50 do { \
51 union _FP_UNION_##fs _flo; _flo.flt = (val); \
52 \
53 X##_f = _flo.bits.frac; \
54 X##_e = _flo.bits.exp; \
55 X##_s = _flo.bits.sign; \
56 } while (0)
57
58
59/*
60 * Repack the raw bits of a native fp value.
61 */
62
63#define _FP_PACK_RAW_1(fs, val, X) \
64 do { \
65 union _FP_UNION_##fs _flo; \
66 \
67 _flo.bits.frac = X##_f; \
68 _flo.bits.exp = X##_e; \
69 _flo.bits.sign = X##_s; \
70 \
71 (val) = _flo.flt; \
72 } while (0)
73
74
75/*
76 * Multiplication algorithms:
77 */
78
79/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
80 multiplication immediately. */
81
82#define _FP_MUL_MEAT_1_imm(fs, R, X, Y) \
83 do { \
84 R##_f = X##_f * Y##_f; \
85 /* Normalize since we know where the msb of the multiplicands \
86 were (bit B), we know that the msb of the of the product is \
87 at either 2B or 2B-1. */ \
88 _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
89 } while (0)
90
91/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
92
93#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit) \
94 do { \
95 _FP_W_TYPE _Z_f0, _Z_f1; \
96 doit(_Z_f1, _Z_f0, X##_f, Y##_f); \
97 /* Normalize since we know where the msb of the multiplicands \
98 were (bit B), we know that the msb of the of the product is \
99 at either 2B or 2B-1. */ \
100 _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
101 R##_f = _Z_f0; \
102 } while (0)
103
104/* Finally, a simple widening multiply algorithm. What fun! */
105
106#define _FP_MUL_MEAT_1_hard(fs, R, X, Y) \
107 do { \
108 _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \
109 \
110 /* split the words in half */ \
111 _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
112 _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
113 _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
114 _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
115 \
116 /* multiply the pieces */ \
117 _z_f0 = _xl * _yl; \
118 _a_f0 = _xh * _yl; \
119 _a_f1 = _xl * _yh; \
120 _z_f1 = _xh * _yh; \
121 \
122 /* reassemble into two full words */ \
123 if ((_a_f0 += _a_f1) < _a_f1) \
124 _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \
125 _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \
126 _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \
127 _FP_FRAC_ADD_2(_z, _z, _a); \
128 \
129 /* normalize */ \
130 _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs); \
131 R##_f = _z_f0; \
132 } while (0)
133
134
135/*
136 * Division algorithms:
137 */
138
139/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
140 division immediately. Give this macro either _FP_DIV_HELP_imm for
141 C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you
142 choose will depend on what the compiler does with divrem4. */
143
144#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
145 do { \
146 _FP_W_TYPE _q, _r; \
147 X##_f <<= (X##_f < Y##_f \
148 ? R##_e--, _FP_WFRACBITS_##fs \
149 : _FP_WFRACBITS_##fs - 1); \
150 doit(_q, _r, X##_f, Y##_f); \
151 R##_f = _q | (_r != 0); \
152 } while (0)
153
154/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
155 that may be useful in this situation. This first is for a primitive
156 that requires normalization, the second for one that does not. Look
157 for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */
158
159#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
160 do { \
161 _FP_W_TYPE _nh, _nl, _q, _r; \
162 \
163 /* Normalize Y -- i.e. make the most significant bit set. */ \
164 Y##_f <<= _FP_WFRACXBITS_##fs - 1; \
165 \
166 /* Shift X op correspondingly high, that is, up one full word. */ \
167 if (X##_f <= Y##_f) \
168 { \
169 _nl = 0; \
170 _nh = X##_f; \
171 } \
172 else \
173 { \
174 R##_e++; \
175 _nl = X##_f << (_FP_W_TYPE_SIZE-1); \
176 _nh = X##_f >> 1; \
177 } \
178 \
179 udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
180 R##_f = _q | (_r != 0); \
181 } while (0)
182
183#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
184 do { \
185 _FP_W_TYPE _nh, _nl, _q, _r; \
186 if (X##_f < Y##_f) \
187 { \
188 R##_e--; \
189 _nl = X##_f << _FP_WFRACBITS_##fs; \
190 _nh = X##_f >> _FP_WFRACXBITS_##fs; \
191 } \
192 else \
193 { \
194 _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
195 _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
196 } \
197 udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
198 R##_f = _q | (_r != 0); \
199 } while (0)
200
201
202/*
203 * Square root algorithms:
204 * We have just one right now, maybe Newton approximation
205 * should be added for those machines where division is fast.
206 */
207
208#define _FP_SQRT_MEAT_1(R, S, T, X, q) \
209 do { \
210 while (q) \
211 { \
212 T##_f = S##_f + q; \
213 if (T##_f <= X##_f) \
214 { \
215 S##_f = T##_f + q; \
216 X##_f -= T##_f; \
217 R##_f += q; \
218 } \
219 _FP_FRAC_SLL_1(X, 1); \
220 q >>= 1; \
221 } \
222 } while (0)
223
224/*
225 * Assembly/disassembly for converting to/from integral types.
226 * No shifting or overflow handled here.
227 */
228
229#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
230#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
231
232
233/*
234 * Convert FP values between word sizes
235 */
236
237#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S) \
238 do { \
239 D##_f = S##_f; \
240 if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs) \
241 _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs), \
242 _FP_WFRACBITS_##sfs); \
243 else \
244 D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs; \
245 } while (0)
diff --git a/arch/powerpc/math-emu/op-2.h b/arch/powerpc/math-emu/op-2.h
new file mode 100644
index 000000000000..b9b06b4c6ea1
--- /dev/null
+++ b/arch/powerpc/math-emu/op-2.h
@@ -0,0 +1,433 @@
1/*
2 * Basic two-word fraction declaration and manipulation.
3 */
4
5#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
6#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
7#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
8#define _FP_FRAC_HIGH_2(X) (X##_f1)
9#define _FP_FRAC_LOW_2(X) (X##_f0)
10#define _FP_FRAC_WORD_2(X,w) (X##_f##w)
11
12#define _FP_FRAC_SLL_2(X,N) \
13 do { \
14 if ((N) < _FP_W_TYPE_SIZE) \
15 { \
16 if (__builtin_constant_p(N) && (N) == 1) \
17 { \
18 X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \
19 X##_f0 += X##_f0; \
20 } \
21 else \
22 { \
23 X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
24 X##_f0 <<= (N); \
25 } \
26 } \
27 else \
28 { \
29 X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \
30 X##_f0 = 0; \
31 } \
32 } while (0)
33
34#define _FP_FRAC_SRL_2(X,N) \
35 do { \
36 if ((N) < _FP_W_TYPE_SIZE) \
37 { \
38 X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
39 X##_f1 >>= (N); \
40 } \
41 else \
42 { \
43 X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \
44 X##_f1 = 0; \
45 } \
46 } while (0)
47
48/* Right shift with sticky-lsb. */
49#define _FP_FRAC_SRS_2(X,N,sz) \
50 do { \
51 if ((N) < _FP_W_TYPE_SIZE) \
52 { \
53 X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
54 (__builtin_constant_p(N) && (N) == 1 \
55 ? X##_f0 & 1 \
56 : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \
57 X##_f1 >>= (N); \
58 } \
59 else \
60 { \
61 X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
62 (((X##_f1 << (sz - (N))) | X##_f0) != 0)); \
63 X##_f1 = 0; \
64 } \
65 } while (0)
66
67#define _FP_FRAC_ADDI_2(X,I) \
68 __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
69
70#define _FP_FRAC_ADD_2(R,X,Y) \
71 __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
72
73#define _FP_FRAC_SUB_2(R,X,Y) \
74 __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
75
76#define _FP_FRAC_CLZ_2(R,X) \
77 do { \
78 if (X##_f1) \
79 __FP_CLZ(R,X##_f1); \
80 else \
81 { \
82 __FP_CLZ(R,X##_f0); \
83 R += _FP_W_TYPE_SIZE; \
84 } \
85 } while(0)
86
87/* Predicates */
88#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)
89#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)
90#define _FP_FRAC_OVERP_2(fs,X) (X##_f1 & _FP_OVERFLOW_##fs)
91#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
92#define _FP_FRAC_GT_2(X, Y) \
93 ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
94#define _FP_FRAC_GE_2(X, Y) \
95 ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
96
97#define _FP_ZEROFRAC_2 0, 0
98#define _FP_MINFRAC_2 0, 1
99
100/*
101 * Internals
102 */
103
104#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)
105
106#define __FP_CLZ_2(R, xh, xl) \
107 do { \
108 if (xh) \
109 __FP_CLZ(R,xl); \
110 else \
111 { \
112 __FP_CLZ(R,xl); \
113 R += _FP_W_TYPE_SIZE; \
114 } \
115 } while(0)
116
117#if 0
118
119#ifndef __FP_FRAC_ADDI_2
120#define __FP_FRAC_ADDI_2(xh, xl, i) \
121 (xh += ((xl += i) < i))
122#endif
123#ifndef __FP_FRAC_ADD_2
124#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
125 (rh = xh + yh + ((rl = xl + yl) < xl))
126#endif
127#ifndef __FP_FRAC_SUB_2
128#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
129 (rh = xh - yh - ((rl = xl - yl) > xl))
130#endif
131
132#else
133
134#undef __FP_FRAC_ADDI_2
135#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)
136#undef __FP_FRAC_ADD_2
137#define __FP_FRAC_ADD_2 add_ssaaaa
138#undef __FP_FRAC_SUB_2
139#define __FP_FRAC_SUB_2 sub_ddmmss
140
141#endif
142
143/*
144 * Unpack the raw bits of a native fp value. Do not classify or
145 * normalize the data.
146 */
147
148#define _FP_UNPACK_RAW_2(fs, X, val) \
149 do { \
150 union _FP_UNION_##fs _flo; _flo.flt = (val); \
151 \
152 X##_f0 = _flo.bits.frac0; \
153 X##_f1 = _flo.bits.frac1; \
154 X##_e = _flo.bits.exp; \
155 X##_s = _flo.bits.sign; \
156 } while (0)
157
158
159/*
160 * Repack the raw bits of a native fp value.
161 */
162
163#define _FP_PACK_RAW_2(fs, val, X) \
164 do { \
165 union _FP_UNION_##fs _flo; \
166 \
167 _flo.bits.frac0 = X##_f0; \
168 _flo.bits.frac1 = X##_f1; \
169 _flo.bits.exp = X##_e; \
170 _flo.bits.sign = X##_s; \
171 \
172 (val) = _flo.flt; \
173 } while (0)
174
175
176/*
177 * Multiplication algorithms:
178 */
179
180/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
181
182#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit) \
183 do { \
184 _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
185 \
186 doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
187 doit(_b_f1, _b_f0, X##_f0, Y##_f1); \
188 doit(_c_f1, _c_f0, X##_f1, Y##_f0); \
189 doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
190 \
191 __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
192 _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \
193 0, _b_f1, _b_f0, 0, \
194 _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
195 _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \
196 __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
197 _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \
198 0, _c_f1, _c_f0, 0, \
199 _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
200 _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \
201 \
202 /* Normalize since we know where the msb of the multiplicands \
203 were (bit B), we know that the msb of the of the product is \
204 at either 2B or 2B-1. */ \
205 _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
206 R##_f0 = _FP_FRAC_WORD_4(_z,0); \
207 R##_f1 = _FP_FRAC_WORD_4(_z,1); \
208 } while (0)
209
210/* This next macro appears to be totally broken. Fortunately nowhere
211 * seems to use it :-> The problem is that we define _z[4] but
212 * then use it in _FP_FRAC_SRS_4, which will attempt to access
213 * _z_f[n] which will cause an error. The fix probably involves
214 * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998
215 */
216#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y) \
217 do { \
218 _FP_W_TYPE _x[2], _y[2], _z[4]; \
219 _x[0] = X##_f0; _x[1] = X##_f1; \
220 _y[0] = Y##_f0; _y[1] = Y##_f1; \
221 \
222 mpn_mul_n(_z, _x, _y, 2); \
223 \
224 /* Normalize since we know where the msb of the multiplicands \
225 were (bit B), we know that the msb of the of the product is \
226 at either 2B or 2B-1. */ \
227 _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs); \
228 R##_f0 = _z[0]; \
229 R##_f1 = _z[1]; \
230 } while (0)
231
232
233/*
234 * Division algorithms:
235 * This seems to be giving me difficulties -- PMM
236 * Look, NetBSD seems to be able to comment algorithms. Can't you?
237 * I've thrown printks at the problem.
238 * This now appears to work, but I still don't really know why.
239 * Also, I don't think the result is properly normalised...
240 */
241
242#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y) \
243 do { \
244 extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2], \
245 _FP_W_TYPE n1, _FP_W_TYPE n0, \
246 _FP_W_TYPE d1, _FP_W_TYPE d0); \
247 _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0; \
248 _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0; \
249 _FP_W_TYPE _rmem[2], _qmem[2]; \
250 /* I think this check is to ensure that the result is normalised. \
251 * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in \
252 * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y. \
253 * In this case we tweak things. (this is based on comments in \
254 * the NetBSD FPU emulation code. ) \
255 * We know X,Y are normalised because we ensure this as part of \
256 * the unpacking process. -- PMM \
257 */ \
258 if (_FP_FRAC_GT_2(X, Y)) \
259 { \
260/* R##_e++; */ \
261 _n_f3 = X##_f1 >> 1; \
262 _n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
263 _n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \
264 _n_f0 = 0; \
265 } \
266 else \
267 { \
268 R##_e--; \
269 _n_f3 = X##_f1; \
270 _n_f2 = X##_f0; \
271 _n_f1 = _n_f0 = 0; \
272 } \
273 \
274 /* Normalize, i.e. make the most significant bit of the \
275 denominator set. CHANGED: - 1 to nothing -- PMM */ \
276 _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */); \
277 \
278 /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4 \
279 primitive snagged from libgcc2.c. */ \
280 \
281 _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1); \
282 _q_f1 = _qmem[0]; \
283 umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0); \
284 _r_f1 = _rmem[0]; \
285 _r_f0 = _n_f1; \
286 if (_FP_FRAC_GT_2(_m, _r)) \
287 { \
288 _q_f1--; \
289 _FP_FRAC_ADD_2(_r, _r, Y); \
290 if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
291 { \
292 _q_f1--; \
293 _FP_FRAC_ADD_2(_r, _r, Y); \
294 } \
295 } \
296 _FP_FRAC_SUB_2(_r, _r, _m); \
297 \
298 _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1); \
299 _q_f0 = _qmem[0]; \
300 umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0); \
301 _r_f1 = _rmem[0]; \
302 _r_f0 = _n_f0; \
303 if (_FP_FRAC_GT_2(_m, _r)) \
304 { \
305 _q_f0--; \
306 _FP_FRAC_ADD_2(_r, _r, Y); \
307 if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
308 { \
309 _q_f0--; \
310 _FP_FRAC_ADD_2(_r, _r, Y); \
311 } \
312 } \
313 _FP_FRAC_SUB_2(_r, _r, _m); \
314 \
315 R##_f1 = _q_f1; \
316 R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0); \
317 /* adjust so answer is normalized again. I'm not sure what the \
318 * final sz param should be. In practice it's never used since \
319 * N is 1 which is always going to be < _FP_W_TYPE_SIZE... \
320 */ \
321 /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs); */ \
322 } while (0)
323
324
325#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \
326 do { \
327 _FP_W_TYPE _x[4], _y[2], _z[4]; \
328 _y[0] = Y##_f0; _y[1] = Y##_f1; \
329 _x[0] = _x[3] = 0; \
330 if (_FP_FRAC_GT_2(X, Y)) \
331 { \
332 R##_e++; \
333 _x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) | \
334 X##_f1 >> (_FP_W_TYPE_SIZE - \
335 (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE))); \
336 _x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE); \
337 } \
338 else \
339 { \
340 _x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) | \
341 X##_f1 >> (_FP_W_TYPE_SIZE - \
342 (_FP_WFRACBITS - _FP_W_TYPE_SIZE))); \
343 _x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE); \
344 } \
345 \
346 (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \
347 R##_f1 = _z[1]; \
348 R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \
349 } while (0)
350
351
352/*
353 * Square root algorithms:
354 * We have just one right now, maybe Newton approximation
355 * should be added for those machines where division is fast.
356 */
357
358#define _FP_SQRT_MEAT_2(R, S, T, X, q) \
359 do { \
360 while (q) \
361 { \
362 T##_f1 = S##_f1 + q; \
363 if (T##_f1 <= X##_f1) \
364 { \
365 S##_f1 = T##_f1 + q; \
366 X##_f1 -= T##_f1; \
367 R##_f1 += q; \
368 } \
369 _FP_FRAC_SLL_2(X, 1); \
370 q >>= 1; \
371 } \
372 q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
373 while (q) \
374 { \
375 T##_f0 = S##_f0 + q; \
376 T##_f1 = S##_f1; \
377 if (T##_f1 < X##_f1 || \
378 (T##_f1 == X##_f1 && T##_f0 < X##_f0)) \
379 { \
380 S##_f0 = T##_f0 + q; \
381 if (((_FP_WS_TYPE)T##_f0) < 0 && \
382 ((_FP_WS_TYPE)S##_f0) >= 0) \
383 S##_f1++; \
384 _FP_FRAC_SUB_2(X, X, T); \
385 R##_f0 += q; \
386 } \
387 _FP_FRAC_SLL_2(X, 1); \
388 q >>= 1; \
389 } \
390 } while (0)
391
392
393/*
394 * Assembly/disassembly for converting to/from integral types.
395 * No shifting or overflow handled here.
396 */
397
398#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
399 do { \
400 if (rsize <= _FP_W_TYPE_SIZE) \
401 r = X##_f0; \
402 else \
403 { \
404 r = X##_f1; \
405 r <<= _FP_W_TYPE_SIZE; \
406 r += X##_f0; \
407 } \
408 } while (0)
409
410#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \
411 do { \
412 X##_f0 = r; \
413 X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
414 } while (0)
415
416/*
417 * Convert FP values between word sizes
418 */
419
420#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S) \
421 do { \
422 _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
423 _FP_WFRACBITS_##sfs); \
424 D##_f = S##_f0; \
425 } while (0)
426
427#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S) \
428 do { \
429 D##_f0 = S##_f; \
430 D##_f1 = 0; \
431 _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
432 } while (0)
433
diff --git a/arch/powerpc/math-emu/op-4.h b/arch/powerpc/math-emu/op-4.h
new file mode 100644
index 000000000000..fcdd6d064c54
--- /dev/null
+++ b/arch/powerpc/math-emu/op-4.h
@@ -0,0 +1,297 @@
1/*
2 * Basic four-word fraction declaration and manipulation.
3 *
4 * When adding quadword support for 32 bit machines, we need
5 * to be a little careful as double multiply uses some of these
6 * macros: (in op-2.h)
7 * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
8 * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
9 * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
10 * _FP_FRAC_DECL_4: it appears to be broken and is not used
11 * anywhere anyway. )
12 *
13 * I've now fixed all the macros that were here from the sparc64 code.
14 * [*none* of the shift macros were correct!] -- PMM 02/1998
15 *
16 * The only quadword stuff that remains to be coded is:
17 * 1) the conversion to/from ints, which requires
18 * that we check (in op-common.h) that the following do the right thing
19 * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
20 * 2) multiply, divide and sqrt, which require:
21 * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q),
22 * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to
23 * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h.
24 * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for
25 * these; they are used nowhere else. ]
26 */
27
28#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
29#define _FP_FRAC_COPY_4(D,S) \
30 (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
31 D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
32/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
33 * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
34 * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
35 * which just assigns the In values to the array X##_f[].
36 * This is why the number of parameters doesn't appear to match
37 * at first glance... -- PMM
38 */
39#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I)
40#define _FP_FRAC_HIGH_4(X) (X##_f[3])
41#define _FP_FRAC_LOW_4(X) (X##_f[0])
42#define _FP_FRAC_WORD_4(X,w) (X##_f[w])
43
44#define _FP_FRAC_SLL_4(X,N) \
45 do { \
46 _FP_I_TYPE _up, _down, _skip, _i; \
47 _skip = (N) / _FP_W_TYPE_SIZE; \
48 _up = (N) % _FP_W_TYPE_SIZE; \
49 _down = _FP_W_TYPE_SIZE - _up; \
50 for (_i = 3; _i > _skip; --_i) \
51 X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down; \
52/* bugfixed: was X##_f[_i] <<= _up; -- PMM 02/1998 */ \
53 X##_f[_i] = X##_f[0] << _up; \
54 for (--_i; _i >= 0; --_i) \
55 X##_f[_i] = 0; \
56 } while (0)
57
58/* This one was broken too */
59#define _FP_FRAC_SRL_4(X,N) \
60 do { \
61 _FP_I_TYPE _up, _down, _skip, _i; \
62 _skip = (N) / _FP_W_TYPE_SIZE; \
63 _down = (N) % _FP_W_TYPE_SIZE; \
64 _up = _FP_W_TYPE_SIZE - _down; \
65 for (_i = 0; _i < 3-_skip; ++_i) \
66 X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
67 X##_f[_i] = X##_f[3] >> _down; \
68 for (++_i; _i < 4; ++_i) \
69 X##_f[_i] = 0; \
70 } while (0)
71
72
73/* Right shift with sticky-lsb.
74 * What this actually means is that we do a standard right-shift,
75 * but that if any of the bits that fall off the right hand side
76 * were one then we always set the LSbit.
77 */
78#define _FP_FRAC_SRS_4(X,N,size) \
79 do { \
80 _FP_I_TYPE _up, _down, _skip, _i; \
81 _FP_W_TYPE _s; \
82 _skip = (N) / _FP_W_TYPE_SIZE; \
83 _down = (N) % _FP_W_TYPE_SIZE; \
84 _up = _FP_W_TYPE_SIZE - _down; \
85 for (_s = _i = 0; _i < _skip; ++_i) \
86 _s |= X##_f[_i]; \
87 _s |= X##_f[_i] << _up; \
88/* s is now != 0 if we want to set the LSbit */ \
89 for (_i = 0; _i < 3-_skip; ++_i) \
90 X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
91 X##_f[_i] = X##_f[3] >> _down; \
92 for (++_i; _i < 4; ++_i) \
93 X##_f[_i] = 0; \
94 /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
95 X##_f[0] |= (_s != 0); \
96 } while (0)
97
98#define _FP_FRAC_ADD_4(R,X,Y) \
99 __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
100 X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
101 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
102
103#define _FP_FRAC_SUB_4(R,X,Y) \
104 __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
105 X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
106 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
107
108#define _FP_FRAC_ADDI_4(X,I) \
109 __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
110
111#define _FP_ZEROFRAC_4 0,0,0,0
112#define _FP_MINFRAC_4 0,0,0,1
113
114#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
115#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0)
116#define _FP_FRAC_OVERP_4(fs,X) (X##_f[0] & _FP_OVERFLOW_##fs)
117
118#define _FP_FRAC_EQ_4(X,Y) \
119 (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
120 && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
121
122#define _FP_FRAC_GT_4(X,Y) \
123 (X##_f[3] > Y##_f[3] || \
124 (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
125 (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
126 (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \
127 )) \
128 )) \
129 )
130
131#define _FP_FRAC_GE_4(X,Y) \
132 (X##_f[3] > Y##_f[3] || \
133 (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
134 (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
135 (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \
136 )) \
137 )) \
138 )
139
140
141#define _FP_FRAC_CLZ_4(R,X) \
142 do { \
143 if (X##_f[3]) \
144 { \
145 __FP_CLZ(R,X##_f[3]); \
146 } \
147 else if (X##_f[2]) \
148 { \
149 __FP_CLZ(R,X##_f[2]); \
150 R += _FP_W_TYPE_SIZE; \
151 } \
152 else if (X##_f[1]) \
153 { \
154 __FP_CLZ(R,X##_f[2]); \
155 R += _FP_W_TYPE_SIZE*2; \
156 } \
157 else \
158 { \
159 __FP_CLZ(R,X##_f[0]); \
160 R += _FP_W_TYPE_SIZE*3; \
161 } \
162 } while(0)
163
164
165#define _FP_UNPACK_RAW_4(fs, X, val) \
166 do { \
167 union _FP_UNION_##fs _flo; _flo.flt = (val); \
168 X##_f[0] = _flo.bits.frac0; \
169 X##_f[1] = _flo.bits.frac1; \
170 X##_f[2] = _flo.bits.frac2; \
171 X##_f[3] = _flo.bits.frac3; \
172 X##_e = _flo.bits.exp; \
173 X##_s = _flo.bits.sign; \
174 } while (0)
175
176#define _FP_PACK_RAW_4(fs, val, X) \
177 do { \
178 union _FP_UNION_##fs _flo; \
179 _flo.bits.frac0 = X##_f[0]; \
180 _flo.bits.frac1 = X##_f[1]; \
181 _flo.bits.frac2 = X##_f[2]; \
182 _flo.bits.frac3 = X##_f[3]; \
183 _flo.bits.exp = X##_e; \
184 _flo.bits.sign = X##_s; \
185 (val) = _flo.flt; \
186 } while (0)
187
188
189/*
190 * Internals
191 */
192
193#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \
194 (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
195
196#ifndef __FP_FRAC_ADD_4
197#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
198 (r0 = x0 + y0, \
199 r1 = x1 + y1 + (r0 < x0), \
200 r2 = x2 + y2 + (r1 < x1), \
201 r3 = x3 + y3 + (r2 < x2))
202#endif
203
204#ifndef __FP_FRAC_SUB_4
205#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
206 (r0 = x0 - y0, \
207 r1 = x1 - y1 - (r0 > x0), \
208 r2 = x2 - y2 - (r1 > x1), \
209 r3 = x3 - y3 - (r2 > x2))
210#endif
211
212#ifndef __FP_FRAC_ADDI_4
213/* I always wanted to be a lisp programmer :-> */
214#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
215 (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2)))
216#endif
217
218/* Convert FP values between word sizes. This appears to be more
219 * complicated than I'd have expected it to be, so these might be
220 * wrong... These macros are in any case somewhat bogus because they
221 * use information about what various FRAC_n variables look like
222 * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
223 * the ones in op-2.h and op-1.h.
224 */
225#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \
226 do { \
227 _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
228 _FP_WFRACBITS_##sfs); \
229 D##_f = S##_f[0]; \
230 } while (0)
231
232#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S) \
233 do { \
234 _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
235 _FP_WFRACBITS_##sfs); \
236 D##_f0 = S##_f[0]; \
237 D##_f1 = S##_f[1]; \
238 } while (0)
239
240/* Assembly/disassembly for converting to/from integral types.
241 * No shifting or overflow handled here.
242 */
243/* Put the FP value X into r, which is an integer of size rsize. */
244#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
245 do { \
246 if (rsize <= _FP_W_TYPE_SIZE) \
247 r = X##_f[0]; \
248 else if (rsize <= 2*_FP_W_TYPE_SIZE) \
249 { \
250 r = X##_f[1]; \
251 r <<= _FP_W_TYPE_SIZE; \
252 r += X##_f[0]; \
253 } \
254 else \
255 { \
256 /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
257 /* and int == 4words as a single case. */ \
258 r = X##_f[3]; \
259 r <<= _FP_W_TYPE_SIZE; \
260 r += X##_f[2]; \
261 r <<= _FP_W_TYPE_SIZE; \
262 r += X##_f[1]; \
263 r <<= _FP_W_TYPE_SIZE; \
264 r += X##_f[0]; \
265 } \
266 } while (0)
267
268/* "No disassemble Number Five!" */
269/* move an integer of size rsize into X's fractional part. We rely on
270 * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
271 * having to mask the values we store into it.
272 */
273#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
274 do { \
275 X##_f[0] = r; \
276 X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
277 X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
278 X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
279 } while (0)
280
281#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \
282 do { \
283 D##_f[0] = S##_f; \
284 D##_f[1] = D##_f[2] = D##_f[3] = 0; \
285 _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
286 } while (0)
287
288#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S) \
289 do { \
290 D##_f[0] = S##_f0; \
291 D##_f[1] = S##_f1; \
292 D##_f[2] = D##_f[3] = 0; \
293 _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
294 } while (0)
295
296/* FIXME! This has to be written */
297#define _FP_SQRT_MEAT_4(R, S, T, X, q)
diff --git a/arch/powerpc/math-emu/op-common.h b/arch/powerpc/math-emu/op-common.h
new file mode 100644
index 000000000000..afb82b6498ce
--- /dev/null
+++ b/arch/powerpc/math-emu/op-common.h
@@ -0,0 +1,688 @@
1#define _FP_DECL(wc, X) \
2 _FP_I_TYPE X##_c, X##_s, X##_e; \
3 _FP_FRAC_DECL_##wc(X)
4
5/*
6 * Finish truely unpacking a native fp value by classifying the kind
7 * of fp value and normalizing both the exponent and the fraction.
8 */
9
10#define _FP_UNPACK_CANONICAL(fs, wc, X) \
11do { \
12 switch (X##_e) \
13 { \
14 default: \
15 _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \
16 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
17 X##_e -= _FP_EXPBIAS_##fs; \
18 X##_c = FP_CLS_NORMAL; \
19 break; \
20 \
21 case 0: \
22 if (_FP_FRAC_ZEROP_##wc(X)) \
23 X##_c = FP_CLS_ZERO; \
24 else \
25 { \
26 /* a denormalized number */ \
27 _FP_I_TYPE _shift; \
28 _FP_FRAC_CLZ_##wc(_shift, X); \
29 _shift -= _FP_FRACXBITS_##fs; \
30 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
31 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
32 X##_c = FP_CLS_NORMAL; \
33 } \
34 break; \
35 \
36 case _FP_EXPMAX_##fs: \
37 if (_FP_FRAC_ZEROP_##wc(X)) \
38 X##_c = FP_CLS_INF; \
39 else \
40 /* we don't differentiate between signaling and quiet nans */ \
41 X##_c = FP_CLS_NAN; \
42 break; \
43 } \
44} while (0)
45
46
47/*
48 * Before packing the bits back into the native fp result, take care
49 * of such mundane things as rounding and overflow. Also, for some
50 * kinds of fp values, the original parts may not have been fully
51 * extracted -- but that is ok, we can regenerate them now.
52 */
53
54#define _FP_PACK_CANONICAL(fs, wc, X) \
55({int __ret = 0; \
56 switch (X##_c) \
57 { \
58 case FP_CLS_NORMAL: \
59 X##_e += _FP_EXPBIAS_##fs; \
60 if (X##_e > 0) \
61 { \
62 __ret |= _FP_ROUND(wc, X); \
63 if (_FP_FRAC_OVERP_##wc(fs, X)) \
64 { \
65 _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
66 X##_e++; \
67 } \
68 else \
69 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
70 if (X##_e >= _FP_EXPMAX_##fs) \
71 { \
72 /* overflow to infinity */ \
73 X##_e = _FP_EXPMAX_##fs; \
74 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
75 __ret |= EFLAG_OVERFLOW; \
76 } \
77 } \
78 else \
79 { \
80 /* we've got a denormalized number */ \
81 X##_e = -X##_e + 1; \
82 if (X##_e <= _FP_WFRACBITS_##fs) \
83 { \
84 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
85 _FP_FRAC_SLL_##wc(X, 1); \
86 if (_FP_FRAC_OVERP_##wc(fs, X)) \
87 { \
88 X##_e = 1; \
89 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
90 } \
91 else \
92 { \
93 X##_e = 0; \
94 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
95 __ret |= EFLAG_UNDERFLOW; \
96 } \
97 } \
98 else \
99 { \
100 /* underflow to zero */ \
101 X##_e = 0; \
102 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
103 __ret |= EFLAG_UNDERFLOW; \
104 } \
105 } \
106 break; \
107 \
108 case FP_CLS_ZERO: \
109 X##_e = 0; \
110 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
111 break; \
112 \
113 case FP_CLS_INF: \
114 X##_e = _FP_EXPMAX_##fs; \
115 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
116 break; \
117 \
118 case FP_CLS_NAN: \
119 X##_e = _FP_EXPMAX_##fs; \
120 if (!_FP_KEEPNANFRACP) \
121 { \
122 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
123 X##_s = 0; \
124 } \
125 else \
126 _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
127 break; \
128 } \
129 __ret; \
130})
131
132
133/*
134 * Main addition routine. The input values should be cooked.
135 */
136
137#define _FP_ADD(fs, wc, R, X, Y) \
138do { \
139 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
140 { \
141 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
142 { \
143 /* shift the smaller number so that its exponent matches the larger */ \
144 _FP_I_TYPE diff = X##_e - Y##_e; \
145 \
146 if (diff < 0) \
147 { \
148 diff = -diff; \
149 if (diff <= _FP_WFRACBITS_##fs) \
150 _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
151 else if (!_FP_FRAC_ZEROP_##wc(X)) \
152 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
153 else \
154 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
155 R##_e = Y##_e; \
156 } \
157 else \
158 { \
159 if (diff > 0) \
160 { \
161 if (diff <= _FP_WFRACBITS_##fs) \
162 _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
163 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
164 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
165 else \
166 _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
167 } \
168 R##_e = X##_e; \
169 } \
170 \
171 R##_c = FP_CLS_NORMAL; \
172 \
173 if (X##_s == Y##_s) \
174 { \
175 R##_s = X##_s; \
176 _FP_FRAC_ADD_##wc(R, X, Y); \
177 if (_FP_FRAC_OVERP_##wc(fs, R)) \
178 { \
179 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
180 R##_e++; \
181 } \
182 } \
183 else \
184 { \
185 R##_s = X##_s; \
186 _FP_FRAC_SUB_##wc(R, X, Y); \
187 if (_FP_FRAC_ZEROP_##wc(R)) \
188 { \
189 /* return an exact zero */ \
190 if (FP_ROUNDMODE == FP_RND_MINF) \
191 R##_s |= Y##_s; \
192 else \
193 R##_s &= Y##_s; \
194 R##_c = FP_CLS_ZERO; \
195 } \
196 else \
197 { \
198 if (_FP_FRAC_NEGP_##wc(R)) \
199 { \
200 _FP_FRAC_SUB_##wc(R, Y, X); \
201 R##_s = Y##_s; \
202 } \
203 \
204 /* renormalize after subtraction */ \
205 _FP_FRAC_CLZ_##wc(diff, R); \
206 diff -= _FP_WFRACXBITS_##fs; \
207 if (diff) \
208 { \
209 R##_e -= diff; \
210 _FP_FRAC_SLL_##wc(R, diff); \
211 } \
212 } \
213 } \
214 break; \
215 } \
216 \
217 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
218 _FP_CHOOSENAN(fs, wc, R, X, Y); \
219 break; \
220 \
221 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
222 R##_e = X##_e; \
223 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
224 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
225 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
226 _FP_FRAC_COPY_##wc(R, X); \
227 R##_s = X##_s; \
228 R##_c = X##_c; \
229 break; \
230 \
231 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
232 R##_e = Y##_e; \
233 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
234 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
235 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
236 _FP_FRAC_COPY_##wc(R, Y); \
237 R##_s = Y##_s; \
238 R##_c = Y##_c; \
239 break; \
240 \
241 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
242 if (X##_s != Y##_s) \
243 { \
244 /* +INF + -INF => NAN */ \
245 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
246 R##_s = X##_s ^ Y##_s; \
247 R##_c = FP_CLS_NAN; \
248 break; \
249 } \
250 /* FALLTHRU */ \
251 \
252 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
253 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
254 R##_s = X##_s; \
255 R##_c = FP_CLS_INF; \
256 break; \
257 \
258 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
259 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
260 R##_s = Y##_s; \
261 R##_c = FP_CLS_INF; \
262 break; \
263 \
264 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
265 /* make sure the sign is correct */ \
266 if (FP_ROUNDMODE == FP_RND_MINF) \
267 R##_s = X##_s | Y##_s; \
268 else \
269 R##_s = X##_s & Y##_s; \
270 R##_c = FP_CLS_ZERO; \
271 break; \
272 \
273 default: \
274 abort(); \
275 } \
276} while (0)
277
278
279/*
280 * Main negation routine. FIXME -- when we care about setting exception
281 * bits reliably, this will not do. We should examine all of the fp classes.
282 */
283
284#define _FP_NEG(fs, wc, R, X) \
285 do { \
286 _FP_FRAC_COPY_##wc(R, X); \
287 R##_c = X##_c; \
288 R##_e = X##_e; \
289 R##_s = 1 ^ X##_s; \
290 } while (0)
291
292
293/*
294 * Main multiplication routine. The input values should be cooked.
295 */
296
297#define _FP_MUL(fs, wc, R, X, Y) \
298do { \
299 R##_s = X##_s ^ Y##_s; \
300 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
301 { \
302 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
303 R##_c = FP_CLS_NORMAL; \
304 R##_e = X##_e + Y##_e + 1; \
305 \
306 _FP_MUL_MEAT_##fs(R,X,Y); \
307 \
308 if (_FP_FRAC_OVERP_##wc(fs, R)) \
309 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
310 else \
311 R##_e--; \
312 break; \
313 \
314 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
315 _FP_CHOOSENAN(fs, wc, R, X, Y); \
316 break; \
317 \
318 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
319 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
320 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
321 R##_s = X##_s; \
322 \
323 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
324 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
325 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
326 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
327 _FP_FRAC_COPY_##wc(R, X); \
328 R##_c = X##_c; \
329 break; \
330 \
331 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
332 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
333 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
334 R##_s = Y##_s; \
335 \
336 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
337 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
338 _FP_FRAC_COPY_##wc(R, Y); \
339 R##_c = Y##_c; \
340 break; \
341 \
342 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
343 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
344 R##_c = FP_CLS_NAN; \
345 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
346 break; \
347 \
348 default: \
349 abort(); \
350 } \
351} while (0)
352
353
354/*
355 * Main division routine. The input values should be cooked.
356 */
357
358#define _FP_DIV(fs, wc, R, X, Y) \
359do { \
360 R##_s = X##_s ^ Y##_s; \
361 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
362 { \
363 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
364 R##_c = FP_CLS_NORMAL; \
365 R##_e = X##_e - Y##_e; \
366 \
367 _FP_DIV_MEAT_##fs(R,X,Y); \
368 break; \
369 \
370 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
371 _FP_CHOOSENAN(fs, wc, R, X, Y); \
372 break; \
373 \
374 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
375 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
376 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
377 R##_s = X##_s; \
378 _FP_FRAC_COPY_##wc(R, X); \
379 R##_c = X##_c; \
380 break; \
381 \
382 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
383 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
384 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
385 R##_s = Y##_s; \
386 _FP_FRAC_COPY_##wc(R, Y); \
387 R##_c = Y##_c; \
388 break; \
389 \
390 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
391 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
392 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
393 R##_c = FP_CLS_ZERO; \
394 break; \
395 \
396 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
397 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
398 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
399 R##_c = FP_CLS_INF; \
400 break; \
401 \
402 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
403 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
404 R##_c = FP_CLS_NAN; \
405 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
406 break; \
407 \
408 default: \
409 abort(); \
410 } \
411} while (0)
412
413
414/*
415 * Main differential comparison routine. The inputs should be raw not
416 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
417 */
418
419#define _FP_CMP(fs, wc, ret, X, Y, un) \
420 do { \
421 /* NANs are unordered */ \
422 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
423 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
424 { \
425 ret = un; \
426 } \
427 else \
428 { \
429 int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
430 int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
431 \
432 if (__x_zero && __y_zero) \
433 ret = 0; \
434 else if (__x_zero) \
435 ret = Y##_s ? 1 : -1; \
436 else if (__y_zero) \
437 ret = X##_s ? -1 : 1; \
438 else if (X##_s != Y##_s) \
439 ret = X##_s ? -1 : 1; \
440 else if (X##_e > Y##_e) \
441 ret = X##_s ? -1 : 1; \
442 else if (X##_e < Y##_e) \
443 ret = X##_s ? 1 : -1; \
444 else if (_FP_FRAC_GT_##wc(X, Y)) \
445 ret = X##_s ? -1 : 1; \
446 else if (_FP_FRAC_GT_##wc(Y, X)) \
447 ret = X##_s ? 1 : -1; \
448 else \
449 ret = 0; \
450 } \
451 } while (0)
452
453
454/* Simplification for strict equality. */
455
456#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
457 do { \
458 /* NANs are unordered */ \
459 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
460 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
461 { \
462 ret = 1; \
463 } \
464 else \
465 { \
466 ret = !(X##_e == Y##_e \
467 && _FP_FRAC_EQ_##wc(X, Y) \
468 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
469 } \
470 } while (0)
471
472/*
473 * Main square root routine. The input value should be cooked.
474 */
475
476#define _FP_SQRT(fs, wc, R, X) \
477do { \
478 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
479 _FP_W_TYPE q; \
480 switch (X##_c) \
481 { \
482 case FP_CLS_NAN: \
483 R##_s = 0; \
484 R##_c = FP_CLS_NAN; \
485 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
486 break; \
487 case FP_CLS_INF: \
488 if (X##_s) \
489 { \
490 R##_s = 0; \
491 R##_c = FP_CLS_NAN; /* sNAN */ \
492 } \
493 else \
494 { \
495 R##_s = 0; \
496 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
497 } \
498 break; \
499 case FP_CLS_ZERO: \
500 R##_s = X##_s; \
501 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
502 break; \
503 case FP_CLS_NORMAL: \
504 R##_s = 0; \
505 if (X##_s) \
506 { \
507 R##_c = FP_CLS_NAN; /* sNAN */ \
508 break; \
509 } \
510 R##_c = FP_CLS_NORMAL; \
511 if (X##_e & 1) \
512 _FP_FRAC_SLL_##wc(X, 1); \
513 R##_e = X##_e >> 1; \
514 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
515 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
516 q = _FP_OVERFLOW_##fs; \
517 _FP_FRAC_SLL_##wc(X, 1); \
518 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
519 _FP_FRAC_SRL_##wc(R, 1); \
520 } \
521 } while (0)
522
523/*
524 * Convert from FP to integer
525 */
526
527/* "When a NaN, infinity, large positive argument >= 2147483648.0, or
528 * large negative argument <= -2147483649.0 is converted to an integer,
529 * the invalid_current bit...should be set and fp_exception_IEEE_754 should
530 * be raised. If the floating point invalid trap is disabled, no trap occurs
531 * and a numerical result is generated: if the sign bit of the operand
532 * is 0, the result is 2147483647; if the sign bit of the operand is 1,
533 * the result is -2147483648."
534 * Similarly for conversion to extended ints, except that the boundaries
535 * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
536 * -2^63 for s=1.
537 * -- SPARC Architecture Manual V9, Appendix B, which specifies how
538 * SPARCs resolve implementation dependencies in the IEEE-754 spec.
539 * I don't believe that the code below follows this. I'm not even sure
540 * it's right!
541 * It doesn't cope with needing to convert to an n bit integer when there
542 * is no n bit integer type. Fortunately gcc provides long long so this
543 * isn't a problem for sparc32.
544 * I have, however, fixed its NaN handling to conform as above.
545 * -- PMM 02/1998
546 * NB: rsigned is not 'is r declared signed?' but 'should the value stored
547 * in r be signed or unsigned?'. r is always(?) declared unsigned.
548 * Comments below are mine, BTW -- PMM
549 */
550#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
551 do { \
552 switch (X##_c) \
553 { \
554 case FP_CLS_NORMAL: \
555 if (X##_e < 0) \
556 { \
557 /* case FP_CLS_NAN: see above! */ \
558 case FP_CLS_ZERO: \
559 r = 0; \
560 } \
561 else if (X##_e >= rsize - (rsigned != 0)) \
562 { /* overflow */ \
563 case FP_CLS_NAN: \
564 case FP_CLS_INF: \
565 if (rsigned) \
566 { \
567 r = 1; \
568 r <<= rsize - 1; \
569 r -= 1 - X##_s; \
570 } \
571 else \
572 { \
573 r = 0; \
574 if (!X##_s) \
575 r = ~r; \
576 } \
577 } \
578 else \
579 { \
580 if (_FP_W_TYPE_SIZE*wc < rsize) \
581 { \
582 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
583 r <<= X##_e - _FP_WFRACBITS_##fs; \
584 } \
585 else \
586 { \
587 if (X##_e >= _FP_WFRACBITS_##fs) \
588 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
589 else \
590 _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
591 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
592 } \
593 if (rsigned && X##_s) \
594 r = -r; \
595 } \
596 break; \
597 } \
598 } while (0)
599
600#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
601 do { \
602 if (r) \
603 { \
604 X##_c = FP_CLS_NORMAL; \
605 \
606 if ((X##_s = (r < 0))) \
607 r = -r; \
608 /* Note that `r' is now considered unsigned, so we don't have \
609 to worry about the single signed overflow case. */ \
610 \
611 if (rsize <= _FP_W_TYPE_SIZE) \
612 __FP_CLZ(X##_e, r); \
613 else \
614 __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \
615 (_FP_W_TYPE)r); \
616 if (rsize < _FP_W_TYPE_SIZE) \
617 X##_e -= (_FP_W_TYPE_SIZE - rsize); \
618 X##_e = rsize - X##_e - 1; \
619 \
620 if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
621 __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \
622 r &= ~((_FP_W_TYPE)1 << X##_e); \
623 _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \
624 _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
625 } \
626 else \
627 { \
628 X##_c = FP_CLS_ZERO, X##_s = 0; \
629 } \
630 } while (0)
631
632
633#define FP_CONV(dfs,sfs,dwc,swc,D,S) \
634 do { \
635 _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
636 D##_e = S##_e; \
637 D##_c = S##_c; \
638 D##_s = S##_s; \
639 } while (0)
640
641/*
642 * Helper primitives.
643 */
644
645/* Count leading zeros in a word. */
646
647#ifndef __FP_CLZ
648#if _FP_W_TYPE_SIZE < 64
649/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
650#define __FP_CLZ(r, x) \
651 do { \
652 _FP_W_TYPE _t = (x); \
653 r = _FP_W_TYPE_SIZE - 1; \
654 if (_t > 0xffff) r -= 16; \
655 if (_t > 0xffff) _t >>= 16; \
656 if (_t > 0xff) r -= 8; \
657 if (_t > 0xff) _t >>= 8; \
658 if (_t & 0xf0) r -= 4; \
659 if (_t & 0xf0) _t >>= 4; \
660 if (_t & 0xc) r -= 2; \
661 if (_t & 0xc) _t >>= 2; \
662 if (_t & 0x2) r -= 1; \
663 } while (0)
664#else /* not _FP_W_TYPE_SIZE < 64 */
665#define __FP_CLZ(r, x) \
666 do { \
667 _FP_W_TYPE _t = (x); \
668 r = _FP_W_TYPE_SIZE - 1; \
669 if (_t > 0xffffffff) r -= 32; \
670 if (_t > 0xffffffff) _t >>= 32; \
671 if (_t > 0xffff) r -= 16; \
672 if (_t > 0xffff) _t >>= 16; \
673 if (_t > 0xff) r -= 8; \
674 if (_t > 0xff) _t >>= 8; \
675 if (_t & 0xf0) r -= 4; \
676 if (_t & 0xf0) _t >>= 4; \
677 if (_t & 0xc) r -= 2; \
678 if (_t & 0xc) _t >>= 2; \
679 if (_t & 0x2) r -= 1; \
680 } while (0)
681#endif /* not _FP_W_TYPE_SIZE < 64 */
682#endif /* ndef __FP_CLZ */
683
684#define _FP_DIV_HELP_imm(q, r, n, d) \
685 do { \
686 q = n / d, r = n % d; \
687 } while (0)
688
diff --git a/arch/powerpc/math-emu/sfp-machine.h b/arch/powerpc/math-emu/sfp-machine.h
new file mode 100644
index 000000000000..4b17d83cfcdd
--- /dev/null
+++ b/arch/powerpc/math-emu/sfp-machine.h
@@ -0,0 +1,377 @@
1/* Machine-dependent software floating-point definitions. PPC version.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library 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 GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 Actually, this is a PPC (32bit) version, written based on the
21 i386, sparc, and sparc64 versions, by me,
22 Peter Maydell (pmaydell@chiark.greenend.org.uk).
23 Comments are by and large also mine, although they may be inaccurate.
24
25 In picking out asm fragments I've gone with the lowest common
26 denominator, which also happens to be the hardware I have :->
27 That is, a SPARC without hardware multiply and divide.
28 */
29
30/* basic word size definitions */
31#define _FP_W_TYPE_SIZE 32
32#define _FP_W_TYPE unsigned long
33#define _FP_WS_TYPE signed long
34#define _FP_I_TYPE long
35
36#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
37#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
38#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
39
40/* You can optionally code some things like addition in asm. For
41 * example, i386 defines __FP_FRAC_ADD_2 as asm. If you don't
42 * then you get a fragment of C code [if you change an #ifdef 0
43 * in op-2.h] or a call to add_ssaaaa (see below).
44 * Good places to look for asm fragments to use are gcc and glibc.
45 * gcc's longlong.h is useful.
46 */
47
48/* We need to know how to multiply and divide. If the host word size
49 * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which
50 * codes the multiply with whatever gcc does to 'a * b'.
51 * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm
52 * function that can multiply two 1W values and get a 2W result.
53 * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which
54 * does bitshifting to avoid overflow.
55 * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size
56 * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or
57 * _FP_DIV_HELP_ldiv (see op-1.h).
58 * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W).
59 * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd
60 * to do this.]
61 * In general, 'n' is the number of words required to hold the type,
62 * and 't' is either S, D or Q for single/double/quad.
63 * -- PMM
64 */
65/* Example: SPARC64:
66 * #define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_imm(S,R,X,Y)
67 * #define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_1_wide(D,R,X,Y,umul_ppmm)
68 * #define _FP_MUL_MEAT_Q(R,X,Y) _FP_MUL_MEAT_2_wide(Q,R,X,Y,umul_ppmm)
69 *
70 * #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
71 * #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
72 * #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv_64(Q,R,X,Y)
73 *
74 * Example: i386:
75 * #define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(S,R,X,Y,_i386_mul_32_64)
76 * #define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(D,R,X,Y,_i386_mul_32_64)
77 *
78 * #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y,_i386_div_64_32)
79 * #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
80 */
81
82#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(S,R,X,Y,umul_ppmm)
83#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(D,R,X,Y,umul_ppmm)
84
85#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
86#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
87
88/* These macros define what NaN looks like. They're supposed to expand to
89 * a comma-separated set of 32bit unsigned ints that encode NaN.
90 */
91#define _FP_NANFRAC_S _FP_QNANBIT_S
92#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
93#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
94
95#define _FP_KEEPNANFRACP 1
96
97/* This macro appears to be called when both X and Y are NaNs, and
98 * has to choose one and copy it to R. i386 goes for the larger of the
99 * two, sparc64 just picks Y. I don't understand this at all so I'll
100 * go with sparc64 because it's shorter :-> -- PMM
101 */
102#define _FP_CHOOSENAN(fs, wc, R, X, Y) \
103 do { \
104 R##_s = Y##_s; \
105 _FP_FRAC_COPY_##wc(R,Y); \
106 R##_c = FP_CLS_NAN; \
107 } while (0)
108
109
110extern void fp_unpack_d(long *, unsigned long *, unsigned long *,
111 long *, long *, void *);
112extern int fp_pack_d(void *, long, unsigned long, unsigned long, long, long);
113extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
114
115#define __FP_UNPACK_RAW_1(fs, X, val) \
116 do { \
117 union _FP_UNION_##fs *_flo = \
118 (union _FP_UNION_##fs *)val; \
119 \
120 X##_f = _flo->bits.frac; \
121 X##_e = _flo->bits.exp; \
122 X##_s = _flo->bits.sign; \
123 } while (0)
124
125#define __FP_UNPACK_RAW_2(fs, X, val) \
126 do { \
127 union _FP_UNION_##fs *_flo = \
128 (union _FP_UNION_##fs *)val; \
129 \
130 X##_f0 = _flo->bits.frac0; \
131 X##_f1 = _flo->bits.frac1; \
132 X##_e = _flo->bits.exp; \
133 X##_s = _flo->bits.sign; \
134 } while (0)
135
136#define __FP_UNPACK_S(X,val) \
137 do { \
138 __FP_UNPACK_RAW_1(S,X,val); \
139 _FP_UNPACK_CANONICAL(S,1,X); \
140 } while (0)
141
142#define __FP_UNPACK_D(X,val) \
143 fp_unpack_d(&X##_s, &X##_f1, &X##_f0, &X##_e, &X##_c, val)
144
145#define __FP_PACK_RAW_1(fs, val, X) \
146 do { \
147 union _FP_UNION_##fs *_flo = \
148 (union _FP_UNION_##fs *)val; \
149 \
150 _flo->bits.frac = X##_f; \
151 _flo->bits.exp = X##_e; \
152 _flo->bits.sign = X##_s; \
153 } while (0)
154
155#define __FP_PACK_RAW_2(fs, val, X) \
156 do { \
157 union _FP_UNION_##fs *_flo = \
158 (union _FP_UNION_##fs *)val; \
159 \
160 _flo->bits.frac0 = X##_f0; \
161 _flo->bits.frac1 = X##_f1; \
162 _flo->bits.exp = X##_e; \
163 _flo->bits.sign = X##_s; \
164 } while (0)
165
166#include <linux/kernel.h>
167#include <linux/sched.h>
168
169#define __FPU_FPSCR (current->thread.fpscr.val)
170
171/* We only actually write to the destination register
172 * if exceptions signalled (if any) will not trap.
173 */
174#define __FPU_ENABLED_EXC \
175({ \
176 (__FPU_FPSCR >> 3) & 0x1f; \
177})
178
179#define __FPU_TRAP_P(bits) \
180 ((__FPU_ENABLED_EXC & (bits)) != 0)
181
182#define __FP_PACK_S(val,X) \
183({ int __exc = _FP_PACK_CANONICAL(S,1,X); \
184 if(!__exc || !__FPU_TRAP_P(__exc)) \
185 __FP_PACK_RAW_1(S,val,X); \
186 __exc; \
187})
188
189#define __FP_PACK_D(val,X) \
190 fp_pack_d(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
191
192#define __FP_PACK_DS(val,X) \
193 fp_pack_ds(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
194
195/* Obtain the current rounding mode. */
196#define FP_ROUNDMODE \
197({ \
198 __FPU_FPSCR & 0x3; \
199})
200
201/* the asm fragments go here: all these are taken from glibc-2.0.5's
202 * stdlib/longlong.h
203 */
204
205#include <linux/types.h>
206#include <asm/byteorder.h>
207
208/* add_ssaaaa is used in op-2.h and should be equivalent to
209 * #define add_ssaaaa(sh,sl,ah,al,bh,bl) (sh = ah+bh+ (( sl = al+bl) < al))
210 * add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
211 * high_addend_2, low_addend_2) adds two UWtype integers, composed by
212 * HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
213 * respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
214 * (i.e. carry out) is not stored anywhere, and is lost.
215 */
216#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
217 do { \
218 if (__builtin_constant_p (bh) && (bh) == 0) \
219 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
220 : "=r" ((USItype)(sh)), \
221 "=&r" ((USItype)(sl)) \
222 : "%r" ((USItype)(ah)), \
223 "%r" ((USItype)(al)), \
224 "rI" ((USItype)(bl))); \
225 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
226 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
227 : "=r" ((USItype)(sh)), \
228 "=&r" ((USItype)(sl)) \
229 : "%r" ((USItype)(ah)), \
230 "%r" ((USItype)(al)), \
231 "rI" ((USItype)(bl))); \
232 else \
233 __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
234 : "=r" ((USItype)(sh)), \
235 "=&r" ((USItype)(sl)) \
236 : "%r" ((USItype)(ah)), \
237 "r" ((USItype)(bh)), \
238 "%r" ((USItype)(al)), \
239 "rI" ((USItype)(bl))); \
240 } while (0)
241
242/* sub_ddmmss is used in op-2.h and udivmodti4.c and should be equivalent to
243 * #define sub_ddmmss(sh, sl, ah, al, bh, bl) (sh = ah-bh - ((sl = al-bl) > al))
244 * sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
245 * high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
246 * composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
247 * LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
248 * and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
249 * and is lost.
250 */
251#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
252 do { \
253 if (__builtin_constant_p (ah) && (ah) == 0) \
254 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
255 : "=r" ((USItype)(sh)), \
256 "=&r" ((USItype)(sl)) \
257 : "r" ((USItype)(bh)), \
258 "rI" ((USItype)(al)), \
259 "r" ((USItype)(bl))); \
260 else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
261 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
262 : "=r" ((USItype)(sh)), \
263 "=&r" ((USItype)(sl)) \
264 : "r" ((USItype)(bh)), \
265 "rI" ((USItype)(al)), \
266 "r" ((USItype)(bl))); \
267 else if (__builtin_constant_p (bh) && (bh) == 0) \
268 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
269 : "=r" ((USItype)(sh)), \
270 "=&r" ((USItype)(sl)) \
271 : "r" ((USItype)(ah)), \
272 "rI" ((USItype)(al)), \
273 "r" ((USItype)(bl))); \
274 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
275 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
276 : "=r" ((USItype)(sh)), \
277 "=&r" ((USItype)(sl)) \
278 : "r" ((USItype)(ah)), \
279 "rI" ((USItype)(al)), \
280 "r" ((USItype)(bl))); \
281 else \
282 __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
283 : "=r" ((USItype)(sh)), \
284 "=&r" ((USItype)(sl)) \
285 : "r" ((USItype)(ah)), \
286 "r" ((USItype)(bh)), \
287 "rI" ((USItype)(al)), \
288 "r" ((USItype)(bl))); \
289 } while (0)
290
291/* asm fragments for mul and div */
292
293/* umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
294 * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
295 * word product in HIGH_PROD and LOW_PROD.
296 */
297#define umul_ppmm(ph, pl, m0, m1) \
298 do { \
299 USItype __m0 = (m0), __m1 = (m1); \
300 __asm__ ("mulhwu %0,%1,%2" \
301 : "=r" ((USItype)(ph)) \
302 : "%r" (__m0), \
303 "r" (__m1)); \
304 (pl) = __m0 * __m1; \
305 } while (0)
306
307/* udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
308 * denominator) divides a UDWtype, composed by the UWtype integers
309 * HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
310 * in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
311 * than DENOMINATOR for correct operation. If, in addition, the most
312 * significant bit of DENOMINATOR must be 1, then the pre-processor symbol
313 * UDIV_NEEDS_NORMALIZATION is defined to 1.
314 */
315#define udiv_qrnnd(q, r, n1, n0, d) \
316 do { \
317 UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
318 __d1 = __ll_highpart (d); \
319 __d0 = __ll_lowpart (d); \
320 \
321 __r1 = (n1) % __d1; \
322 __q1 = (n1) / __d1; \
323 __m = (UWtype) __q1 * __d0; \
324 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
325 if (__r1 < __m) \
326 { \
327 __q1--, __r1 += (d); \
328 if (__r1 >= (d)) /* we didn't get carry when adding to __r1 */ \
329 if (__r1 < __m) \
330 __q1--, __r1 += (d); \
331 } \
332 __r1 -= __m; \
333 \
334 __r0 = __r1 % __d1; \
335 __q0 = __r1 / __d1; \
336 __m = (UWtype) __q0 * __d0; \
337 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
338 if (__r0 < __m) \
339 { \
340 __q0--, __r0 += (d); \
341 if (__r0 >= (d)) \
342 if (__r0 < __m) \
343 __q0--, __r0 += (d); \
344 } \
345 __r0 -= __m; \
346 \
347 (q) = (UWtype) __q1 * __ll_B | __q0; \
348 (r) = __r0; \
349 } while (0)
350
351#define UDIV_NEEDS_NORMALIZATION 1
352
353#define abort() \
354 return 0
355
356#ifdef __BIG_ENDIAN
357#define __BYTE_ORDER __BIG_ENDIAN
358#else
359#define __BYTE_ORDER __LITTLE_ENDIAN
360#endif
361
362/* Exception flags. */
363#define EFLAG_INVALID (1 << (31 - 2))
364#define EFLAG_OVERFLOW (1 << (31 - 3))
365#define EFLAG_UNDERFLOW (1 << (31 - 4))
366#define EFLAG_DIVZERO (1 << (31 - 5))
367#define EFLAG_INEXACT (1 << (31 - 6))
368
369#define EFLAG_VXSNAN (1 << (31 - 7))
370#define EFLAG_VXISI (1 << (31 - 8))
371#define EFLAG_VXIDI (1 << (31 - 9))
372#define EFLAG_VXZDZ (1 << (31 - 10))
373#define EFLAG_VXIMZ (1 << (31 - 11))
374#define EFLAG_VXVC (1 << (31 - 12))
375#define EFLAG_VXSOFT (1 << (31 - 21))
376#define EFLAG_VXSQRT (1 << (31 - 22))
377#define EFLAG_VXCVI (1 << (31 - 23))
diff --git a/arch/powerpc/math-emu/single.h b/arch/powerpc/math-emu/single.h
new file mode 100644
index 000000000000..f19d99451815
--- /dev/null
+++ b/arch/powerpc/math-emu/single.h
@@ -0,0 +1,66 @@
1/*
2 * Definitions for IEEE Single Precision
3 */
4
5#if _FP_W_TYPE_SIZE < 32
6#error "Here's a nickel kid. Go buy yourself a real computer."
7#endif
8
9#define _FP_FRACBITS_S 24
10#define _FP_FRACXBITS_S (_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
11#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S)
12#define _FP_WFRACXBITS_S (_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
13#define _FP_EXPBITS_S 8
14#define _FP_EXPBIAS_S 127
15#define _FP_EXPMAX_S 255
16#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
17#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
18#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
19
20/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
21 chosen by the target machine. */
22
23union _FP_UNION_S
24{
25 float flt;
26 struct {
27#if __BYTE_ORDER == __BIG_ENDIAN
28 unsigned sign : 1;
29 unsigned exp : _FP_EXPBITS_S;
30 unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
31#else
32 unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
33 unsigned exp : _FP_EXPBITS_S;
34 unsigned sign : 1;
35#endif
36 } bits __attribute__((packed));
37};
38
39#define FP_DECL_S(X) _FP_DECL(1,X)
40#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
41#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X)
42
43#define FP_UNPACK_S(X,val) \
44 do { \
45 _FP_UNPACK_RAW_1(S,X,val); \
46 _FP_UNPACK_CANONICAL(S,1,X); \
47 } while (0)
48
49#define FP_PACK_S(val,X) \
50 do { \
51 _FP_PACK_CANONICAL(S,1,X); \
52 _FP_PACK_RAW_1(S,val,X); \
53 } while (0)
54
55#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X)
56#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y)
57#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y)
58#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y)
59#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y)
60#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X)
61
62#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un)
63#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y)
64
65#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg)
66#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt)
diff --git a/arch/powerpc/math-emu/soft-fp.h b/arch/powerpc/math-emu/soft-fp.h
new file mode 100644
index 000000000000..cca39598f873
--- /dev/null
+++ b/arch/powerpc/math-emu/soft-fp.h
@@ -0,0 +1,104 @@
1#ifndef SOFT_FP_H
2#define SOFT_FP_H
3
4#include "sfp-machine.h"
5
6#define _FP_WORKBITS 3
7#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
8#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
9#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1)
10#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0)
11
12#ifndef FP_RND_NEAREST
13# define FP_RND_NEAREST 0
14# define FP_RND_ZERO 1
15# define FP_RND_PINF 2
16# define FP_RND_MINF 3
17#ifndef FP_ROUNDMODE
18# define FP_ROUNDMODE FP_RND_NEAREST
19#endif
20#endif
21
22#define _FP_ROUND_NEAREST(wc, X) \
23({ int __ret = 0; \
24 int __frac = _FP_FRAC_LOW_##wc(X) & 15; \
25 if (__frac & 7) { \
26 __ret = EFLAG_INEXACT; \
27 if ((__frac & 7) != _FP_WORK_ROUND) \
28 _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
29 else if (__frac & _FP_WORK_LSB) \
30 _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
31 } \
32 __ret; \
33})
34
35#define _FP_ROUND_ZERO(wc, X) \
36({ int __ret = 0; \
37 if (_FP_FRAC_LOW_##wc(X) & 7) \
38 __ret = EFLAG_INEXACT; \
39 __ret; \
40})
41
42#define _FP_ROUND_PINF(wc, X) \
43({ int __ret = EFLAG_INEXACT; \
44 if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
45 _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
46 else __ret = 0; \
47 __ret; \
48})
49
50#define _FP_ROUND_MINF(wc, X) \
51({ int __ret = EFLAG_INEXACT; \
52 if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
53 _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
54 else __ret = 0; \
55 __ret; \
56})
57
58#define _FP_ROUND(wc, X) \
59({ int __ret = 0; \
60 switch (FP_ROUNDMODE) \
61 { \
62 case FP_RND_NEAREST: \
63 __ret |= _FP_ROUND_NEAREST(wc,X); \
64 break; \
65 case FP_RND_ZERO: \
66 __ret |= _FP_ROUND_ZERO(wc,X); \
67 break; \
68 case FP_RND_PINF: \
69 __ret |= _FP_ROUND_PINF(wc,X); \
70 break; \
71 case FP_RND_MINF: \
72 __ret |= _FP_ROUND_MINF(wc,X); \
73 break; \
74 }; \
75 __ret; \
76})
77
78#define FP_CLS_NORMAL 0
79#define FP_CLS_ZERO 1
80#define FP_CLS_INF 2
81#define FP_CLS_NAN 3
82
83#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y))
84
85#include "op-1.h"
86#include "op-2.h"
87#include "op-4.h"
88#include "op-common.h"
89
90/* Sigh. Silly things longlong.h needs. */
91#define UWtype _FP_W_TYPE
92#define W_TYPE_SIZE _FP_W_TYPE_SIZE
93
94typedef int SItype __attribute__((mode(SI)));
95typedef int DItype __attribute__((mode(DI)));
96typedef unsigned int USItype __attribute__((mode(SI)));
97typedef unsigned int UDItype __attribute__((mode(DI)));
98#if _FP_W_TYPE_SIZE == 32
99typedef unsigned int UHWtype __attribute__((mode(HI)));
100#elif _FP_W_TYPE_SIZE == 64
101typedef USItype UHWtype;
102#endif
103
104#endif
diff --git a/arch/powerpc/math-emu/stfd.c b/arch/powerpc/math-emu/stfd.c
new file mode 100644
index 000000000000..3f8c2558a9e8
--- /dev/null
+++ b/arch/powerpc/math-emu/stfd.c
@@ -0,0 +1,20 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6stfd(void *frS, void *ea)
7{
8#if 0
9#ifdef DEBUG
10 printk("%s: S %p, ea %p: ", __FUNCTION__, frS, ea);
11 dump_double(frS);
12 printk("\n");
13#endif
14#endif
15
16 if (copy_to_user(ea, frS, sizeof(double)))
17 return -EFAULT;
18
19 return 0;
20}
diff --git a/arch/powerpc/math-emu/stfiwx.c b/arch/powerpc/math-emu/stfiwx.c
new file mode 100644
index 000000000000..95caaeec6a08
--- /dev/null
+++ b/arch/powerpc/math-emu/stfiwx.c
@@ -0,0 +1,16 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5int
6stfiwx(u32 *frS, void *ea)
7{
8#ifdef DEBUG
9 printk("%s: %p %p\n", __FUNCTION__, frS, ea);
10#endif
11
12 if (copy_to_user(ea, &frS[1], sizeof(frS[1])))
13 return -EFAULT;
14
15 return 0;
16}
diff --git a/arch/powerpc/math-emu/stfs.c b/arch/powerpc/math-emu/stfs.c
new file mode 100644
index 000000000000..e87ca23c6dc3
--- /dev/null
+++ b/arch/powerpc/math-emu/stfs.c
@@ -0,0 +1,41 @@
1#include <linux/types.h>
2#include <linux/errno.h>
3#include <asm/uaccess.h>
4
5#include "soft-fp.h"
6#include "double.h"
7#include "single.h"
8
9int
10stfs(void *frS, void *ea)
11{
12 FP_DECL_D(A);
13 FP_DECL_S(R);
14 float f;
15 int err;
16
17#ifdef DEBUG
18 printk("%s: S %p, ea %p\n", __FUNCTION__, frS, ea);
19#endif
20
21 __FP_UNPACK_D(A, frS);
22
23#ifdef DEBUG
24 printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
25#endif
26
27 FP_CONV(S, D, 1, 2, R, A);
28
29#ifdef DEBUG
30 printk("R: %ld %lu %ld (%ld)\n", R_s, R_f, R_e, R_c);
31#endif
32
33 err = _FP_PACK_CANONICAL(S, 1, R);
34 if (!err || !__FPU_TRAP_P(err)) {
35 __FP_PACK_RAW_1(S, &f, R);
36 if (copy_to_user(ea, &f, sizeof(float)))
37 return -EFAULT;
38 }
39
40 return err;
41}
diff --git a/arch/powerpc/math-emu/types.c b/arch/powerpc/math-emu/types.c
new file mode 100644
index 000000000000..e1ed15d829db
--- /dev/null
+++ b/arch/powerpc/math-emu/types.c
@@ -0,0 +1,51 @@
1#include "soft-fp.h"
2#include "double.h"
3#include "single.h"
4
5void
6fp_unpack_d(long *_s, unsigned long *_f1, unsigned long *_f0,
7 long *_e, long *_c, void *val)
8{
9 FP_DECL_D(X);
10
11 __FP_UNPACK_RAW_2(D, X, val);
12
13 _FP_UNPACK_CANONICAL(D, 2, X);
14
15 *_s = X_s;
16 *_f1 = X_f1;
17 *_f0 = X_f0;
18 *_e = X_e;
19 *_c = X_c;
20}
21
22int
23fp_pack_d(void *val, long X_s, unsigned long X_f1,
24 unsigned long X_f0, long X_e, long X_c)
25{
26 int exc;
27
28 exc = _FP_PACK_CANONICAL(D, 2, X);
29 if (!exc || !__FPU_TRAP_P(exc))
30 __FP_PACK_RAW_2(D, val, X);
31 return exc;
32}
33
34int
35fp_pack_ds(void *val, long X_s, unsigned long X_f1,
36 unsigned long X_f0, long X_e, long X_c)
37{
38 FP_DECL_S(__X);
39 int exc;
40
41 FP_CONV(S, D, 1, 2, __X, X);
42 exc = _FP_PACK_CANONICAL(S, 1, __X);
43 if (!exc || !__FPU_TRAP_P(exc)) {
44 _FP_UNPACK_CANONICAL(S, 1, __X);
45 FP_CONV(D, S, 2, 1, X, __X);
46 exc |= _FP_PACK_CANONICAL(D, 2, X);
47 if (!exc || !__FPU_TRAP_P(exc))
48 __FP_PACK_RAW_2(D, val, X);
49 }
50 return exc;
51}
diff --git a/arch/powerpc/math-emu/udivmodti4.c b/arch/powerpc/math-emu/udivmodti4.c
new file mode 100644
index 000000000000..7e112dc1e2f2
--- /dev/null
+++ b/arch/powerpc/math-emu/udivmodti4.c
@@ -0,0 +1,191 @@
1/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */
2
3#include "soft-fp.h"
4
5#undef count_leading_zeros
6#define count_leading_zeros __FP_CLZ
7
8void
9_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
10 _FP_W_TYPE n1, _FP_W_TYPE n0,
11 _FP_W_TYPE d1, _FP_W_TYPE d0)
12{
13 _FP_W_TYPE q0, q1, r0, r1;
14 _FP_I_TYPE b, bm;
15
16 if (d1 == 0)
17 {
18#if !UDIV_NEEDS_NORMALIZATION
19 if (d0 > n1)
20 {
21 /* 0q = nn / 0D */
22
23 udiv_qrnnd (q0, n0, n1, n0, d0);
24 q1 = 0;
25
26 /* Remainder in n0. */
27 }
28 else
29 {
30 /* qq = NN / 0d */
31
32 if (d0 == 0)
33 d0 = 1 / d0; /* Divide intentionally by zero. */
34
35 udiv_qrnnd (q1, n1, 0, n1, d0);
36 udiv_qrnnd (q0, n0, n1, n0, d0);
37
38 /* Remainder in n0. */
39 }
40
41 r0 = n0;
42 r1 = 0;
43
44#else /* UDIV_NEEDS_NORMALIZATION */
45
46 if (d0 > n1)
47 {
48 /* 0q = nn / 0D */
49
50 count_leading_zeros (bm, d0);
51
52 if (bm != 0)
53 {
54 /* Normalize, i.e. make the most significant bit of the
55 denominator set. */
56
57 d0 = d0 << bm;
58 n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
59 n0 = n0 << bm;
60 }
61
62 udiv_qrnnd (q0, n0, n1, n0, d0);
63 q1 = 0;
64
65 /* Remainder in n0 >> bm. */
66 }
67 else
68 {
69 /* qq = NN / 0d */
70
71 if (d0 == 0)
72 d0 = 1 / d0; /* Divide intentionally by zero. */
73
74 count_leading_zeros (bm, d0);
75
76 if (bm == 0)
77 {
78 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
79 conclude (the most significant bit of n1 is set) /\ (the
80 leading quotient digit q1 = 1).
81
82 This special case is necessary, not an optimization.
83 (Shifts counts of SI_TYPE_SIZE are undefined.) */
84
85 n1 -= d0;
86 q1 = 1;
87 }
88 else
89 {
90 _FP_W_TYPE n2;
91
92 /* Normalize. */
93
94 b = _FP_W_TYPE_SIZE - bm;
95
96 d0 = d0 << bm;
97 n2 = n1 >> b;
98 n1 = (n1 << bm) | (n0 >> b);
99 n0 = n0 << bm;
100
101 udiv_qrnnd (q1, n1, n2, n1, d0);
102 }
103
104 /* n1 != d0... */
105
106 udiv_qrnnd (q0, n0, n1, n0, d0);
107
108 /* Remainder in n0 >> bm. */
109 }
110
111 r0 = n0 >> bm;
112 r1 = 0;
113#endif /* UDIV_NEEDS_NORMALIZATION */
114 }
115 else
116 {
117 if (d1 > n1)
118 {
119 /* 00 = nn / DD */
120
121 q0 = 0;
122 q1 = 0;
123
124 /* Remainder in n1n0. */
125 r0 = n0;
126 r1 = n1;
127 }
128 else
129 {
130 /* 0q = NN / dd */
131
132 count_leading_zeros (bm, d1);
133 if (bm == 0)
134 {
135 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
136 conclude (the most significant bit of n1 is set) /\ (the
137 quotient digit q0 = 0 or 1).
138
139 This special case is necessary, not an optimization. */
140
141 /* The condition on the next line takes advantage of that
142 n1 >= d1 (true due to program flow). */
143 if (n1 > d1 || n0 >= d0)
144 {
145 q0 = 1;
146 sub_ddmmss (n1, n0, n1, n0, d1, d0);
147 }
148 else
149 q0 = 0;
150
151 q1 = 0;
152
153 r0 = n0;
154 r1 = n1;
155 }
156 else
157 {
158 _FP_W_TYPE m1, m0, n2;
159
160 /* Normalize. */
161
162 b = _FP_W_TYPE_SIZE - bm;
163
164 d1 = (d1 << bm) | (d0 >> b);
165 d0 = d0 << bm;
166 n2 = n1 >> b;
167 n1 = (n1 << bm) | (n0 >> b);
168 n0 = n0 << bm;
169
170 udiv_qrnnd (q0, n1, n2, n1, d1);
171 umul_ppmm (m1, m0, q0, d0);
172
173 if (m1 > n1 || (m1 == n1 && m0 > n0))
174 {
175 q0--;
176 sub_ddmmss (m1, m0, m1, m0, d1, d0);
177 }
178
179 q1 = 0;
180
181 /* Remainder in (n1n0 - m1m0) >> bm. */
182 sub_ddmmss (n1, n0, n1, n0, m1, m0);
183 r0 = (n1 << b) | (n0 >> bm);
184 r1 = n1 >> bm;
185 }
186 }
187 }
188
189 q[0] = q0; q[1] = q1;
190 r[0] = r0, r[1] = r1;
191}
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index a4815d316722..5aea0909a5ec 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/mm/fault.c
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -269,25 +267,29 @@ good_area:
269#endif 267#endif
270#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 268#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
271 pte_t *ptep; 269 pte_t *ptep;
270 pmd_t *pmdp;
272 271
273 /* Since 4xx/Book-E supports per-page execute permission, 272 /* Since 4xx/Book-E supports per-page execute permission,
274 * we lazily flush dcache to icache. */ 273 * we lazily flush dcache to icache. */
275 ptep = NULL; 274 ptep = NULL;
276 if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { 275 if (get_pteptr(mm, address, &ptep, &pmdp)) {
277 struct page *page = pte_page(*ptep); 276 spinlock_t *ptl = pte_lockptr(mm, pmdp);
278 277 spin_lock(ptl);
279 if (! test_bit(PG_arch_1, &page->flags)) { 278 if (pte_present(*ptep)) {
280 flush_dcache_icache_page(page); 279 struct page *page = pte_page(*ptep);
281 set_bit(PG_arch_1, &page->flags); 280
281 if (!test_bit(PG_arch_1, &page->flags)) {
282 flush_dcache_icache_page(page);
283 set_bit(PG_arch_1, &page->flags);
284 }
285 pte_update(ptep, 0, _PAGE_HWEXEC);
286 _tlbie(address);
287 pte_unmap_unlock(ptep, ptl);
288 up_read(&mm->mmap_sem);
289 return 0;
282 } 290 }
283 pte_update(ptep, 0, _PAGE_HWEXEC); 291 pte_unmap_unlock(ptep, ptl);
284 _tlbie(address);
285 pte_unmap(ptep);
286 up_read(&mm->mmap_sem);
287 return 0;
288 } 292 }
289 if (ptep != NULL)
290 pte_unmap(ptep);
291#endif 293#endif
292 /* a write */ 294 /* a write */
293 } else if (is_write) { 295 } else if (is_write) {
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index 12ccd7155bac..ea469eefa146 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/hashtable.S
3 *
4 * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $ 2 * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
5 * 3 *
6 * PowerPC version 4 * PowerPC version
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index e9d589eefc14..c006d9039633 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -167,18 +167,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
167 * normal insert callback here. 167 * normal insert callback here.
168 */ 168 */
169#ifdef CONFIG_PPC_ISERIES 169#ifdef CONFIG_PPC_ISERIES
170 if (_machine == PLATFORM_ISERIES_LPAR) 170 if (machine_is(iseries))
171 ret = iSeries_hpte_insert(hpteg, va, 171 ret = iSeries_hpte_insert(hpteg, va,
172 __pa(vaddr), 172 paddr,
173 tmp_mode, 173 tmp_mode,
174 HPTE_V_BOLTED, 174 HPTE_V_BOLTED,
175 psize); 175 psize);
176 else 176 else
177#endif 177#endif
178#ifdef CONFIG_PPC_PSERIES 178#ifdef CONFIG_PPC_PSERIES
179 if (_machine & PLATFORM_LPAR) 179 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR))
180 ret = pSeries_lpar_hpte_insert(hpteg, va, 180 ret = pSeries_lpar_hpte_insert(hpteg, va,
181 virt_to_abs(paddr), 181 paddr,
182 tmp_mode, 182 tmp_mode,
183 HPTE_V_BOLTED, 183 HPTE_V_BOLTED,
184 psize); 184 psize);
@@ -186,7 +186,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
186#endif 186#endif
187#ifdef CONFIG_PPC_MULTIPLATFORM 187#ifdef CONFIG_PPC_MULTIPLATFORM
188 ret = native_hpte_insert(hpteg, va, 188 ret = native_hpte_insert(hpteg, va,
189 virt_to_abs(paddr), 189 paddr,
190 tmp_mode, HPTE_V_BOLTED, 190 tmp_mode, HPTE_V_BOLTED,
191 psize); 191 psize);
192#endif 192#endif
@@ -295,8 +295,7 @@ static void __init htab_init_page_sizes(void)
295 * Not in the device-tree, let's fallback on known size 295 * Not in the device-tree, let's fallback on known size
296 * list for 16M capable GP & GR 296 * list for 16M capable GP & GR
297 */ 297 */
298 if ((_machine != PLATFORM_ISERIES_LPAR) && 298 if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries))
299 cpu_has_feature(CPU_FTR_16M_PAGE))
300 memcpy(mmu_psize_defs, mmu_psize_defaults_gp, 299 memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
301 sizeof(mmu_psize_defaults_gp)); 300 sizeof(mmu_psize_defaults_gp));
302 found: 301 found:
@@ -392,7 +391,7 @@ static unsigned long __init htab_get_table_size(void)
392#ifdef CONFIG_MEMORY_HOTPLUG 391#ifdef CONFIG_MEMORY_HOTPLUG
393void create_section_mapping(unsigned long start, unsigned long end) 392void create_section_mapping(unsigned long start, unsigned long end)
394{ 393{
395 BUG_ON(htab_bolt_mapping(start, end, start, 394 BUG_ON(htab_bolt_mapping(start, end, __pa(start),
396 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, 395 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
397 mmu_linear_psize)); 396 mmu_linear_psize));
398} 397}
@@ -422,7 +421,7 @@ void __init htab_initialize(void)
422 421
423 htab_hash_mask = pteg_count - 1; 422 htab_hash_mask = pteg_count - 1;
424 423
425 if (platform_is_lpar()) { 424 if (firmware_has_feature(FW_FEATURE_LPAR)) {
426 /* Using a hypervisor which owns the htab */ 425 /* Using a hypervisor which owns the htab */
427 htab_address = NULL; 426 htab_address = NULL;
428 _SDR1 = 0; 427 _SDR1 = 0;
@@ -431,7 +430,6 @@ void __init htab_initialize(void)
431 * the absolute address space. 430 * the absolute address space.
432 */ 431 */
433 table = lmb_alloc(htab_size_bytes, htab_size_bytes); 432 table = lmb_alloc(htab_size_bytes, htab_size_bytes);
434 BUG_ON(table == 0);
435 433
436 DBG("Hash table allocated at %lx, size: %lx\n", table, 434 DBG("Hash table allocated at %lx, size: %lx\n", table,
437 htab_size_bytes); 435 htab_size_bytes);
@@ -474,21 +472,22 @@ void __init htab_initialize(void)
474 472
475 if (dart_tablebase != 0 && dart_tablebase >= base 473 if (dart_tablebase != 0 && dart_tablebase >= base
476 && dart_tablebase < (base + size)) { 474 && dart_tablebase < (base + size)) {
475 unsigned long dart_table_end = dart_tablebase + 16 * MB;
477 if (base != dart_tablebase) 476 if (base != dart_tablebase)
478 BUG_ON(htab_bolt_mapping(base, dart_tablebase, 477 BUG_ON(htab_bolt_mapping(base, dart_tablebase,
479 base, mode_rw, 478 __pa(base), mode_rw,
480 mmu_linear_psize)); 479 mmu_linear_psize));
481 if ((base + size) > (dart_tablebase + 16*MB)) 480 if ((base + size) > dart_table_end)
482 BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB, 481 BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB,
483 base + size, 482 base + size,
484 dart_tablebase+16*MB, 483 __pa(dart_table_end),
485 mode_rw, 484 mode_rw,
486 mmu_linear_psize)); 485 mmu_linear_psize));
487 continue; 486 continue;
488 } 487 }
489#endif /* CONFIG_U3_DART */ 488#endif /* CONFIG_U3_DART */
490 BUG_ON(htab_bolt_mapping(base, base + size, base, 489 BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
491 mode_rw, mmu_linear_psize)); 490 mode_rw, mmu_linear_psize));
492 } 491 }
493 492
494 /* 493 /*
@@ -505,8 +504,8 @@ void __init htab_initialize(void)
505 if (base + size >= tce_alloc_start) 504 if (base + size >= tce_alloc_start)
506 tce_alloc_start = base + size + 1; 505 tce_alloc_start = base + size + 1;
507 506
508 BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end, 507 BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
509 tce_alloc_start, mode_rw, 508 __pa(tce_alloc_start), mode_rw,
510 mmu_linear_psize)); 509 mmu_linear_psize));
511 } 510 }
512 511
@@ -517,7 +516,7 @@ void __init htab_initialize(void)
517 516
518void htab_initialize_secondary(void) 517void htab_initialize_secondary(void)
519{ 518{
520 if (!platform_is_lpar()) 519 if (!firmware_has_feature(FW_FEATURE_LPAR))
521 mtspr(SPRN_SDR1, _SDR1); 520 mtspr(SPRN_SDR1, _SDR1);
522} 521}
523 522
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index b51bb28c054b..7370f9f33e29 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -133,21 +133,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
133 return __pte(old); 133 return __pte(old);
134} 134}
135 135
136/*
137 * This function checks for proper alignment of input addr and len parameters.
138 */
139int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
140{
141 if (len & ~HPAGE_MASK)
142 return -EINVAL;
143 if (addr & ~HPAGE_MASK)
144 return -EINVAL;
145 if (! (within_hugepage_low_range(addr, len)
146 || within_hugepage_high_range(addr, len)) )
147 return -EINVAL;
148 return 0;
149}
150
151struct slb_flush_info { 136struct slb_flush_info {
152 struct mm_struct *mm; 137 struct mm_struct *mm;
153 u16 newareas; 138 u16 newareas;
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index 8b0c132bc163..add8c1a9af68 100644
--- a/arch/powerpc/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -13,12 +13,12 @@
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/semaphore.h> 16#include <linux/mutex.h>
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18 18
19#include "mmu_decl.h" 19#include "mmu_decl.h"
20 20
21static DECLARE_MUTEX(imlist_sem); 21static DEFINE_MUTEX(imlist_mutex);
22struct vm_struct * imlist = NULL; 22struct vm_struct * imlist = NULL;
23 23
24static int get_free_im_addr(unsigned long size, unsigned long *im_addr) 24static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
@@ -257,7 +257,7 @@ struct vm_struct * im_get_free_area(unsigned long size)
257 struct vm_struct *area; 257 struct vm_struct *area;
258 unsigned long addr; 258 unsigned long addr;
259 259
260 down(&imlist_sem); 260 mutex_lock(&imlist_mutex);
261 if (get_free_im_addr(size, &addr)) { 261 if (get_free_im_addr(size, &addr)) {
262 printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n", 262 printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
263 __FUNCTION__, size); 263 __FUNCTION__, size);
@@ -272,7 +272,7 @@ struct vm_struct * im_get_free_area(unsigned long size)
272 __FUNCTION__, addr, size); 272 __FUNCTION__, addr, size);
273 } 273 }
274next_im_done: 274next_im_done:
275 up(&imlist_sem); 275 mutex_unlock(&imlist_mutex);
276 return area; 276 return area;
277} 277}
278 278
@@ -281,9 +281,9 @@ struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
281{ 281{
282 struct vm_struct *area; 282 struct vm_struct *area;
283 283
284 down(&imlist_sem); 284 mutex_lock(&imlist_mutex);
285 area = __im_get_area(v_addr, size, criteria); 285 area = __im_get_area(v_addr, size, criteria);
286 up(&imlist_sem); 286 mutex_unlock(&imlist_mutex);
287 return area; 287 return area;
288} 288}
289 289
@@ -297,17 +297,17 @@ void im_free(void * addr)
297 printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr); 297 printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr);
298 return; 298 return;
299 } 299 }
300 down(&imlist_sem); 300 mutex_lock(&imlist_mutex);
301 for (p = &imlist ; (tmp = *p) ; p = &tmp->next) { 301 for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
302 if (tmp->addr == addr) { 302 if (tmp->addr == addr) {
303 *p = tmp->next; 303 *p = tmp->next;
304 unmap_vm_area(tmp); 304 unmap_vm_area(tmp);
305 kfree(tmp); 305 kfree(tmp);
306 up(&imlist_sem); 306 mutex_unlock(&imlist_mutex);
307 return; 307 return;
308 } 308 }
309 } 309 }
310 up(&imlist_sem); 310 mutex_unlock(&imlist_mutex);
311 printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__, 311 printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
312 addr); 312 addr);
313} 313}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 7d0d75c11848..b57fb3a2b7bb 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -216,7 +216,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
216 216
217 while (start < end) { 217 while (start < end) {
218 ClearPageReserved(virt_to_page(start)); 218 ClearPageReserved(virt_to_page(start));
219 set_page_count(virt_to_page(start), 1); 219 init_page_count(virt_to_page(start));
220 free_page(start); 220 free_page(start);
221 cnt++; 221 cnt++;
222 start += PAGE_SIZE; 222 start += PAGE_SIZE;
@@ -248,7 +248,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
248 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 248 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
249 for (; start < end; start += PAGE_SIZE) { 249 for (; start < end; start += PAGE_SIZE) {
250 ClearPageReserved(virt_to_page(start)); 250 ClearPageReserved(virt_to_page(start));
251 set_page_count(virt_to_page(start), 1); 251 init_page_count(virt_to_page(start));
252 free_page(start); 252 free_page(start);
253 totalram_pages++; 253 totalram_pages++;
254 } 254 }
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 81cfb0c2ec58..babebd15bdc4 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -84,54 +84,6 @@
84/* max amount of RAM to use */ 84/* max amount of RAM to use */
85unsigned long __max_memory; 85unsigned long __max_memory;
86 86
87/* info on what we think the IO hole is */
88unsigned long io_hole_start;
89unsigned long io_hole_size;
90
91/*
92 * Do very early mm setup.
93 */
94void __init mm_init_ppc64(void)
95{
96#ifndef CONFIG_PPC_ISERIES
97 unsigned long i;
98#endif
99
100 ppc64_boot_msg(0x100, "MM Init");
101
102 /* This is the story of the IO hole... please, keep seated,
103 * unfortunately, we are out of oxygen masks at the moment.
104 * So we need some rough way to tell where your big IO hole
105 * is. On pmac, it's between 2G and 4G, on POWER3, it's around
106 * that area as well, on POWER4 we don't have one, etc...
107 * We need that as a "hint" when sizing the TCE table on POWER3
108 * So far, the simplest way that seem work well enough for us it
109 * to just assume that the first discontinuity in our physical
110 * RAM layout is the IO hole. That may not be correct in the future
111 * (and isn't on iSeries but then we don't care ;)
112 */
113
114#ifndef CONFIG_PPC_ISERIES
115 for (i = 1; i < lmb.memory.cnt; i++) {
116 unsigned long base, prevbase, prevsize;
117
118 prevbase = lmb.memory.region[i-1].base;
119 prevsize = lmb.memory.region[i-1].size;
120 base = lmb.memory.region[i].base;
121 if (base > (prevbase + prevsize)) {
122 io_hole_start = prevbase + prevsize;
123 io_hole_size = base - (prevbase + prevsize);
124 break;
125 }
126 }
127#endif /* CONFIG_PPC_ISERIES */
128 if (io_hole_start)
129 printk("IO Hole assumed to be %lx -> %lx\n",
130 io_hole_start, io_hole_start + io_hole_size - 1);
131
132 ppc64_boot_msg(0x100, "MM Init Done");
133}
134
135void free_initmem(void) 87void free_initmem(void)
136{ 88{
137 unsigned long addr; 89 unsigned long addr;
@@ -140,7 +92,7 @@ void free_initmem(void)
140 for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { 92 for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
141 memset((void *)addr, 0xcc, PAGE_SIZE); 93 memset((void *)addr, 0xcc, PAGE_SIZE);
142 ClearPageReserved(virt_to_page(addr)); 94 ClearPageReserved(virt_to_page(addr));
143 set_page_count(virt_to_page(addr), 1); 95 init_page_count(virt_to_page(addr));
144 free_page(addr); 96 free_page(addr);
145 totalram_pages++; 97 totalram_pages++;
146 } 98 }
@@ -155,7 +107,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
155 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 107 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
156 for (; start < end; start += PAGE_SIZE) { 108 for (; start < end; start += PAGE_SIZE) {
157 ClearPageReserved(virt_to_page(start)); 109 ClearPageReserved(virt_to_page(start));
158 set_page_count(virt_to_page(start), 1); 110 init_page_count(virt_to_page(start));
159 free_page(start); 111 free_page(start);
160 totalram_pages++; 112 totalram_pages++;
161 } 113 }
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
index bbe3eac918e8..417d58518558 100644
--- a/arch/powerpc/mm/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -31,6 +31,8 @@
31#define DBG(fmt...) 31#define DBG(fmt...)
32#endif 32#endif
33 33
34#define LMB_ALLOC_ANYWHERE 0
35
34struct lmb lmb; 36struct lmb lmb;
35 37
36void lmb_dump_all(void) 38void lmb_dump_all(void)
@@ -226,6 +228,20 @@ unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
226unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align, 228unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
227 unsigned long max_addr) 229 unsigned long max_addr)
228{ 230{
231 unsigned long alloc;
232
233 alloc = __lmb_alloc_base(size, align, max_addr);
234
235 if (alloc == 0)
236 panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
237 size, max_addr);
238
239 return alloc;
240}
241
242unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
243 unsigned long max_addr)
244{
229 long i, j; 245 long i, j;
230 unsigned long base = 0; 246 unsigned long base = 0;
231 247
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 550517c2dd42..741dd8802d49 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -108,8 +108,8 @@ EXPORT_SYMBOL(phys_mem_access_prot);
108void online_page(struct page *page) 108void online_page(struct page *page)
109{ 109{
110 ClearPageReserved(page); 110 ClearPageReserved(page);
111 set_page_count(page, 0); 111 init_page_count(page);
112 free_cold_page(page); 112 __free_page(page);
113 totalram_pages++; 113 totalram_pages++;
114 num_physpages++; 114 num_physpages++;
115} 115}
@@ -125,7 +125,7 @@ int __devinit add_memory(u64 start, u64 size)
125 nid = hot_add_scn_to_nid(start); 125 nid = hot_add_scn_to_nid(start);
126 pgdata = NODE_DATA(nid); 126 pgdata = NODE_DATA(nid);
127 127
128 start = __va(start); 128 start = (unsigned long)__va(start);
129 create_section_mapping(start, start + size); 129 create_section_mapping(start, start + size);
130 130
131 /* this should work for most non-highmem platforms */ 131 /* this should work for most non-highmem platforms */
@@ -195,7 +195,7 @@ void show_mem(void)
195 printk("Mem-info:\n"); 195 printk("Mem-info:\n");
196 show_free_areas(); 196 show_free_areas();
197 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 197 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
198 for_each_pgdat(pgdat) { 198 for_each_online_pgdat(pgdat) {
199 unsigned long flags; 199 unsigned long flags;
200 pgdat_resize_lock(pgdat, &flags); 200 pgdat_resize_lock(pgdat, &flags);
201 for (i = 0; i < pgdat->node_spanned_pages; i++) { 201 for (i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -249,7 +249,6 @@ void __init do_init_bootmem(void)
249 bootmap_pages = bootmem_bootmap_pages(total_pages); 249 bootmap_pages = bootmem_bootmap_pages(total_pages);
250 250
251 start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); 251 start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
252 BUG_ON(!start);
253 252
254 boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); 253 boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
255 254
@@ -343,7 +342,7 @@ void __init mem_init(void)
343#ifdef CONFIG_NEED_MULTIPLE_NODES 342#ifdef CONFIG_NEED_MULTIPLE_NODES
344 for_each_online_node(nid) { 343 for_each_online_node(nid) {
345 if (NODE_DATA(nid)->node_spanned_pages != 0) { 344 if (NODE_DATA(nid)->node_spanned_pages != 0) {
346 printk("freeing bootmem node %x\n", nid); 345 printk("freeing bootmem node %d\n", nid);
347 totalram_pages += 346 totalram_pages +=
348 free_all_bootmem_node(NODE_DATA(nid)); 347 free_all_bootmem_node(NODE_DATA(nid));
349 } 348 }
@@ -352,7 +351,7 @@ void __init mem_init(void)
352 max_mapnr = max_pfn; 351 max_mapnr = max_pfn;
353 totalram_pages += free_all_bootmem(); 352 totalram_pages += free_all_bootmem();
354#endif 353#endif
355 for_each_pgdat(pgdat) { 354 for_each_online_pgdat(pgdat) {
356 for (i = 0; i < pgdat->node_spanned_pages; i++) { 355 for (i = 0; i < pgdat->node_spanned_pages; i++) {
357 if (!pfn_valid(pgdat->node_start_pfn + i)) 356 if (!pfn_valid(pgdat->node_start_pfn + i))
358 continue; 357 continue;
@@ -376,7 +375,7 @@ void __init mem_init(void)
376 struct page *page = pfn_to_page(pfn); 375 struct page *page = pfn_to_page(pfn);
377 376
378 ClearPageReserved(page); 377 ClearPageReserved(page);
379 set_page_count(page, 1); 378 init_page_count(page);
380 __free_page(page); 379 __free_page(page);
381 totalhigh_pages++; 380 totalhigh_pages++;
382 } 381 }
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index fe65f522aff3..972a8e884b9a 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/mm/mmap.c
3 *
4 * flexible mmap layout support 2 * flexible mmap layout support
5 * 3 *
6 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 2863a912bcd0..0a335f34974c 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -129,10 +129,12 @@ void __init get_region(unsigned int nid, unsigned long *start_pfn,
129 *start_pfn = 0; 129 *start_pfn = 0;
130} 130}
131 131
132static inline void map_cpu_to_node(int cpu, int node) 132static void __cpuinit map_cpu_to_node(int cpu, int node)
133{ 133{
134 numa_cpu_lookup_table[cpu] = node; 134 numa_cpu_lookup_table[cpu] = node;
135 135
136 dbg("adding cpu %d to node %d\n", cpu, node);
137
136 if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) 138 if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node])))
137 cpu_set(cpu, numa_cpumask_lookup_table[node]); 139 cpu_set(cpu, numa_cpumask_lookup_table[node]);
138} 140}
@@ -153,7 +155,7 @@ static void unmap_cpu_from_node(unsigned long cpu)
153} 155}
154#endif /* CONFIG_HOTPLUG_CPU */ 156#endif /* CONFIG_HOTPLUG_CPU */
155 157
156static struct device_node *find_cpu_node(unsigned int cpu) 158static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
157{ 159{
158 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); 160 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
159 struct device_node *cpu_node = NULL; 161 struct device_node *cpu_node = NULL;
@@ -189,23 +191,29 @@ static int *of_get_associativity(struct device_node *dev)
189 return (unsigned int *)get_property(dev, "ibm,associativity", NULL); 191 return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
190} 192}
191 193
192static int of_node_numa_domain(struct device_node *device) 194/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
195 * info is found.
196 */
197static int of_node_to_nid(struct device_node *device)
193{ 198{
194 int numa_domain; 199 int nid = -1;
195 unsigned int *tmp; 200 unsigned int *tmp;
196 201
197 if (min_common_depth == -1) 202 if (min_common_depth == -1)
198 return 0; 203 goto out;
199 204
200 tmp = of_get_associativity(device); 205 tmp = of_get_associativity(device);
201 if (tmp && (tmp[0] >= min_common_depth)) { 206 if (!tmp)
202 numa_domain = tmp[min_common_depth]; 207 goto out;
203 } else { 208
204 dbg("WARNING: no NUMA information for %s\n", 209 if (tmp[0] >= min_common_depth)
205 device->full_name); 210 nid = tmp[min_common_depth];
206 numa_domain = 0; 211
207 } 212 /* POWER4 LPAR uses 0xffff as invalid node */
208 return numa_domain; 213 if (nid == 0xffff || nid >= MAX_NUMNODES)
214 nid = -1;
215out:
216 return nid;
209} 217}
210 218
211/* 219/*
@@ -246,8 +254,7 @@ static int __init find_min_common_depth(void)
246 if ((len >= 1) && ref_points) { 254 if ((len >= 1) && ref_points) {
247 depth = ref_points[1]; 255 depth = ref_points[1];
248 } else { 256 } else {
249 dbg("WARNING: could not find NUMA " 257 dbg("NUMA: ibm,associativity-reference-points not found.\n");
250 "associativity reference point\n");
251 depth = -1; 258 depth = -1;
252 } 259 }
253 of_node_put(rtas_root); 260 of_node_put(rtas_root);
@@ -283,9 +290,9 @@ static unsigned long __devinit read_n_cells(int n, unsigned int **buf)
283 * Figure out to which domain a cpu belongs and stick it there. 290 * Figure out to which domain a cpu belongs and stick it there.
284 * Return the id of the domain used. 291 * Return the id of the domain used.
285 */ 292 */
286static int numa_setup_cpu(unsigned long lcpu) 293static int __cpuinit numa_setup_cpu(unsigned long lcpu)
287{ 294{
288 int numa_domain = 0; 295 int nid = 0;
289 struct device_node *cpu = find_cpu_node(lcpu); 296 struct device_node *cpu = find_cpu_node(lcpu);
290 297
291 if (!cpu) { 298 if (!cpu) {
@@ -293,27 +300,16 @@ static int numa_setup_cpu(unsigned long lcpu)
293 goto out; 300 goto out;
294 } 301 }
295 302
296 numa_domain = of_node_numa_domain(cpu); 303 nid = of_node_to_nid(cpu);
297 304
298 if (numa_domain >= num_online_nodes()) { 305 if (nid < 0 || !node_online(nid))
299 /* 306 nid = any_online_node(NODE_MASK_ALL);
300 * POWER4 LPAR uses 0xffff as invalid node,
301 * dont warn in this case.
302 */
303 if (numa_domain != 0xffff)
304 printk(KERN_ERR "WARNING: cpu %ld "
305 "maps to invalid NUMA node %d\n",
306 lcpu, numa_domain);
307 numa_domain = 0;
308 }
309out: 307out:
310 node_set_online(numa_domain); 308 map_cpu_to_node(lcpu, nid);
311
312 map_cpu_to_node(lcpu, numa_domain);
313 309
314 of_node_put(cpu); 310 of_node_put(cpu);
315 311
316 return numa_domain; 312 return nid;
317} 313}
318 314
319static int cpu_numa_callback(struct notifier_block *nfb, 315static int cpu_numa_callback(struct notifier_block *nfb,
@@ -325,10 +321,7 @@ static int cpu_numa_callback(struct notifier_block *nfb,
325 321
326 switch (action) { 322 switch (action) {
327 case CPU_UP_PREPARE: 323 case CPU_UP_PREPARE:
328 if (min_common_depth == -1 || !numa_enabled) 324 numa_setup_cpu(lcpu);
329 map_cpu_to_node(lcpu, 0);
330 else
331 numa_setup_cpu(lcpu);
332 ret = NOTIFY_OK; 325 ret = NOTIFY_OK;
333 break; 326 break;
334#ifdef CONFIG_HOTPLUG_CPU 327#ifdef CONFIG_HOTPLUG_CPU
@@ -375,7 +368,7 @@ static int __init parse_numa_properties(void)
375{ 368{
376 struct device_node *cpu = NULL; 369 struct device_node *cpu = NULL;
377 struct device_node *memory = NULL; 370 struct device_node *memory = NULL;
378 int max_domain; 371 int default_nid = 0;
379 unsigned long i; 372 unsigned long i;
380 373
381 if (numa_enabled == 0) { 374 if (numa_enabled == 0) {
@@ -385,32 +378,32 @@ static int __init parse_numa_properties(void)
385 378
386 min_common_depth = find_min_common_depth(); 379 min_common_depth = find_min_common_depth();
387 380
388 dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
389 if (min_common_depth < 0) 381 if (min_common_depth < 0)
390 return min_common_depth; 382 return min_common_depth;
391 383
392 max_domain = numa_setup_cpu(boot_cpuid); 384 dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
393 385
394 /* 386 /*
395 * Even though we connect cpus to numa domains later in SMP init, 387 * Even though we connect cpus to numa domains later in SMP
396 * we need to know the maximum node id now. This is because each 388 * init, we need to know the node ids now. This is because
397 * node id must have NODE_DATA etc backing it. 389 * each node to be onlined must have NODE_DATA etc backing it.
398 * As a result of hotplug we could still have cpus appear later on
399 * with larger node ids. In that case we force the cpu into node 0.
400 */ 390 */
401 for_each_cpu(i) { 391 for_each_present_cpu(i) {
402 int numa_domain; 392 int nid;
403 393
404 cpu = find_cpu_node(i); 394 cpu = find_cpu_node(i);
395 BUG_ON(!cpu);
396 nid = of_node_to_nid(cpu);
397 of_node_put(cpu);
405 398
406 if (cpu) { 399 /*
407 numa_domain = of_node_numa_domain(cpu); 400 * Don't fall back to default_nid yet -- we will plug
408 of_node_put(cpu); 401 * cpus into nodes once the memory scan has discovered
409 402 * the topology.
410 if (numa_domain < MAX_NUMNODES && 403 */
411 max_domain < numa_domain) 404 if (nid < 0)
412 max_domain = numa_domain; 405 continue;
413 } 406 node_set_online(nid);
414 } 407 }
415 408
416 get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); 409 get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
@@ -418,7 +411,7 @@ static int __init parse_numa_properties(void)
418 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 411 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
419 unsigned long start; 412 unsigned long start;
420 unsigned long size; 413 unsigned long size;
421 int numa_domain; 414 int nid;
422 int ranges; 415 int ranges;
423 unsigned int *memcell_buf; 416 unsigned int *memcell_buf;
424 unsigned int len; 417 unsigned int len;
@@ -439,18 +432,15 @@ new_range:
439 start = read_n_cells(n_mem_addr_cells, &memcell_buf); 432 start = read_n_cells(n_mem_addr_cells, &memcell_buf);
440 size = read_n_cells(n_mem_size_cells, &memcell_buf); 433 size = read_n_cells(n_mem_size_cells, &memcell_buf);
441 434
442 numa_domain = of_node_numa_domain(memory); 435 /*
443 436 * Assumption: either all memory nodes or none will
444 if (numa_domain >= MAX_NUMNODES) { 437 * have associativity properties. If none, then
445 if (numa_domain != 0xffff) 438 * everything goes to default_nid.
446 printk(KERN_ERR "WARNING: memory at %lx maps " 439 */
447 "to invalid NUMA node %d\n", start, 440 nid = of_node_to_nid(memory);
448 numa_domain); 441 if (nid < 0)
449 numa_domain = 0; 442 nid = default_nid;
450 } 443 node_set_online(nid);
451
452 if (max_domain < numa_domain)
453 max_domain = numa_domain;
454 444
455 if (!(size = numa_enforce_memory_limit(start, size))) { 445 if (!(size = numa_enforce_memory_limit(start, size))) {
456 if (--ranges) 446 if (--ranges)
@@ -459,16 +449,13 @@ new_range:
459 continue; 449 continue;
460 } 450 }
461 451
462 add_region(numa_domain, start >> PAGE_SHIFT, 452 add_region(nid, start >> PAGE_SHIFT,
463 size >> PAGE_SHIFT); 453 size >> PAGE_SHIFT);
464 454
465 if (--ranges) 455 if (--ranges)
466 goto new_range; 456 goto new_range;
467 } 457 }
468 458
469 for (i = 0; i <= max_domain; i++)
470 node_set_online(i);
471
472 return 0; 459 return 0;
473} 460}
474 461
@@ -483,7 +470,6 @@ static void __init setup_nonnuma(void)
483 printk(KERN_INFO "Memory hole size: %ldMB\n", 470 printk(KERN_INFO "Memory hole size: %ldMB\n",
484 (top_of_ram - total_ram) >> 20); 471 (top_of_ram - total_ram) >> 20);
485 472
486 map_cpu_to_node(boot_cpuid, 0);
487 for (i = 0; i < lmb.memory.cnt; ++i) 473 for (i = 0; i < lmb.memory.cnt; ++i)
488 add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, 474 add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
489 lmb_size_pages(&lmb.memory, i)); 475 lmb_size_pages(&lmb.memory, i));
@@ -570,11 +556,11 @@ static void __init *careful_allocation(int nid, unsigned long size,
570 unsigned long end_pfn) 556 unsigned long end_pfn)
571{ 557{
572 int new_nid; 558 int new_nid;
573 unsigned long ret = lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT); 559 unsigned long ret = __lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT);
574 560
575 /* retry over all memory */ 561 /* retry over all memory */
576 if (!ret) 562 if (!ret)
577 ret = lmb_alloc_base(size, align, lmb_end_of_DRAM()); 563 ret = __lmb_alloc_base(size, align, lmb_end_of_DRAM());
578 564
579 if (!ret) 565 if (!ret)
580 panic("numa.c: cannot allocate %lu bytes on node %d", 566 panic("numa.c: cannot allocate %lu bytes on node %d",
@@ -620,6 +606,8 @@ void __init do_init_bootmem(void)
620 dump_numa_memory_topology(); 606 dump_numa_memory_topology();
621 607
622 register_cpu_notifier(&ppc64_numa_nb); 608 register_cpu_notifier(&ppc64_numa_nb);
609 cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
610 (void *)(unsigned long)boot_cpuid);
623 611
624 for_each_online_node(nid) { 612 for_each_online_node(nid) {
625 unsigned long start_pfn, end_pfn, pages_present; 613 unsigned long start_pfn, end_pfn, pages_present;
@@ -767,10 +755,11 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
767{ 755{
768 struct device_node *memory = NULL; 756 struct device_node *memory = NULL;
769 nodemask_t nodes; 757 nodemask_t nodes;
770 int numa_domain = 0; 758 int default_nid = any_online_node(NODE_MASK_ALL);
759 int nid;
771 760
772 if (!numa_enabled || (min_common_depth < 0)) 761 if (!numa_enabled || (min_common_depth < 0))
773 return numa_domain; 762 return default_nid;
774 763
775 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 764 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
776 unsigned long start, size; 765 unsigned long start, size;
@@ -787,29 +776,30 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
787ha_new_range: 776ha_new_range:
788 start = read_n_cells(n_mem_addr_cells, &memcell_buf); 777 start = read_n_cells(n_mem_addr_cells, &memcell_buf);
789 size = read_n_cells(n_mem_size_cells, &memcell_buf); 778 size = read_n_cells(n_mem_size_cells, &memcell_buf);
790 numa_domain = of_node_numa_domain(memory); 779 nid = of_node_to_nid(memory);
791 780
792 /* Domains not present at boot default to 0 */ 781 /* Domains not present at boot default to 0 */
793 if (!node_online(numa_domain)) 782 if (nid < 0 || !node_online(nid))
794 numa_domain = any_online_node(NODE_MASK_ALL); 783 nid = default_nid;
795 784
796 if ((scn_addr >= start) && (scn_addr < (start + size))) { 785 if ((scn_addr >= start) && (scn_addr < (start + size))) {
797 of_node_put(memory); 786 of_node_put(memory);
798 goto got_numa_domain; 787 goto got_nid;
799 } 788 }
800 789
801 if (--ranges) /* process all ranges in cell */ 790 if (--ranges) /* process all ranges in cell */
802 goto ha_new_range; 791 goto ha_new_range;
803 } 792 }
804 BUG(); /* section address should be found above */ 793 BUG(); /* section address should be found above */
794 return 0;
805 795
806 /* Temporary code to ensure that returned node is not empty */ 796 /* Temporary code to ensure that returned node is not empty */
807got_numa_domain: 797got_nid:
808 nodes_setall(nodes); 798 nodes_setall(nodes);
809 while (NODE_DATA(numa_domain)->node_spanned_pages == 0) { 799 while (NODE_DATA(nid)->node_spanned_pages == 0) {
810 node_clear(numa_domain, nodes); 800 node_clear(nid, nodes);
811 numa_domain = any_online_node(nodes); 801 nid = any_online_node(nodes);
812 } 802 }
813 return numa_domain; 803 return nid;
814} 804}
815#endif /* CONFIG_MEMORY_HOTPLUG */ 805#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index f4e5ac122615..90628601fac7 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -37,6 +37,7 @@
37 37
38unsigned long ioremap_base; 38unsigned long ioremap_base;
39unsigned long ioremap_bot; 39unsigned long ioremap_bot;
40EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
40int io_bat_index; 41int io_bat_index;
41 42
42#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) 43#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
@@ -153,6 +154,7 @@ ioremap64(unsigned long long addr, unsigned long size)
153{ 154{
154 return __ioremap(addr, size, _PAGE_NO_CACHE); 155 return __ioremap(addr, size, _PAGE_NO_CACHE);
155} 156}
157EXPORT_SYMBOL(ioremap64);
156 158
157void __iomem * 159void __iomem *
158ioremap(phys_addr_t addr, unsigned long size) 160ioremap(phys_addr_t addr, unsigned long size)
@@ -162,6 +164,7 @@ ioremap(phys_addr_t addr, unsigned long size)
162 return ioremap64(addr64, size); 164 return ioremap64(addr64, size);
163} 165}
164#endif /* CONFIG_PHYS_64BIT */ 166#endif /* CONFIG_PHYS_64BIT */
167EXPORT_SYMBOL(ioremap);
165 168
166void __iomem * 169void __iomem *
167__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) 170__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
@@ -247,6 +250,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
247out: 250out:
248 return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK)); 251 return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
249} 252}
253EXPORT_SYMBOL(__ioremap);
250 254
251void iounmap(volatile void __iomem *addr) 255void iounmap(volatile void __iomem *addr)
252{ 256{
@@ -259,6 +263,7 @@ void iounmap(volatile void __iomem *addr)
259 if (addr > high_memory && (unsigned long) addr < ioremap_bot) 263 if (addr > high_memory && (unsigned long) addr < ioremap_bot)
260 vunmap((void *) (PAGE_MASK & (unsigned long)addr)); 264 vunmap((void *) (PAGE_MASK & (unsigned long)addr));
261} 265}
266EXPORT_SYMBOL(iounmap);
262 267
263void __iomem *ioport_map(unsigned long port, unsigned int len) 268void __iomem *ioport_map(unsigned long port, unsigned int len)
264{ 269{
@@ -367,7 +372,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
367 * the PTE pointer is unmodified if PTE is not found. 372 * the PTE pointer is unmodified if PTE is not found.
368 */ 373 */
369int 374int
370get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) 375get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
371{ 376{
372 pgd_t *pgd; 377 pgd_t *pgd;
373 pmd_t *pmd; 378 pmd_t *pmd;
@@ -382,6 +387,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
382 if (pte) { 387 if (pte) {
383 retval = 1; 388 retval = 1;
384 *ptep = pte; 389 *ptep = pte;
390 if (pmdp)
391 *pmdp = pmd;
385 /* XXX caller needs to do pte_unmap, yuck */ 392 /* XXX caller needs to do pte_unmap, yuck */
386 } 393 }
387 } 394 }
@@ -419,7 +426,7 @@ unsigned long iopa(unsigned long addr)
419 mm = &init_mm; 426 mm = &init_mm;
420 427
421 pa = 0; 428 pa = 0;
422 if (get_pteptr(mm, addr, &pte)) { 429 if (get_pteptr(mm, addr, &pte, NULL)) {
423 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); 430 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
424 pte_unmap(pte); 431 pte_unmap(pte);
425 } 432 }
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index d1acee38f163..abfaabf667bf 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/mm/slb_low.S
3 *
4 * Low-level SLB routines 2 * Low-level SLB routines
5 * 3 *
6 * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM 4 * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 82e4951826bc..4a9291d9fef8 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -239,7 +239,7 @@ void stabs_alloc(void)
239 if (cpu_has_feature(CPU_FTR_SLB)) 239 if (cpu_has_feature(CPU_FTR_SLB))
240 return; 240 return;
241 241
242 for_each_cpu(cpu) { 242 for_each_possible_cpu(cpu) {
243 unsigned long newstab; 243 unsigned long newstab;
244 244
245 if (cpu == 0) 245 if (cpu == 0)
@@ -247,10 +247,6 @@ void stabs_alloc(void)
247 247
248 newstab = lmb_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE, 248 newstab = lmb_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE,
249 1<<SID_SHIFT); 249 1<<SID_SHIFT);
250 if (! newstab)
251 panic("Unable to allocate segment table for CPU %d.\n",
252 cpu);
253
254 newstab = (unsigned long)__va(newstab); 250 newstab = (unsigned long)__va(newstab);
255 251
256 memset((void *)newstab, 0, HW_PAGE_SIZE); 252 memset((void *)newstab, 0, HW_PAGE_SIZE);
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index bb3afb6e6317..f734b11566c2 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -36,7 +36,7 @@
36DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); 36DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
37 37
38/* This is declared as we are using the more or less generic 38/* This is declared as we are using the more or less generic
39 * include/asm-ppc64/tlb.h file -- tgall 39 * include/asm-powerpc/tlb.h file -- tgall
40 */ 40 */
41DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 41DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
42DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); 42DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 554cd7c75321..f5f9859a8338 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -6,7 +6,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
6 oprofilefs.o oprofile_stats.o \ 6 oprofilefs.o oprofile_stats.o \
7 timer_int.o ) 7 timer_int.o )
8 8
9oprofile-y := $(DRIVER_OBJS) common.o 9oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o 10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
12oprofile-$(CONFIG_PPC32) += op_model_7450.o 12oprofile-$(CONFIG_PPC32) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
new file mode 100644
index 000000000000..75f57bc96b40
--- /dev/null
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -0,0 +1,126 @@
1/**
2 * Copyright (C) 2005 Brian Rogan <bcr6@cornell.edu>, IBM
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8**/
9
10#include <linux/oprofile.h>
11#include <linux/sched.h>
12#include <asm/processor.h>
13#include <asm/uaccess.h>
14
15#define STACK_SP(STACK) *(STACK)
16
17#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2)
18#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1)
19
20#ifdef CONFIG_PPC64
21#define STACK_LR(STACK) STACK_LR64(STACK)
22#else
23#define STACK_LR(STACK) STACK_LR32(STACK)
24#endif
25
26static unsigned int user_getsp32(unsigned int sp, int is_first)
27{
28 unsigned int stack_frame[2];
29
30 if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
31 return 0;
32
33 /*
34 * The most likely reason for this is that we returned -EFAULT,
35 * which means that we've done all that we can do from
36 * interrupt context.
37 */
38 if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
39 sizeof(stack_frame)))
40 return 0;
41
42 if (!is_first)
43 oprofile_add_trace(STACK_LR32(stack_frame));
44
45 /*
46 * We do not enforce increasing stack addresses here because
47 * we may transition to a different stack, eg a signal handler.
48 */
49 return STACK_SP(stack_frame);
50}
51
52#ifdef CONFIG_PPC64
53static unsigned long user_getsp64(unsigned long sp, int is_first)
54{
55 unsigned long stack_frame[3];
56
57 if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
58 return 0;
59
60 if (__copy_from_user_inatomic(stack_frame, (void *)sp,
61 sizeof(stack_frame)))
62 return 0;
63
64 if (!is_first)
65 oprofile_add_trace(STACK_LR64(stack_frame));
66
67 return STACK_SP(stack_frame);
68}
69#endif
70
71static unsigned long kernel_getsp(unsigned long sp, int is_first)
72{
73 unsigned long *stack_frame = (unsigned long *)sp;
74
75 if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
76 return 0;
77
78 if (!is_first)
79 oprofile_add_trace(STACK_LR(stack_frame));
80
81 /*
82 * We do not enforce increasing stack addresses here because
83 * we might be transitioning from an interrupt stack to a kernel
84 * stack. validate_sp() is designed to understand this, so just
85 * use it.
86 */
87 return STACK_SP(stack_frame);
88}
89
90void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
91{
92 unsigned long sp = regs->gpr[1];
93 int first_frame = 1;
94
95 /* We ditch the top stackframe so need to loop through an extra time */
96 depth += 1;
97
98 if (!user_mode(regs)) {
99 while (depth--) {
100 sp = kernel_getsp(sp, first_frame);
101 if (!sp)
102 break;
103 first_frame = 0;
104 }
105 } else {
106#ifdef CONFIG_PPC64
107 if (!test_thread_flag(TIF_32BIT)) {
108 while (depth--) {
109 sp = user_getsp64(sp, first_frame);
110 if (!sp)
111 break;
112 first_frame = 0;
113 }
114
115 return;
116 }
117#endif
118
119 while (depth--) {
120 sp = user_getsp32(sp, first_frame);
121 if (!sp)
122 break;
123 first_frame = 0;
124 }
125 }
126}
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index cc2535be3a73..5b1de7e8041e 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -117,18 +117,10 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
117 117
118 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); 118 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
119 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); 119 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
120#ifdef CONFIG_PPC64
121 oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
122 &sys.backtrace_spinlocks);
123#endif
124 120
125 /* Default to tracing both kernel and user */ 121 /* Default to tracing both kernel and user */
126 sys.enable_kernel = 1; 122 sys.enable_kernel = 1;
127 sys.enable_user = 1; 123 sys.enable_user = 1;
128#ifdef CONFIG_PPC64
129 /* Turn on backtracing through spinlocks by default */
130 sys.backtrace_spinlocks = 1;
131#endif
132 124
133 return 0; 125 return 0;
134} 126}
@@ -168,6 +160,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
168 ops->shutdown = op_powerpc_shutdown; 160 ops->shutdown = op_powerpc_shutdown;
169 ops->start = op_powerpc_start; 161 ops->start = op_powerpc_start;
170 ops->stop = op_powerpc_stop; 162 ops->stop = op_powerpc_stop;
163 ops->backtrace = op_powerpc_backtrace;
171 164
172 printk(KERN_INFO "oprofile: using %s performance monitoring.\n", 165 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
173 ops->cpu_type); 166 ops->cpu_type);
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index 32abfdbb0eb1..e0491c3c71f1 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs,
176 mtmsr(mfmsr() | MSR_PMM); 176 mtmsr(mfmsr() | MSR_PMM);
177 177
178 pc = mfspr(SPRN_SIAR); 178 pc = mfspr(SPRN_SIAR);
179 is_kernel = (pc >= KERNELBASE); 179 is_kernel = is_kernel_addr(pc);
180 180
181 for (i = 0; i < NUM_CTRS; ++i) { 181 for (i = 0; i < NUM_CTRS; ++i) {
182 val = ctr_read(i); 182 val = ctr_read(i);
183 if (val < 0) { 183 if (val < 0) {
184 if (oprofile_running && ctr[i].enabled) { 184 if (oprofile_running && ctr[i].enabled) {
185 oprofile_add_pc(pc, is_kernel, i); 185 oprofile_add_ext_sample(pc, regs, i, is_kernel);
186 ctr_write(i, reset_value[i]); 186 ctr_write(i, reset_value[i]);
187 } else { 187 } else {
188 ctr_write(i, 0); 188 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index 26539cda6023..93d63e62662f 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
154 mtmsr(mfmsr() | MSR_PMM); 154 mtmsr(mfmsr() | MSR_PMM);
155 155
156 pc = regs->nip; 156 pc = regs->nip;
157 is_kernel = (pc >= KERNELBASE); 157 is_kernel = is_kernel_addr(pc);
158 158
159 for (i = 0; i < num_counters; ++i) { 159 for (i = 0; i < num_counters; ++i) {
160 val = ctr_read(i); 160 val = ctr_read(i);
161 if (val < 0) { 161 if (val < 0) {
162 if (oprofile_running && ctr[i].enabled) { 162 if (oprofile_running && ctr[i].enabled) {
163 oprofile_add_pc(pc, is_kernel, i); 163 oprofile_add_ext_sample(pc, regs, i, is_kernel);
164 ctr_write(i, reset_value[i]); 164 ctr_write(i, reset_value[i]);
165 } else { 165 } else {
166 ctr_write(i, 0); 166 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 659a021da0c7..4c2beab1fdc1 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -10,6 +10,7 @@
10#include <linux/oprofile.h> 10#include <linux/oprofile.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <asm/firmware.h>
13#include <asm/ptrace.h> 14#include <asm/ptrace.h>
14#include <asm/system.h> 15#include <asm/system.h>
15#include <asm/processor.h> 16#include <asm/processor.h>
@@ -24,18 +25,14 @@ static unsigned long reset_value[OP_MAX_COUNTER];
24 25
25static int oprofile_running; 26static int oprofile_running;
26static int mmcra_has_sihv; 27static int mmcra_has_sihv;
28/* Unfortunately these bits vary between CPUs */
29static unsigned long mmcra_sihv = MMCRA_SIHV;
30static unsigned long mmcra_sipr = MMCRA_SIPR;
27 31
28/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ 32/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
29static u32 mmcr0_val; 33static u32 mmcr0_val;
30static u64 mmcr1_val; 34static u64 mmcr1_val;
31static u32 mmcra_val; 35static u64 mmcra_val;
32
33/*
34 * Since we do not have an NMI, backtracing through spinlocks is
35 * only a best guess. In light of this, allow it to be disabled at
36 * runtime.
37 */
38static int backtrace_spinlocks;
39 36
40static void power4_reg_setup(struct op_counter_config *ctr, 37static void power4_reg_setup(struct op_counter_config *ctr,
41 struct op_system_config *sys, 38 struct op_system_config *sys,
@@ -62,8 +59,6 @@ static void power4_reg_setup(struct op_counter_config *ctr,
62 mmcr1_val = sys->mmcr1; 59 mmcr1_val = sys->mmcr1;
63 mmcra_val = sys->mmcra; 60 mmcra_val = sys->mmcra;
64 61
65 backtrace_spinlocks = sys->backtrace_spinlocks;
66
67 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) 62 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
68 reset_value[i] = 0x80000000UL - ctr[i].count; 63 reset_value[i] = 0x80000000UL - ctr[i].count;
69 64
@@ -196,25 +191,6 @@ static void __attribute_used__ kernel_unknown_bucket(void)
196{ 191{
197} 192}
198 193
199static unsigned long check_spinlock_pc(struct pt_regs *regs,
200 unsigned long profile_pc)
201{
202 unsigned long pc = instruction_pointer(regs);
203
204 /*
205 * If both the SIAR (sampled instruction) and the perfmon exception
206 * occurred in a spinlock region then we account the sample to the
207 * calling function. This isnt 100% correct, we really need soft
208 * IRQ disable so we always get the perfmon exception at the
209 * point at which the SIAR is set.
210 */
211 if (backtrace_spinlocks && in_lock_functions(pc) &&
212 in_lock_functions(profile_pc))
213 return regs->link;
214 else
215 return profile_pc;
216}
217
218/* 194/*
219 * On GQ and newer the MMCRA stores the HV and PR bits at the time 195 * On GQ and newer the MMCRA stores the HV and PR bits at the time
220 * the SIAR was sampled. We use that to work out if the SIAR was sampled in 196 * the SIAR was sampled. We use that to work out if the SIAR was sampled in
@@ -227,17 +203,17 @@ static unsigned long get_pc(struct pt_regs *regs)
227 203
228 /* Cant do much about it */ 204 /* Cant do much about it */
229 if (!mmcra_has_sihv) 205 if (!mmcra_has_sihv)
230 return check_spinlock_pc(regs, pc); 206 return pc;
231 207
232 mmcra = mfspr(SPRN_MMCRA); 208 mmcra = mfspr(SPRN_MMCRA);
233 209
234 /* Were we in the hypervisor? */ 210 /* Were we in the hypervisor? */
235 if (platform_is_lpar() && (mmcra & MMCRA_SIHV)) 211 if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv))
236 /* function descriptor madness */ 212 /* function descriptor madness */
237 return *((unsigned long *)hypervisor_bucket); 213 return *((unsigned long *)hypervisor_bucket);
238 214
239 /* We were in userspace, nothing to do */ 215 /* We were in userspace, nothing to do */
240 if (mmcra & MMCRA_SIPR) 216 if (mmcra & mmcra_sipr)
241 return pc; 217 return pc;
242 218
243#ifdef CONFIG_PPC_RTAS 219#ifdef CONFIG_PPC_RTAS
@@ -256,7 +232,7 @@ static unsigned long get_pc(struct pt_regs *regs)
256 /* function descriptor madness */ 232 /* function descriptor madness */
257 return *((unsigned long *)kernel_unknown_bucket); 233 return *((unsigned long *)kernel_unknown_bucket);
258 234
259 return check_spinlock_pc(regs, pc); 235 return pc;
260} 236}
261 237
262static int get_kernel(unsigned long pc) 238static int get_kernel(unsigned long pc)
@@ -267,7 +243,7 @@ static int get_kernel(unsigned long pc)
267 is_kernel = is_kernel_addr(pc); 243 is_kernel = is_kernel_addr(pc);
268 } else { 244 } else {
269 unsigned long mmcra = mfspr(SPRN_MMCRA); 245 unsigned long mmcra = mfspr(SPRN_MMCRA);
270 is_kernel = ((mmcra & MMCRA_SIPR) == 0); 246 is_kernel = ((mmcra & mmcra_sipr) == 0);
271 } 247 }
272 248
273 return is_kernel; 249 return is_kernel;
@@ -292,7 +268,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
292 val = ctr_read(i); 268 val = ctr_read(i);
293 if (val < 0) { 269 if (val < 0) {
294 if (oprofile_running && ctr[i].enabled) { 270 if (oprofile_running && ctr[i].enabled) {
295 oprofile_add_pc(pc, is_kernel, i); 271 oprofile_add_ext_sample(pc, regs, i, is_kernel);
296 ctr_write(i, reset_value[i]); 272 ctr_write(i, reset_value[i]);
297 } else { 273 } else {
298 ctr_write(i, 0); 274 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 5c909ee609fe..042f8f4867ad 100644
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -175,10 +175,13 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
175 struct op_counter_config *ctr) 175 struct op_counter_config *ctr)
176{ 176{
177 unsigned int mmcr0; 177 unsigned int mmcr0;
178 int is_kernel;
178 int val; 179 int val;
179 int i; 180 int i;
180 unsigned long pc = mfspr(SPRN_SIAR); 181 unsigned long pc = mfspr(SPRN_SIAR);
181 182
183 is_kernel = is_kernel_addr(pc);
184
182 /* set the PMM bit (see comment below) */ 185 /* set the PMM bit (see comment below) */
183 mtmsrd(mfmsr() | MSR_PMM); 186 mtmsrd(mfmsr() | MSR_PMM);
184 187
@@ -186,7 +189,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
186 val = ctr_read(i); 189 val = ctr_read(i);
187 if (val < 0) { 190 if (val < 0) {
188 if (ctr[i].enabled) { 191 if (ctr[i].enabled) {
189 oprofile_add_pc(pc, is_kernel_addr(pc), i); 192 oprofile_add_ext_sample(pc, regs, i, is_kernel);
190 ctr_write(i, reset_value[i]); 193 ctr_write(i, reset_value[i]);
191 } else { 194 } else {
192 ctr_write(i, 0); 195 ctr_write(i, 0);
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 9d8b28ef3343..5c72367441a8 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -1,4 +1,6 @@
1# 1#
2# Makefile for the PowerPC 83xx linux kernel. 2# Makefile for the PowerPC 83xx linux kernel.
3# 3#
4obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o pci.o 4obj-y := misc.o
5obj-$(CONFIG_PCI) += pci.o
6obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c
new file mode 100644
index 000000000000..1455bcef4892
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/misc.c
@@ -0,0 +1,55 @@
1/*
2 * misc setup functions for MPC83xx
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15
16#include <asm/io.h>
17#include <asm/hw_irq.h>
18#include <sysdev/fsl_soc.h>
19
20#include "mpc83xx.h"
21
22void mpc83xx_restart(char *cmd)
23{
24#define RST_OFFSET 0x00000900
25#define RST_PROT_REG 0x00000018
26#define RST_CTRL_REG 0x0000001c
27 __be32 __iomem *reg;
28
29 /* map reset register space */
30 reg = ioremap(get_immrbase() + 0x900, 0xff);
31
32 local_irq_disable();
33
34 /* enable software reset "RSTE" */
35 out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
36
37 /* set software hard reset */
38 out_be32(reg + (RST_CTRL_REG >> 2), 0x2);
39 for (;;) ;
40}
41
42long __init mpc83xx_time_init(void)
43{
44#define SPCR_OFFSET 0x00000110
45#define SPCR_TBEN 0x00400000
46 __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
47 __be32 tmp;
48
49 tmp = in_be32(spcr);
50 out_be32(spcr, tmp | SPCR_TBEN);
51
52 iounmap(spcr);
53
54 return 0;
55}
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 2098dd05a773..7c18b4cd5db4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -24,22 +24,15 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <linux/root_dev.h> 26#include <linux/root_dev.h>
27#include <linux/module.h>
28#include <linux/fsl_devices.h>
29 27
30#include <asm/system.h> 28#include <asm/system.h>
31#include <asm/pgtable.h>
32#include <asm/page.h>
33#include <asm/atomic.h> 29#include <asm/atomic.h>
34#include <asm/time.h> 30#include <asm/time.h>
35#include <asm/io.h> 31#include <asm/io.h>
36#include <asm/machdep.h> 32#include <asm/machdep.h>
37#include <asm/ipic.h> 33#include <asm/ipic.h>
38#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
39#include <asm/pci-bridge.h>
40#include <asm/mpc83xx.h>
41#include <asm/irq.h> 35#include <asm/irq.h>
42#include <mm/mmu_decl.h>
43#include <asm/prom.h> 36#include <asm/prom.h>
44#include <asm/udbg.h> 37#include <asm/udbg.h>
45#include <sysdev/fsl_soc.h> 38#include <sysdev/fsl_soc.h>
@@ -52,8 +45,6 @@ unsigned long isa_mem_base = 0;
52#endif 45#endif
53 46
54#ifdef CONFIG_PCI 47#ifdef CONFIG_PCI
55extern int mpc83xx_pci2_busno;
56
57static int 48static int
58mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) 49mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
59{ 50{
@@ -78,26 +69,14 @@ mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
78 const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4; 69 const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
79 return PCI_IRQ_TABLE_LOOKUP; 70 return PCI_IRQ_TABLE_LOOKUP;
80} 71}
81 72#endif /* CONFIG_PCI */
82static int
83mpc83xx_exclude_device(u_char bus, u_char devfn)
84{
85 if (bus == 0 && PCI_SLOT(devfn) == 0)
86 return PCIBIOS_DEVICE_NOT_FOUND;
87 if (mpc83xx_pci2_busno)
88 if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
89 return PCIBIOS_DEVICE_NOT_FOUND;
90 return PCIBIOS_SUCCESSFUL;
91}
92#endif /* CONFIG_PCI */
93 73
94/* ************************************************************************ 74/* ************************************************************************
95 * 75 *
96 * Setup the architecture 76 * Setup the architecture
97 * 77 *
98 */ 78 */
99static void __init 79static void __init mpc834x_sys_setup_arch(void)
100mpc834x_sys_setup_arch(void)
101{ 80{
102 struct device_node *np; 81 struct device_node *np;
103 82
@@ -106,14 +85,14 @@ mpc834x_sys_setup_arch(void)
106 85
107 np = of_find_node_by_type(NULL, "cpu"); 86 np = of_find_node_by_type(NULL, "cpu");
108 if (np != 0) { 87 if (np != 0) {
109 unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL); 88 unsigned int *fp =
89 (int *)get_property(np, "clock-frequency", NULL);
110 if (fp != 0) 90 if (fp != 0)
111 loops_per_jiffy = *fp / HZ; 91 loops_per_jiffy = *fp / HZ;
112 else 92 else
113 loops_per_jiffy = 50000000 / HZ; 93 loops_per_jiffy = 50000000 / HZ;
114 of_node_put(np); 94 of_node_put(np);
115 } 95 }
116
117#ifdef CONFIG_PCI 96#ifdef CONFIG_PCI
118 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 97 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
119 add_bridge(np); 98 add_bridge(np);
@@ -124,14 +103,13 @@ mpc834x_sys_setup_arch(void)
124#endif 103#endif
125 104
126#ifdef CONFIG_ROOT_NFS 105#ifdef CONFIG_ROOT_NFS
127 ROOT_DEV = Root_NFS; 106 ROOT_DEV = Root_NFS;
128#else 107#else
129 ROOT_DEV = Root_HDA1; 108 ROOT_DEV = Root_HDA1;
130#endif 109#endif
131} 110}
132 111
133void __init 112void __init mpc834x_sys_init_IRQ(void)
134mpc834x_sys_init_IRQ(void)
135{ 113{
136 u8 senses[8] = { 114 u8 senses[8] = {
137 0, /* EXT 0 */ 115 0, /* EXT 0 */
@@ -160,64 +138,27 @@ mpc834x_sys_init_IRQ(void)
160} 138}
161 139
162#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374) 140#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
163extern ulong ds1374_get_rtc_time(void); 141extern ulong ds1374_get_rtc_time(void);
164extern int ds1374_set_rtc_time(ulong); 142extern int ds1374_set_rtc_time(ulong);
165 143
166static int __init 144static int __init mpc834x_rtc_hookup(void)
167mpc834x_rtc_hookup(void)
168{ 145{
169 struct timespec tv; 146 struct timespec tv;
170 147
171 ppc_md.get_rtc_time = ds1374_get_rtc_time; 148 ppc_md.get_rtc_time = ds1374_get_rtc_time;
172 ppc_md.set_rtc_time = ds1374_set_rtc_time; 149 ppc_md.set_rtc_time = ds1374_set_rtc_time;
173 150
174 tv.tv_nsec = 0; 151 tv.tv_nsec = 0;
175 tv.tv_sec = (ppc_md.get_rtc_time)(); 152 tv.tv_sec = (ppc_md.get_rtc_time) ();
176 do_settimeofday(&tv); 153 do_settimeofday(&tv);
177 154
178 return 0; 155 return 0;
179} 156}
157
180late_initcall(mpc834x_rtc_hookup); 158late_initcall(mpc834x_rtc_hookup);
181#endif 159#endif
182 160
183static void 161void __init platform_init(void)
184mpc83xx_restart(char *cmd)
185{
186#define RST_OFFSET 0x00000900
187#define RST_PROT_REG 0x00000018
188#define RST_CTRL_REG 0x0000001c
189 __be32 __iomem *reg;
190
191 // map reset register space
192 reg = ioremap(get_immrbase() + 0x900, 0xff);
193
194 local_irq_disable();
195
196 /* enable software reset "RSTE" */
197 out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
198
199 /* set software hard reset */
200 out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445);
201 for(;;);
202}
203
204static long __init
205mpc83xx_time_init(void)
206{
207#define SPCR_OFFSET 0x00000110
208#define SPCR_TBEN 0x00400000
209 __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
210 __be32 tmp;
211
212 tmp = in_be32(spcr);
213 out_be32(spcr, tmp|SPCR_TBEN);
214
215 iounmap(spcr);
216
217 return 0;
218}
219void __init
220platform_init(void)
221{ 162{
222 /* setup the PowerPC module struct */ 163 /* setup the PowerPC module struct */
223 ppc_md.setup_arch = mpc834x_sys_setup_arch; 164 ppc_md.setup_arch = mpc834x_sys_setup_arch;
@@ -239,5 +180,3 @@ platform_init(void)
239 180
240 return; 181 return;
241} 182}
242
243
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.h b/arch/powerpc/platforms/83xx/mpc834x_sys.h
index e4ca39f6a862..fedecb73f7ff 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.h
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.h
@@ -20,4 +20,4 @@
20#define PIRQC MPC83xx_IRQ_EXT6 20#define PIRQC MPC83xx_IRQ_EXT6
21#define PIRQD MPC83xx_IRQ_EXT7 21#define PIRQD MPC83xx_IRQ_EXT7
22 22
23#endif /* __MACH_MPC83XX_SYS_H__ */ 23#endif /* __MACH_MPC83XX_SYS_H__ */
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index ce9e66abef24..01cae106912b 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -10,5 +10,8 @@
10 */ 10 */
11 11
12extern int add_bridge(struct device_node *dev); 12extern int add_bridge(struct device_node *dev);
13extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
14extern void mpc83xx_restart(char *cmd);
15extern long mpc83xx_time_init(void);
13 16
14#endif /* __MPC83XX_H__ */ 17#endif /* __MPC83XX_H__ */
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 469cdacc5bd4..16f7d3b30e1d 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -36,7 +36,16 @@
36 36
37int mpc83xx_pci2_busno; 37int mpc83xx_pci2_busno;
38 38
39#ifdef CONFIG_PCI 39int mpc83xx_exclude_device(u_char bus, u_char devfn)
40{
41 if (bus == 0 && PCI_SLOT(devfn) == 0)
42 return PCIBIOS_DEVICE_NOT_FOUND;
43 if (mpc83xx_pci2_busno)
44 if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
45 return PCIBIOS_DEVICE_NOT_FOUND;
46 return PCIBIOS_SUCCESSFUL;
47}
48
40int __init add_bridge(struct device_node *dev) 49int __init add_bridge(struct device_node *dev)
41{ 50{
42 int len; 51 int len;
@@ -52,7 +61,7 @@ int __init add_bridge(struct device_node *dev)
52 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 61 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
53 62
54 /* Get bus range if any */ 63 /* Get bus range if any */
55 bus_range = (int *) get_property(dev, "bus-range", &len); 64 bus_range = (int *)get_property(dev, "bus-range", &len);
56 if (bus_range == NULL || len < 2 * sizeof(int)) { 65 if (bus_range == NULL || len < 2 * sizeof(int)) {
57 printk(KERN_WARNING "Can't get bus-range for %s, assume" 66 printk(KERN_WARNING "Can't get bus-range for %s, assume"
58 " bus 0\n", dev->full_name); 67 " bus 0\n", dev->full_name);
@@ -74,7 +83,7 @@ int __init add_bridge(struct device_node *dev)
74 if ((rsrc.start & 0xfffff) == 0x8500) { 83 if ((rsrc.start & 0xfffff) == 0x8500) {
75 setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304); 84 setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304);
76 } 85 }
77 /* PCI 2*/ 86 /* PCI 2 */
78 if ((rsrc.start & 0xfffff) == 0x8600) { 87 if ((rsrc.start & 0xfffff) == 0x8600) {
79 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); 88 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384);
80 primary = 0; 89 primary = 0;
@@ -84,10 +93,10 @@ int __init add_bridge(struct device_node *dev)
84 93
85 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " 94 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. "
86 "Firmware bus number: %d->%d\n", 95 "Firmware bus number: %d->%d\n",
87 rsrc.start, hose->first_busno, hose->last_busno); 96 rsrc.start, hose->first_busno, hose->last_busno);
88 97
89 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", 98 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
90 hose, hose->cfg_addr, hose->cfg_data); 99 hose, hose->cfg_addr, hose->cfg_data);
91 100
92 /* Interpret the "ranges" property */ 101 /* Interpret the "ranges" property */
93 /* This also maps the I/O region and sets isa_io/mem_base */ 102 /* This also maps the I/O region and sets isa_io/mem_base */
@@ -95,5 +104,3 @@ int __init add_bridge(struct device_node *dev)
95 104
96 return 0; 105 return 0;
97} 106}
98
99#endif
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c5bc2821d991..06e371282f57 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -1,86 +1,31 @@
1config 85xx 1menu "Platform support"
2 bool 2 depends on PPC_85xx
3 depends on E500
4 default y
5
6config PPC_INDIRECT_PCI_BE
7 bool
8 depends on 85xx
9 default y
10
11menu "Freescale 85xx options"
12 depends on E500
13 3
14choice 4choice
15 prompt "Machine Type" 5 prompt "Machine Type"
16 depends on 85xx
17 default MPC8540_ADS 6 default MPC8540_ADS
18 7
19config MPC8540_ADS 8config MPC8540_ADS
20 bool "Freescale MPC8540 ADS" 9 bool "Freescale MPC8540 ADS"
10 select DEFAULT_UIMAGE
21 help 11 help
22 This option enables support for the MPC 8540 ADS evaluation board. 12 This option enables support for the MPC 8540 ADS board
23
24config MPC8548_CDS
25 bool "Freescale MPC8548 CDS"
26 help
27 This option enablese support for the MPC8548 CDS evaluation board.
28
29config MPC8555_CDS
30 bool "Freescale MPC8555 CDS"
31 help
32 This option enablese support for the MPC8555 CDS evaluation board.
33
34config MPC8560_ADS
35 bool "Freescale MPC8560 ADS"
36 help
37 This option enables support for the MPC 8560 ADS evaluation board.
38
39config SBC8560
40 bool "WindRiver PowerQUICC III SBC8560"
41 help
42 This option enables support for the WindRiver PowerQUICC III
43 SBC8560 board.
44
45config STX_GP3
46 bool "Silicon Turnkey Express GP3"
47 help
48 This option enables support for the Silicon Turnkey Express GP3
49 board.
50 13
51endchoice 14endchoice
52 15
53# It's often necessary to know the specific 85xx processor type.
54# Fortunately, it is implied (so far) from the board type, so we
55# don't need to ask more redundant questions.
56config MPC8540 16config MPC8540
57 bool 17 bool
58 depends on MPC8540_ADS 18 select PPC_UDBG_16550
59 default y 19 select PPC_INDIRECT_PCI
60 20 default y if MPC8540_ADS
61config MPC8548
62 bool
63 depends on MPC8548_CDS
64 default y
65 21
66config MPC8555 22config PPC_INDIRECT_PCI_BE
67 bool
68 depends on MPC8555_CDS
69 default y
70
71config MPC8560
72 bool 23 bool
73 depends on SBC8560 || MPC8560_ADS || STX_GP3 24 depends on PPC_85xx
74 default y
75
76config 85xx_PCI2
77 bool "Supprt for 2nd PCI host controller"
78 depends on MPC8555_CDS
79 default y 25 default y
80 26
81config PPC_GEN550 27config MPIC
82 bool 28 bool
83 depends on MPC8540 || SBC8560 || MPC8555
84 default y 29 default y
85 30
86endmenu 31endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 6407197ffd89..ffc4139cb214 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -1 +1,5 @@
1# empty makefile so make clean works 1#
2# Makefile for the PowerPC 85xx linux kernel.
3#
4obj-$(CONFIG_PPC_85xx) += misc.o pci.o
5obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c
new file mode 100644
index 000000000000..26c5e822c7c8
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/misc.c
@@ -0,0 +1,31 @@
1/*
2 * MPC85xx generic code.
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * Copyright 2005 Freescale Semiconductor Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/irq.h>
14#include <linux/module.h>
15#include <asm/irq.h>
16
17extern void abort(void);
18
19void mpc85xx_restart(char *cmd)
20{
21 local_irq_disable();
22 abort();
23}
24
25/* For now this is a pass through */
26phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
27{
28 return addr;
29};
30
31EXPORT_SYMBOL(fixup_bigphys_addr);
diff --git a/arch/powerpc/platforms/85xx/mpc8540_ads.h b/arch/powerpc/platforms/85xx/mpc8540_ads.h
new file mode 100644
index 000000000000..f770cadb2080
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc8540_ads.h
@@ -0,0 +1,36 @@
1/*
2 * arch/ppc/platforms/85xx/mpc8540_ads.h
3 *
4 * MPC8540ADS board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC8540ADS_H__
18#define __MACH_MPC8540ADS_H__
19
20#include <linux/config.h>
21#include <linux/initrd.h>
22
23#define BOARD_CCSRBAR ((uint)0xe0000000)
24#define BCSR_ADDR ((uint)0xf8000000)
25#define BCSR_SIZE ((uint)(32 * 1024))
26
27/* PCI interrupt controller */
28#define PIRQA MPC85xx_IRQ_EXT1
29#define PIRQB MPC85xx_IRQ_EXT2
30#define PIRQC MPC85xx_IRQ_EXT3
31#define PIRQD MPC85xx_IRQ_EXT4
32
33/* Offset of CPM register space */
34#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
35
36#endif /* __MACH_MPC8540ADS_H__ */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h
new file mode 100644
index 000000000000..b44db6268f3d
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx.h
@@ -0,0 +1,18 @@
1/*
2 * arch/ppc/platforms/85xx/mpc85xx.h
3 *
4 * MPC85xx soc definitions/function decls
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2005 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17extern void mpc85xx_restart(char *);
18extern int add_bridge(struct device_node *dev);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
new file mode 100644
index 000000000000..b7821dbae00d
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -0,0 +1,244 @@
1/*
2 * MPC85xx setup and early boot code plus other random bits.
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * Copyright 2005 Freescale Semiconductor Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/kdev_t.h>
19#include <linux/delay.h>
20#include <linux/seq_file.h>
21#include <linux/root_dev.h>
22
23#include <asm/system.h>
24#include <asm/time.h>
25#include <asm/machdep.h>
26#include <asm/pci-bridge.h>
27#include <asm/mpc85xx.h>
28#include <asm/prom.h>
29#include <asm/mpic.h>
30#include <mm/mmu_decl.h>
31#include <asm/udbg.h>
32
33#include <sysdev/fsl_soc.h>
34#include "mpc85xx.h"
35
36#ifndef CONFIG_PCI
37unsigned long isa_io_base = 0;
38unsigned long isa_mem_base = 0;
39#endif
40
41/*
42 * Internal interrupts are all Level Sensitive, and Positive Polarity
43 *
44 * Note: Likely, this table and the following function should be
45 * obtained and derived from the OF Device Tree.
46 */
47static u_char mpc85xx_ads_openpic_initsenses[] __initdata = {
48 MPC85XX_INTERNAL_IRQ_SENSES,
49 0x0, /* External 0: */
50#if defined(CONFIG_PCI)
51 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 0 */
52 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 1 */
53 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 2 */
54 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 4: PCI slot 3 */
55#else
56 0x0, /* External 1: */
57 0x0, /* External 2: */
58 0x0, /* External 3: */
59 0x0, /* External 4: */
60#endif
61 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
62 0x0, /* External 6: */
63 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */
64 0x0, /* External 8: */
65 0x0, /* External 9: */
66 0x0, /* External 10: */
67 0x0, /* External 11: */
68};
69
70#ifdef CONFIG_PCI
71/*
72 * interrupt routing
73 */
74
75int
76mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
77{
78 static char pci_irq_table[][4] =
79 /*
80 * This is little evil, but works around the fact
81 * that revA boards have IDSEL starting at 18
82 * and others boards (older) start at 12
83 *
84 * PCI IDSEL/INTPIN->INTLINE
85 * A B C D
86 */
87 {
88 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */
89 {PIRQD, PIRQA, PIRQB, PIRQC},
90 {PIRQC, PIRQD, PIRQA, PIRQB},
91 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */
92 {0, 0, 0, 0}, /* -- */
93 {0, 0, 0, 0}, /* -- */
94 {0, 0, 0, 0}, /* -- */
95 {0, 0, 0, 0}, /* -- */
96 {0, 0, 0, 0}, /* -- */
97 {0, 0, 0, 0}, /* -- */
98 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */
99 {PIRQD, PIRQA, PIRQB, PIRQC},
100 {PIRQC, PIRQD, PIRQA, PIRQB},
101 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */
102 {0, 0, 0, 0}, /* -- */
103 {0, 0, 0, 0}, /* -- */
104 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */
105 {PIRQD, PIRQA, PIRQB, PIRQC},
106 {PIRQC, PIRQD, PIRQA, PIRQB},
107 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */
108 };
109
110 const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4;
111 return PCI_IRQ_TABLE_LOOKUP;
112}
113
114int
115mpc85xx_exclude_device(u_char bus, u_char devfn)
116{
117 if (bus == 0 && PCI_SLOT(devfn) == 0)
118 return PCIBIOS_DEVICE_NOT_FOUND;
119 else
120 return PCIBIOS_SUCCESSFUL;
121}
122
123#endif /* CONFIG_PCI */
124
125
126void __init mpc85xx_ads_pic_init(void)
127{
128 struct mpic *mpic1;
129 phys_addr_t OpenPIC_PAddr;
130
131 /* Determine the Physical Address of the OpenPIC regs */
132 OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
133
134 mpic1 = mpic_alloc(OpenPIC_PAddr,
135 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
136 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
137 mpc85xx_ads_openpic_initsenses,
138 sizeof(mpc85xx_ads_openpic_initsenses),
139 " OpenPIC ");
140 BUG_ON(mpic1 == NULL);
141 mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
142 mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
143 mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
144 mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
145 mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
146 mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
147 mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
148 mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
149
150 /* dummy mappings to get to 48 */
151 mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
152 mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
153 mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
154 mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
155
156 /* External ints */
157 mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
158 mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
159 mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
160 mpic_init(mpic1);
161}
162
163/*
164 * Setup the architecture
165 */
166static void __init mpc85xx_ads_setup_arch(void)
167{
168 struct device_node *cpu;
169 struct device_node *np;
170
171 if (ppc_md.progress)
172 ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
173
174 cpu = of_find_node_by_type(NULL, "cpu");
175 if (cpu != 0) {
176 unsigned int *fp;
177
178 fp = (int *)get_property(cpu, "clock-frequency", NULL);
179 if (fp != 0)
180 loops_per_jiffy = *fp / HZ;
181 else
182 loops_per_jiffy = 50000000 / HZ;
183 of_node_put(cpu);
184 }
185
186#ifdef CONFIG_PCI
187 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
188 add_bridge(np);
189
190 ppc_md.pci_swizzle = common_swizzle;
191 ppc_md.pci_map_irq = mpc85xx_map_irq;
192 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
193#endif
194
195#ifdef CONFIG_ROOT_NFS
196 ROOT_DEV = Root_NFS;
197#else
198 ROOT_DEV = Root_HDA1;
199#endif
200}
201
202void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
203{
204 uint pvid, svid, phid1;
205 uint memsize = total_memory;
206
207 pvid = mfspr(SPRN_PVR);
208 svid = mfspr(SPRN_SVR);
209
210 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
211 seq_printf(m, "Machine\t\t: mpc85xx\n");
212 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
213 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
214
215 /* Display cpu Pll setting */
216 phid1 = mfspr(SPRN_HID1);
217 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
218
219 /* Display the amount of memory */
220 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
221}
222
223void __init platform_init(void)
224{
225 ppc_md.setup_arch = mpc85xx_ads_setup_arch;
226 ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo;
227
228 ppc_md.init_IRQ = mpc85xx_ads_pic_init;
229 ppc_md.get_irq = mpic_get_irq;
230
231 ppc_md.restart = mpc85xx_restart;
232 ppc_md.power_off = NULL;
233 ppc_md.halt = NULL;
234
235 ppc_md.time_init = NULL;
236 ppc_md.set_rtc_time = NULL;
237 ppc_md.get_rtc_time = NULL;
238 ppc_md.calibrate_decr = generic_calibrate_decr;
239
240 ppc_md.progress = udbg_progress;
241
242 if (ppc_md.progress)
243 ppc_md.progress("mpc85xx_ads platform_init(): exit", 0);
244}
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
new file mode 100644
index 000000000000..bad290110ed1
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -0,0 +1,96 @@
1/*
2 * FSL SoC setup code
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/pci.h>
18#include <linux/delay.h>
19#include <linux/irq.h>
20#include <linux/module.h>
21
22#include <asm/system.h>
23#include <asm/atomic.h>
24#include <asm/io.h>
25#include <asm/pci-bridge.h>
26#include <asm/prom.h>
27#include <sysdev/fsl_soc.h>
28
29#undef DEBUG
30
31#ifdef DEBUG
32#define DBG(x...) printk(x)
33#else
34#define DBG(x...)
35#endif
36
37int mpc85xx_pci2_busno = 0;
38
39#ifdef CONFIG_PCI
40int __init add_bridge(struct device_node *dev)
41{
42 int len;
43 struct pci_controller *hose;
44 struct resource rsrc;
45 int *bus_range;
46 int primary = 1, has_address = 0;
47 phys_addr_t immr = get_immrbase();
48
49 DBG("Adding PCI host bridge %s\n", dev->full_name);
50
51 /* Fetch host bridge registers address */
52 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
53
54 /* Get bus range if any */
55 bus_range = (int *) get_property(dev, "bus-range", &len);
56 if (bus_range == NULL || len < 2 * sizeof(int)) {
57 printk(KERN_WARNING "Can't get bus-range for %s, assume"
58 " bus 0\n", dev->full_name);
59 }
60
61 hose = pcibios_alloc_controller();
62 if (!hose)
63 return -ENOMEM;
64 hose->arch_data = dev;
65 hose->set_cfg_type = 1;
66
67 hose->first_busno = bus_range ? bus_range[0] : 0;
68 hose->last_busno = bus_range ? bus_range[1] : 0xff;
69
70 /* PCI 1 */
71 if ((rsrc.start & 0xfffff) == 0x8000) {
72 setup_indirect_pci(hose, immr + 0x8000, immr + 0x8004);
73 }
74 /* PCI 2 */
75 if ((rsrc.start & 0xfffff) == 0x9000) {
76 setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004);
77 primary = 0;
78 hose->bus_offset = hose->first_busno;
79 mpc85xx_pci2_busno = hose->first_busno;
80 }
81
82 printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. "
83 "Firmware bus number: %d->%d\n",
84 rsrc.start, hose->first_busno, hose->last_busno);
85
86 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
87 hose, hose->cfg_addr, hose->cfg_data);
88
89 /* Interpret the "ranges" property */
90 /* This also maps the I/O region and sets isa_io/mem_base */
91 pci_process_bridge_OF_ranges(hose, dev, primary);
92
93 return 0;
94}
95
96#endif
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 04073fd987ec..c4f6b0d2d140 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -8,7 +8,7 @@ endif
8obj-$(CONFIG_PPC_CHRP) += chrp/ 8obj-$(CONFIG_PPC_CHRP) += chrp/
9obj-$(CONFIG_4xx) += 4xx/ 9obj-$(CONFIG_4xx) += 4xx/
10obj-$(CONFIG_PPC_83xx) += 83xx/ 10obj-$(CONFIG_PPC_83xx) += 83xx/
11obj-$(CONFIG_85xx) += 85xx/ 11obj-$(CONFIG_PPC_85xx) += 85xx/
12obj-$(CONFIG_PPC_PSERIES) += pseries/ 12obj-$(CONFIG_PPC_PSERIES) += pseries/
13obj-$(CONFIG_PPC_ISERIES) += iseries/ 13obj-$(CONFIG_PPC_ISERIES) += iseries/
14obj-$(CONFIG_PPC_MAPLE) += maple/ 14obj-$(CONFIG_PPC_MAPLE) += maple/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3157071e241c..c2a3db8edb0c 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -10,4 +10,9 @@ config SPU_FS
10 Units on machines implementing the Broadband Processor 10 Units on machines implementing the Broadband Processor
11 Architecture. 11 Architecture.
12 12
13config SPUFS_MMAP
14 bool
15 depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES
16 default y
17
13endmenu 18endmenu
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 3b998a393e3f..e570bad06394 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -6,5 +6,11 @@ obj-$(CONFIG_SPU_FS) += spu-base.o spufs/
6 6
7spu-base-y += spu_base.o spu_priv1.o 7spu-base-y += spu_base.o spu_priv1.o
8 8
9builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o 9# needed only when building loadable spufs.ko
10obj-y += $(builtin-spufs-m) 10spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
11obj-y += $(spufs-modular-m)
12
13# always needed in kernel
14spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o
15obj-y += $(spufs-builtin-y) $(spufs-builtin-m)
16
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 63aa52acf441..978be1c30c1b 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -63,7 +63,24 @@ static DEFINE_PER_CPU(struct iic, iic);
63 63
64void iic_local_enable(void) 64void iic_local_enable(void)
65{ 65{
66 out_be64(&__get_cpu_var(iic).regs->prio, 0xff); 66 struct iic *iic = &__get_cpu_var(iic);
67 u64 tmp;
68
69 /*
70 * There seems to be a bug that is present in DD2.x CPUs
71 * and still only partially fixed in DD3.1.
72 * This bug causes a value written to the priority register
73 * not to make it there, resulting in a system hang unless we
74 * write it again.
75 * Masking with 0xf0 is done because the Cell BE does not
76 * implement the lower four bits of the interrupt priority,
77 * they always read back as zeroes, although future CPUs
78 * might implement different bits.
79 */
80 do {
81 out_be64(&iic->regs->prio, 0xff);
82 tmp = in_be64(&iic->regs->prio);
83 } while ((tmp & 0xf0) != 0xf0);
67} 84}
68 85
69void iic_local_disable(void) 86void iic_local_disable(void)
@@ -123,7 +140,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending)
123 pending.class != 2) 140 pending.class != 2)
124 break; 141 break;
125 irq = IIC_EXT_OFFSET 142 irq = IIC_EXT_OFFSET
126 + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE) 143 + spider_get_irq(node)
127 + node * IIC_NODE_STRIDE; 144 + node * IIC_NODE_STRIDE;
128 break; 145 break;
129 case 0x01 ... 0x04: 146 case 0x01 ... 0x04:
@@ -174,38 +191,98 @@ int iic_get_irq(struct pt_regs *regs)
174 return irq; 191 return irq;
175} 192}
176 193
177static int setup_iic(int cpu, struct iic *iic) 194/* hardcoded part to be compatible with older firmware */
195
196static int setup_iic_hardcoded(void)
178{ 197{
179 struct device_node *np; 198 struct device_node *np;
180 int nodeid = cpu / 2; 199 int nodeid, cpu;
181 unsigned long regs; 200 unsigned long regs;
201 struct iic *iic;
182 202
183 for (np = of_find_node_by_type(NULL, "cpu"); 203 for_each_cpu(cpu) {
184 np; 204 iic = &per_cpu(iic, cpu);
185 np = of_find_node_by_type(np, "cpu")) { 205 nodeid = cpu/2;
186 if (nodeid == *(int *)get_property(np, "node-id", NULL)) 206
187 break; 207 for (np = of_find_node_by_type(NULL, "cpu");
208 np;
209 np = of_find_node_by_type(np, "cpu")) {
210 if (nodeid == *(int *)get_property(np, "node-id", NULL))
211 break;
212 }
213
214 if (!np) {
215 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
216 iic->regs = NULL;
217 iic->target_id = 0xff;
218 return -ENODEV;
219 }
220
221 regs = *(long *)get_property(np, "iic", NULL);
222
223 /* hack until we have decided on the devtree info */
224 regs += 0x400;
225 if (cpu & 1)
226 regs += 0x20;
227
228 printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs);
229 iic->regs = ioremap(regs, sizeof(struct iic_regs));
230 iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe);
188 } 231 }
189 232
190 if (!np) { 233 return 0;
191 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); 234}
192 iic->regs = NULL;
193 iic->target_id = 0xff;
194 return -ENODEV;
195 }
196 235
197 regs = *(long *)get_property(np, "iic", NULL); 236static int setup_iic(void)
237{
238 struct device_node *dn;
239 unsigned long *regs;
240 char *compatible;
241 unsigned *np, found = 0;
242 struct iic *iic = NULL;
243
244 for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
245 compatible = (char *)get_property(dn, "compatible", NULL);
246
247 if (!compatible) {
248 printk(KERN_WARNING "no compatible property found !\n");
249 continue;
250 }
198 251
199 /* hack until we have decided on the devtree info */ 252 if (strstr(compatible, "IBM,CBEA-Internal-Interrupt-Controller"))
200 regs += 0x400; 253 regs = (unsigned long *)get_property(dn,"reg", NULL);
201 if (cpu & 1) 254 else
202 regs += 0x20; 255 continue;
203 256
204 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); 257 if (!regs)
205 iic->regs = __ioremap(regs, sizeof(struct iic_regs), 258 printk(KERN_WARNING "IIC: no reg property\n");
206 _PAGE_NO_CACHE); 259
207 iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); 260 np = (unsigned int *)get_property(dn, "ibm,interrupt-server-ranges", NULL);
208 return 0; 261
262 if (!np) {
263 printk(KERN_WARNING "IIC: CPU association not found\n");
264 iic->regs = NULL;
265 iic->target_id = 0xff;
266 return -ENODEV;
267 }
268
269 iic = &per_cpu(iic, np[0]);
270 iic->regs = ioremap(regs[0], sizeof(struct iic_regs));
271 iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe);
272 printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs);
273
274 iic = &per_cpu(iic, np[1]);
275 iic->regs = ioremap(regs[2], sizeof(struct iic_regs));
276 iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe);
277 printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs);
278
279 found++;
280 }
281
282 if (found)
283 return 0;
284 else
285 return -ENODEV;
209} 286}
210 287
211#ifdef CONFIG_SMP 288#ifdef CONFIG_SMP
@@ -283,10 +360,12 @@ void iic_init_IRQ(void)
283 int cpu, irq_offset; 360 int cpu, irq_offset;
284 struct iic *iic; 361 struct iic *iic;
285 362
363 if (setup_iic() < 0)
364 setup_iic_hardcoded();
365
286 irq_offset = 0; 366 irq_offset = 0;
287 for_each_cpu(cpu) { 367 for_each_possible_cpu(cpu) {
288 iic = &per_cpu(iic, cpu); 368 iic = &per_cpu(iic, cpu);
289 setup_iic(cpu, iic);
290 if (iic->regs) 369 if (iic->regs)
291 out_be64(&iic->regs->prio, 0xff); 370 out_be64(&iic->regs->prio, 0xff);
292 } 371 }
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index a14bd38791c0..799f77d98f96 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -57,7 +57,7 @@ extern void iic_local_disable(void);
57extern u8 iic_get_target_id(int cpu); 57extern u8 iic_get_target_id(int cpu);
58 58
59extern void spider_init_IRQ(void); 59extern void spider_init_IRQ(void);
60extern int spider_get_irq(unsigned long int_pending); 60extern int spider_get_irq(int node);
61 61
62#endif 62#endif
63#endif /* ASM_CELL_PIC_H */ 63#endif /* ASM_CELL_PIC_H */
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 46e7cb9c3e64..a49ceb799a8e 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -289,7 +289,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
289 ioc_base = iommu->mapped_base; 289 ioc_base = iommu->mapped_base;
290 ioc_mmio_base = iommu->mapped_mmio_base; 290 ioc_mmio_base = iommu->mapped_mmio_base;
291 291
292 for (real_address = 0, io_address = 0; 292 for (real_address = 0, io_address = map_start;
293 io_address <= map_start + map_size; 293 io_address <= map_start + map_size;
294 real_address += io_page_size, io_address += io_page_size) { 294 real_address += io_page_size, io_address += io_page_size) {
295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size); 295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size);
@@ -302,7 +302,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
302 set_iopt_cache(ioc_mmio_base, 302 set_iopt_cache(ioc_mmio_base,
303 get_ioc_hash_1way(ioste, io_address), 303 get_ioc_hash_1way(ioste, io_address),
304 get_ioc_tag(ioste, io_address), 304 get_ioc_tag(ioste, io_address),
305 get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW)); 305 get_iopt_entry(real_address, ioid, IOPT_PROT_RW));
306 } 306 }
307} 307}
308 308
@@ -344,8 +344,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
344 344
345 /* node 0 */ 345 /* node 0 */
346 iommu = &cell_iommus[0]; 346 iommu = &cell_iommus[0];
347 iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE); 347 iommu->mapped_base = ioremap(0x20000511000, 0x1000);
348 iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE); 348 iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000);
349 349
350 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 350 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
351 351
@@ -357,8 +357,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
357 357
358 /* node 1 */ 358 /* node 1 */
359 iommu = &cell_iommus[1]; 359 iommu = &cell_iommus[1];
360 iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE); 360 iommu->mapped_base = ioremap(0x30000511000, 0x1000);
361 iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE); 361 iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000);
362 362
363 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 363 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
364 364
@@ -407,8 +407,8 @@ static int cell_map_iommu(void)
407 iommu->base = *base; 407 iommu->base = *base;
408 iommu->mmio_base = *mmio_base; 408 iommu->mmio_base = *mmio_base;
409 409
410 iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE); 410 iommu->mapped_base = ioremap(*base, 0x1000);
411 iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE); 411 iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000);
412 412
413 enable_mapping(iommu->mapped_base, 413 enable_mapping(iommu->mapped_base,
414 iommu->mapped_mmio_base); 414 iommu->mapped_mmio_base);
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index e0e051c675dd..7eed8c624517 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -203,7 +203,7 @@ found:
203 203
204 pr_debug("pervasive area for CPU %d at %lx, size %x\n", 204 pr_debug("pervasive area for CPU %d at %lx, size %x\n",
205 cpu, real_address, size); 205 cpu, real_address, size);
206 p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE); 206 p->regs = ioremap(real_address, size);
207 p->thread = thread; 207 p->thread = thread;
208 return 0; 208 return 0;
209} 209}
@@ -217,7 +217,7 @@ void __init cell_pervasive_init(void)
217 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) 217 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
218 return; 218 return;
219 219
220 for_each_cpu(cpu) { 220 for_each_possible_cpu(cpu) {
221 p = &cbe_pervasive[cpu]; 221 p = &cbe_pervasive[cpu];
222 ret = cbe_find_pmd_mmio(cpu, p); 222 ret = cbe_find_pmd_mmio(cpu, p);
223 if (ret) 223 if (ret)
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index b33a4443f5a9..dac5d0365fde 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -115,7 +115,7 @@ static void __init cell_spuprop_present(struct device_node *spe,
115 for (pfn = start_pfn; pfn < end_pfn; pfn++) { 115 for (pfn = start_pfn; pfn < end_pfn; pfn++) {
116 struct page *page = pfn_to_page(pfn); 116 struct page *page = pfn_to_page(pfn);
117 set_page_links(page, ZONE_DMA, node_id, pfn); 117 set_page_links(page, ZONE_DMA, node_id, pfn);
118 set_page_count(page, 1); 118 init_page_count(page);
119 reset_page_mapcount(page); 119 reset_page_mapcount(page);
120 SetPageReserved(page); 120 SetPageReserved(page);
121 INIT_LIST_HEAD(&page->lru); 121 INIT_LIST_HEAD(&page->lru);
@@ -195,9 +195,13 @@ static void __init cell_init_early(void)
195} 195}
196 196
197 197
198static int __init cell_probe(int platform) 198static int __init cell_probe(void)
199{ 199{
200 if (platform != PLATFORM_CELL) 200 /* XXX This is temporary, the Cell maintainer will come up with
201 * more appropriate detection logic
202 */
203 unsigned long root = of_get_flat_dt_root();
204 if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
201 return 0; 205 return 0;
202 206
203 return 1; 207 return 1;
@@ -212,7 +216,8 @@ static int cell_check_legacy_ioport(unsigned int baseport)
212 return -ENODEV; 216 return -ENODEV;
213} 217}
214 218
215struct machdep_calls __initdata cell_md = { 219define_machine(cell) {
220 .name = "Cell",
216 .probe = cell_probe, 221 .probe = cell_probe,
217 .setup_arch = cell_setup_arch, 222 .setup_arch = cell_setup_arch,
218 .init_early = cell_init_early, 223 .init_early = cell_init_early,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index e74132188bdf..55cbdd77a62d 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -84,10 +84,11 @@ static void __iomem *spider_get_irq_config(int irq)
84 84
85static void spider_enable_irq(unsigned int irq) 85static void spider_enable_irq(unsigned int irq)
86{ 86{
87 int nodeid = (irq / IIC_NODE_STRIDE) * 0x10;
87 void __iomem *cfg = spider_get_irq_config(irq); 88 void __iomem *cfg = spider_get_irq_config(irq);
88 irq = spider_get_nr(irq); 89 irq = spider_get_nr(irq);
89 90
90 out_be32(cfg, in_be32(cfg) | 0x3107000eu); 91 out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid);
91 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); 92 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
92} 93}
93 94
@@ -131,61 +132,108 @@ static struct hw_interrupt_type spider_pic = {
131 .end = spider_end_irq, 132 .end = spider_end_irq,
132}; 133};
133 134
134 135int spider_get_irq(int node)
135int spider_get_irq(unsigned long int_pending)
136{ 136{
137 void __iomem *regs = spider_get_pic(int_pending);
138 unsigned long cs; 137 unsigned long cs;
139 int irq; 138 void __iomem *regs = spider_pics[node];
140
141 cs = in_be32(regs + TIR_CS);
142 139
143 irq = cs >> 24; 140 cs = in_be32(regs + TIR_CS) >> 24;
144 if (irq != 63)
145 return irq;
146 141
147 return -1; 142 if (cs == 63)
143 return -1;
144 else
145 return cs;
148} 146}
149 147
150void spider_init_IRQ(void) 148/* hardcoded part to be compatible with older firmware */
149
150void spider_init_IRQ_hardcoded(void)
151{ 151{
152 int node; 152 int node;
153 struct device_node *dn;
154 unsigned int *property;
155 long spiderpic; 153 long spiderpic;
154 long pics[] = { 0x24000008000, 0x34000008000 };
156 int n; 155 int n;
157 156
158/* FIXME: detect multiple PICs as soon as the device tree has them */ 157 pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__);
159 for (node = 0; node < 1; node++) {
160 dn = of_find_node_by_path("/");
161 n = prom_n_addr_cells(dn);
162 property = (unsigned int *) get_property(dn,
163 "platform-spider-pic", NULL);
164 158
165 if (!property) 159 for (node = 0; node < num_present_cpus()/2; node++) {
166 continue; 160 spiderpic = pics[node];
167 for (spiderpic = 0; n > 0; --n)
168 spiderpic = (spiderpic << 32) + *property++;
169 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); 161 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
170 spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE); 162 spider_pics[node] = ioremap(spiderpic, 0x800);
171 for (n = 0; n < IIC_NUM_EXT; n++) { 163 for (n = 0; n < IIC_NUM_EXT; n++) {
172 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; 164 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
173 get_irq_desc(irq)->handler = &spider_pic; 165 get_irq_desc(irq)->handler = &spider_pic;
166 }
174 167
175 /* do not mask any interrupts because of level */ 168 /* do not mask any interrupts because of level */
176 out_be32(spider_pics[node] + TIR_MSK, 0x0); 169 out_be32(spider_pics[node] + TIR_MSK, 0x0);
177 170
178 /* disable edge detection clear */ 171 /* disable edge detection clear */
179 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ 172 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
180 173
181 /* enable interrupt packets to be output */ 174 /* enable interrupt packets to be output */
182 out_be32(spider_pics[node] + TIR_PIEN, 175 out_be32(spider_pics[node] + TIR_PIEN,
183 in_be32(spider_pics[node] + TIR_PIEN) | 0x1); 176 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
184 177
185 /* Enable the interrupt detection enable bit. Do this last! */ 178 /* Enable the interrupt detection enable bit. Do this last! */
186 out_be32(spider_pics[node] + TIR_DEN, 179 out_be32(spider_pics[node] + TIR_DEN,
187 in_be32(spider_pics[node] +TIR_DEN) | 0x1); 180 in_be32(spider_pics[node] + TIR_DEN) | 0x1);
181 }
182}
183
184void spider_init_IRQ(void)
185{
186 long spider_reg;
187 struct device_node *dn;
188 char *compatible;
189 int n, node = 0;
190
191 for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
192 compatible = (char *)get_property(dn, "compatible", NULL);
188 193
194 if (!compatible)
195 continue;
196
197 if (strstr(compatible, "CBEA,platform-spider-pic"))
198 spider_reg = *(long *)get_property(dn,"reg", NULL);
199 else if (strstr(compatible, "sti,platform-spider-pic")) {
200 spider_init_IRQ_hardcoded();
201 return;
202 } else
203 continue;
204
205 if (!spider_reg)
206 printk("interrupt controller does not have reg property !\n");
207
208 n = prom_n_addr_cells(dn);
209
210 if ( n != 2)
211 printk("reg property with invalid number of elements \n");
212
213 spider_pics[node] = ioremap(spider_reg, 0x800);
214
215 printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n",
216 spider_reg, n, spider_pics[node]);
217
218 for (n = 0; n < IIC_NUM_EXT; n++) {
219 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
220 get_irq_desc(irq)->handler = &spider_pic;
189 } 221 }
222
223 /* do not mask any interrupts because of level */
224 out_be32(spider_pics[node] + TIR_MSK, 0x0);
225
226 /* disable edge detection clear */
227 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
228
229 /* enable interrupt packets to be output */
230 out_be32(spider_pics[node] + TIR_PIEN,
231 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
232
233 /* Enable the interrupt detection enable bit. Do this last! */
234 out_be32(spider_pics[node] + TIR_DEN,
235 in_be32(spider_pics[node] + TIR_DEN) | 0x1);
236
237 node++;
190 } 238 }
191} 239}
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index d75ae03df686..269dda4fd0b4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -32,7 +32,7 @@
32 32
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/semaphore.h> 35#include <linux/mutex.h>
36#include <asm/spu.h> 36#include <asm/spu.h>
37#include <asm/mmu_context.h> 37#include <asm/mmu_context.h>
38 38
@@ -111,7 +111,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
111extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX 111extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
112static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) 112static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
113{ 113{
114 pr_debug("%s\n", __FUNCTION__); 114 pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea);
115 115
116 /* Handle kernel space hash faults immediately. 116 /* Handle kernel space hash faults immediately.
117 User hash faults need to be deferred to process context. */ 117 User hash faults need to be deferred to process context. */
@@ -168,7 +168,7 @@ static int __spu_trap_halt(struct spu *spu)
168static int __spu_trap_tag_group(struct spu *spu) 168static int __spu_trap_tag_group(struct spu *spu)
169{ 169{
170 pr_debug("%s\n", __FUNCTION__); 170 pr_debug("%s\n", __FUNCTION__);
171 /* wake_up(&spu->dma_wq); */ 171 spu->mfc_callback(spu);
172 return 0; 172 return 0;
173} 173}
174 174
@@ -242,6 +242,8 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
242 spu_mfc_dsisr_set(spu, 0ul); 242 spu_mfc_dsisr_set(spu, 0ul);
243 spu_int_stat_clear(spu, 1, stat); 243 spu_int_stat_clear(spu, 1, stat);
244 spin_unlock(&spu->register_lock); 244 spin_unlock(&spu->register_lock);
245 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
246 dar, dsisr);
245 247
246 if (stat & 1) /* segment fault */ 248 if (stat & 1) /* segment fault */
247 __spu_trap_data_seg(spu, dar); 249 __spu_trap_data_seg(spu, dar);
@@ -342,7 +344,7 @@ spu_free_irqs(struct spu *spu)
342} 344}
343 345
344static LIST_HEAD(spu_list); 346static LIST_HEAD(spu_list);
345static DECLARE_MUTEX(spu_mutex); 347static DEFINE_MUTEX(spu_mutex);
346 348
347static void spu_init_channels(struct spu *spu) 349static void spu_init_channels(struct spu *spu)
348{ 350{
@@ -382,7 +384,7 @@ struct spu *spu_alloc(void)
382{ 384{
383 struct spu *spu; 385 struct spu *spu;
384 386
385 down(&spu_mutex); 387 mutex_lock(&spu_mutex);
386 if (!list_empty(&spu_list)) { 388 if (!list_empty(&spu_list)) {
387 spu = list_entry(spu_list.next, struct spu, list); 389 spu = list_entry(spu_list.next, struct spu, list);
388 list_del_init(&spu->list); 390 list_del_init(&spu->list);
@@ -391,7 +393,7 @@ struct spu *spu_alloc(void)
391 pr_debug("No SPU left\n"); 393 pr_debug("No SPU left\n");
392 spu = NULL; 394 spu = NULL;
393 } 395 }
394 up(&spu_mutex); 396 mutex_unlock(&spu_mutex);
395 397
396 if (spu) 398 if (spu)
397 spu_init_channels(spu); 399 spu_init_channels(spu);
@@ -402,9 +404,9 @@ EXPORT_SYMBOL_GPL(spu_alloc);
402 404
403void spu_free(struct spu *spu) 405void spu_free(struct spu *spu)
404{ 406{
405 down(&spu_mutex); 407 mutex_lock(&spu_mutex);
406 list_add_tail(&spu->list, &spu_list); 408 list_add_tail(&spu->list, &spu_list);
407 up(&spu_mutex); 409 mutex_unlock(&spu_mutex);
408} 410}
409EXPORT_SYMBOL_GPL(spu_free); 411EXPORT_SYMBOL_GPL(spu_free);
410 412
@@ -484,14 +486,13 @@ int spu_irq_class_1_bottom(struct spu *spu)
484 486
485 ea = spu->dar; 487 ea = spu->dar;
486 dsisr = spu->dsisr; 488 dsisr = spu->dsisr;
487 if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { 489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
488 access = (_PAGE_PRESENT | _PAGE_USER); 490 access = (_PAGE_PRESENT | _PAGE_USER);
489 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; 491 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
490 if (hash_page(ea, access, 0x300) != 0) 492 if (hash_page(ea, access, 0x300) != 0)
491 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 493 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
492 } 494 }
493 if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || 495 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
494 (dsisr & MFC_DSISR_ACCESS_DENIED)) {
495 if ((ret = spu_handle_mm_fault(spu)) != 0) 496 if ((ret = spu_handle_mm_fault(spu)) != 0)
496 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 497 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
497 else 498 else
@@ -568,6 +569,11 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe)
568 if (!spu->local_store) 569 if (!spu->local_store)
569 goto out; 570 goto out;
570 571
572 prop = get_property(spe, "problem", NULL);
573 if (!prop)
574 goto out_unmap;
575 spu->problem_phys = *(unsigned long *)prop;
576
571 spu->problem= map_spe_prop(spe, "problem"); 577 spu->problem= map_spe_prop(spe, "problem");
572 if (!spu->problem) 578 if (!spu->problem)
573 goto out_unmap; 579 goto out_unmap;
@@ -632,15 +638,16 @@ static int __init create_spu(struct device_node *spe)
632 spu->ibox_callback = NULL; 638 spu->ibox_callback = NULL;
633 spu->wbox_callback = NULL; 639 spu->wbox_callback = NULL;
634 spu->stop_callback = NULL; 640 spu->stop_callback = NULL;
641 spu->mfc_callback = NULL;
635 642
636 down(&spu_mutex); 643 mutex_lock(&spu_mutex);
637 spu->number = number++; 644 spu->number = number++;
638 ret = spu_request_irqs(spu); 645 ret = spu_request_irqs(spu);
639 if (ret) 646 if (ret)
640 goto out_unmap; 647 goto out_unmap;
641 648
642 list_add(&spu->list, &spu_list); 649 list_add(&spu->list, &spu_list);
643 up(&spu_mutex); 650 mutex_unlock(&spu_mutex);
644 651
645 pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", 652 pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
646 spu->name, spu->isrc, spu->local_store, 653 spu->name, spu->isrc, spu->local_store,
@@ -648,7 +655,7 @@ static int __init create_spu(struct device_node *spe)
648 goto out; 655 goto out;
649 656
650out_unmap: 657out_unmap:
651 up(&spu_mutex); 658 mutex_unlock(&spu_mutex);
652 spu_unmap(spu); 659 spu_unmap(spu);
653out_free: 660out_free:
654 kfree(spu); 661 kfree(spu);
@@ -668,10 +675,10 @@ static void destroy_spu(struct spu *spu)
668static void cleanup_spu_base(void) 675static void cleanup_spu_base(void)
669{ 676{
670 struct spu *spu, *tmp; 677 struct spu *spu, *tmp;
671 down(&spu_mutex); 678 mutex_lock(&spu_mutex);
672 list_for_each_entry_safe(spu, tmp, &spu_list, list) 679 list_for_each_entry_safe(spu, tmp, &spu_list, list)
673 destroy_spu(spu); 680 destroy_spu(spu);
674 up(&spu_mutex); 681 mutex_unlock(&spu_mutex);
675} 682}
676module_exit(cleanup_spu_base); 683module_exit(cleanup_spu_base);
677 684
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
new file mode 100644
index 000000000000..3a4245c926ad
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -0,0 +1,345 @@
1/*
2 * System call callback functions for SPUs
3 */
4
5#define DEBUG
6
7#include <linux/kallsyms.h>
8#include <linux/module.h>
9#include <linux/syscalls.h>
10
11#include <asm/spu.h>
12#include <asm/syscalls.h>
13#include <asm/unistd.h>
14
15/*
16 * This table defines the system calls that an SPU can call.
17 * It is currently a subset of the 64 bit powerpc system calls,
18 * with the exact semantics.
19 *
20 * The reasons for disabling some of the system calls are:
21 * 1. They interact with the way SPU syscalls are handled
22 * and we can't let them execute ever:
23 * restart_syscall, exit, for, execve, ptrace, ...
24 * 2. They are deprecated and replaced by other means:
25 * uselib, pciconfig_*, sysfs, ...
26 * 3. They are somewhat interacting with the system in a way
27 * we don't want an SPU to:
28 * reboot, init_module, mount, kexec_load
29 * 4. They are optional and we can't rely on them being
30 * linked into the kernel. Unfortunately, the cond_syscall
31 * helper does not work here as it does not add the necessary
32 * opd symbols:
33 * mbind, mq_open, ipc, ...
34 */
35
36void *spu_syscall_table[] = {
37 [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */
38 [__NR_exit] sys_ni_syscall, /* sys_exit */
39 [__NR_fork] sys_ni_syscall, /* ppc_fork */
40 [__NR_read] sys_read,
41 [__NR_write] sys_write,
42 [__NR_open] sys_open,
43 [__NR_close] sys_close,
44 [__NR_waitpid] sys_waitpid,
45 [__NR_creat] sys_creat,
46 [__NR_link] sys_link,
47 [__NR_unlink] sys_unlink,
48 [__NR_execve] sys_ni_syscall, /* sys_execve */
49 [__NR_chdir] sys_chdir,
50 [__NR_time] sys_time,
51 [__NR_mknod] sys_mknod,
52 [__NR_chmod] sys_chmod,
53 [__NR_lchown] sys_lchown,
54 [__NR_break] sys_ni_syscall,
55 [__NR_oldstat] sys_ni_syscall,
56 [__NR_lseek] sys_lseek,
57 [__NR_getpid] sys_getpid,
58 [__NR_mount] sys_ni_syscall, /* sys_mount */
59 [__NR_umount] sys_ni_syscall,
60 [__NR_setuid] sys_setuid,
61 [__NR_getuid] sys_getuid,
62 [__NR_stime] sys_stime,
63 [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */
64 [__NR_alarm] sys_alarm,
65 [__NR_oldfstat] sys_ni_syscall,
66 [__NR_pause] sys_ni_syscall, /* sys_pause */
67 [__NR_utime] sys_ni_syscall, /* sys_utime */
68 [__NR_stty] sys_ni_syscall,
69 [__NR_gtty] sys_ni_syscall,
70 [__NR_access] sys_access,
71 [__NR_nice] sys_nice,
72 [__NR_ftime] sys_ni_syscall,
73 [__NR_sync] sys_sync,
74 [__NR_kill] sys_kill,
75 [__NR_rename] sys_rename,
76 [__NR_mkdir] sys_mkdir,
77 [__NR_rmdir] sys_rmdir,
78 [__NR_dup] sys_dup,
79 [__NR_pipe] sys_pipe,
80 [__NR_times] sys_times,
81 [__NR_prof] sys_ni_syscall,
82 [__NR_brk] sys_brk,
83 [__NR_setgid] sys_setgid,
84 [__NR_getgid] sys_getgid,
85 [__NR_signal] sys_ni_syscall, /* sys_signal */
86 [__NR_geteuid] sys_geteuid,
87 [__NR_getegid] sys_getegid,
88 [__NR_acct] sys_ni_syscall, /* sys_acct */
89 [__NR_umount2] sys_ni_syscall, /* sys_umount */
90 [__NR_lock] sys_ni_syscall,
91 [__NR_ioctl] sys_ioctl,
92 [__NR_fcntl] sys_fcntl,
93 [__NR_mpx] sys_ni_syscall,
94 [__NR_setpgid] sys_setpgid,
95 [__NR_ulimit] sys_ni_syscall,
96 [__NR_oldolduname] sys_ni_syscall,
97 [__NR_umask] sys_umask,
98 [__NR_chroot] sys_chroot,
99 [__NR_ustat] sys_ni_syscall, /* sys_ustat */
100 [__NR_dup2] sys_dup2,
101 [__NR_getppid] sys_getppid,
102 [__NR_getpgrp] sys_getpgrp,
103 [__NR_setsid] sys_setsid,
104 [__NR_sigaction] sys_ni_syscall,
105 [__NR_sgetmask] sys_sgetmask,
106 [__NR_ssetmask] sys_ssetmask,
107 [__NR_setreuid] sys_setreuid,
108 [__NR_setregid] sys_setregid,
109 [__NR_sigsuspend] sys_ni_syscall,
110 [__NR_sigpending] sys_ni_syscall,
111 [__NR_sethostname] sys_sethostname,
112 [__NR_setrlimit] sys_setrlimit,
113 [__NR_getrlimit] sys_ni_syscall,
114 [__NR_getrusage] sys_getrusage,
115 [__NR_gettimeofday] sys_gettimeofday,
116 [__NR_settimeofday] sys_settimeofday,
117 [__NR_getgroups] sys_getgroups,
118 [__NR_setgroups] sys_setgroups,
119 [__NR_select] sys_ni_syscall,
120 [__NR_symlink] sys_symlink,
121 [__NR_oldlstat] sys_ni_syscall,
122 [__NR_readlink] sys_readlink,
123 [__NR_uselib] sys_ni_syscall, /* sys_uselib */
124 [__NR_swapon] sys_ni_syscall, /* sys_swapon */
125 [__NR_reboot] sys_ni_syscall, /* sys_reboot */
126 [__NR_readdir] sys_ni_syscall,
127 [__NR_mmap] sys_mmap,
128 [__NR_munmap] sys_munmap,
129 [__NR_truncate] sys_truncate,
130 [__NR_ftruncate] sys_ftruncate,
131 [__NR_fchmod] sys_fchmod,
132 [__NR_fchown] sys_fchown,
133 [__NR_getpriority] sys_getpriority,
134 [__NR_setpriority] sys_setpriority,
135 [__NR_profil] sys_ni_syscall,
136 [__NR_statfs] sys_ni_syscall, /* sys_statfs */
137 [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */
138 [__NR_ioperm] sys_ni_syscall,
139 [__NR_socketcall] sys_socketcall,
140 [__NR_syslog] sys_syslog,
141 [__NR_setitimer] sys_setitimer,
142 [__NR_getitimer] sys_getitimer,
143 [__NR_stat] sys_newstat,
144 [__NR_lstat] sys_newlstat,
145 [__NR_fstat] sys_newfstat,
146 [__NR_olduname] sys_ni_syscall,
147 [__NR_iopl] sys_ni_syscall,
148 [__NR_vhangup] sys_vhangup,
149 [__NR_idle] sys_ni_syscall,
150 [__NR_vm86] sys_ni_syscall,
151 [__NR_wait4] sys_wait4,
152 [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */
153 [__NR_sysinfo] sys_sysinfo,
154 [__NR_ipc] sys_ni_syscall, /* sys_ipc */
155 [__NR_fsync] sys_fsync,
156 [__NR_sigreturn] sys_ni_syscall,
157 [__NR_clone] sys_ni_syscall, /* ppc_clone */
158 [__NR_setdomainname] sys_setdomainname,
159 [__NR_uname] ppc_newuname,
160 [__NR_modify_ldt] sys_ni_syscall,
161 [__NR_adjtimex] sys_adjtimex,
162 [__NR_mprotect] sys_mprotect,
163 [__NR_sigprocmask] sys_ni_syscall,
164 [__NR_create_module] sys_ni_syscall,
165 [__NR_init_module] sys_ni_syscall, /* sys_init_module */
166 [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */
167 [__NR_get_kernel_syms] sys_ni_syscall,
168 [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */
169 [__NR_getpgid] sys_getpgid,
170 [__NR_fchdir] sys_fchdir,
171 [__NR_bdflush] sys_bdflush,
172 [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */
173 [__NR_personality] ppc64_personality,
174 [__NR_afs_syscall] sys_ni_syscall,
175 [__NR_setfsuid] sys_setfsuid,
176 [__NR_setfsgid] sys_setfsgid,
177 [__NR__llseek] sys_llseek,
178 [__NR_getdents] sys_getdents,
179 [__NR__newselect] sys_select,
180 [__NR_flock] sys_flock,
181 [__NR_msync] sys_msync,
182 [__NR_readv] sys_readv,
183 [__NR_writev] sys_writev,
184 [__NR_getsid] sys_getsid,
185 [__NR_fdatasync] sys_fdatasync,
186 [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */
187 [__NR_mlock] sys_mlock,
188 [__NR_munlock] sys_munlock,
189 [__NR_mlockall] sys_mlockall,
190 [__NR_munlockall] sys_munlockall,
191 [__NR_sched_setparam] sys_sched_setparam,
192 [__NR_sched_getparam] sys_sched_getparam,
193 [__NR_sched_setscheduler] sys_sched_setscheduler,
194 [__NR_sched_getscheduler] sys_sched_getscheduler,
195 [__NR_sched_yield] sys_sched_yield,
196 [__NR_sched_get_priority_max] sys_sched_get_priority_max,
197 [__NR_sched_get_priority_min] sys_sched_get_priority_min,
198 [__NR_sched_rr_get_interval] sys_sched_rr_get_interval,
199 [__NR_nanosleep] sys_nanosleep,
200 [__NR_mremap] sys_mremap,
201 [__NR_setresuid] sys_setresuid,
202 [__NR_getresuid] sys_getresuid,
203 [__NR_query_module] sys_ni_syscall,
204 [__NR_poll] sys_poll,
205 [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */
206 [__NR_setresgid] sys_setresgid,
207 [__NR_getresgid] sys_getresgid,
208 [__NR_prctl] sys_prctl,
209 [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */
210 [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */
211 [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */
212 [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */
213 [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */
214 [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */
215 [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */
216 [__NR_pread64] sys_pread64,
217 [__NR_pwrite64] sys_pwrite64,
218 [__NR_chown] sys_chown,
219 [__NR_getcwd] sys_getcwd,
220 [__NR_capget] sys_capget,
221 [__NR_capset] sys_capset,
222 [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */
223 [__NR_sendfile] sys_sendfile64,
224 [__NR_getpmsg] sys_ni_syscall,
225 [__NR_putpmsg] sys_ni_syscall,
226 [__NR_vfork] sys_ni_syscall, /* ppc_vfork */
227 [__NR_ugetrlimit] sys_getrlimit,
228 [__NR_readahead] sys_readahead,
229 [192] sys_ni_syscall,
230 [193] sys_ni_syscall,
231 [194] sys_ni_syscall,
232 [195] sys_ni_syscall,
233 [196] sys_ni_syscall,
234 [197] sys_ni_syscall,
235 [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */
236 [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */
237 [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */
238 [__NR_multiplexer] sys_ni_syscall,
239 [__NR_getdents64] sys_getdents64,
240 [__NR_pivot_root] sys_pivot_root,
241 [204] sys_ni_syscall,
242 [__NR_madvise] sys_madvise,
243 [__NR_mincore] sys_mincore,
244 [__NR_gettid] sys_gettid,
245 [__NR_tkill] sys_tkill,
246 [__NR_setxattr] sys_setxattr,
247 [__NR_lsetxattr] sys_lsetxattr,
248 [__NR_fsetxattr] sys_fsetxattr,
249 [__NR_getxattr] sys_getxattr,
250 [__NR_lgetxattr] sys_lgetxattr,
251 [__NR_fgetxattr] sys_fgetxattr,
252 [__NR_listxattr] sys_listxattr,
253 [__NR_llistxattr] sys_llistxattr,
254 [__NR_flistxattr] sys_flistxattr,
255 [__NR_removexattr] sys_removexattr,
256 [__NR_lremovexattr] sys_lremovexattr,
257 [__NR_fremovexattr] sys_fremovexattr,
258 [__NR_futex] sys_futex,
259 [__NR_sched_setaffinity] sys_sched_setaffinity,
260 [__NR_sched_getaffinity] sys_sched_getaffinity,
261 [__NR_tuxcall] sys_ni_syscall,
262 [226] sys_ni_syscall,
263 [__NR_io_setup] sys_io_setup,
264 [__NR_io_destroy] sys_io_destroy,
265 [__NR_io_getevents] sys_io_getevents,
266 [__NR_io_submit] sys_io_submit,
267 [__NR_io_cancel] sys_io_cancel,
268 [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */
269 [__NR_fadvise64] sys_fadvise64,
270 [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */
271 [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */
272 [__NR_epoll_create] sys_epoll_create,
273 [__NR_epoll_ctl] sys_epoll_ctl,
274 [__NR_epoll_wait] sys_epoll_wait,
275 [__NR_remap_file_pages] sys_remap_file_pages,
276 [__NR_timer_create] sys_timer_create,
277 [__NR_timer_settime] sys_timer_settime,
278 [__NR_timer_gettime] sys_timer_gettime,
279 [__NR_timer_getoverrun] sys_timer_getoverrun,
280 [__NR_timer_delete] sys_timer_delete,
281 [__NR_clock_settime] sys_clock_settime,
282 [__NR_clock_gettime] sys_clock_gettime,
283 [__NR_clock_getres] sys_clock_getres,
284 [__NR_clock_nanosleep] sys_clock_nanosleep,
285 [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */
286 [__NR_tgkill] sys_tgkill,
287 [__NR_utimes] sys_utimes,
288 [__NR_statfs64] sys_statfs64,
289 [__NR_fstatfs64] sys_fstatfs64,
290 [254] sys_ni_syscall,
291 [__NR_rtas] ppc_rtas,
292 [256] sys_ni_syscall,
293 [257] sys_ni_syscall,
294 [258] sys_ni_syscall,
295 [__NR_mbind] sys_ni_syscall, /* sys_mbind */
296 [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */
297 [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */
298 [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */
299 [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */
300 [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */
301 [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */
302 [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */
303 [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */
304 [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */
305 [__NR_add_key] sys_ni_syscall, /* sys_add_key */
306 [__NR_request_key] sys_ni_syscall, /* sys_request_key */
307 [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */
308 [__NR_waitid] sys_ni_syscall, /* sys_waitid */
309 [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */
310 [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */
311 [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */
312 [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */
313 [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */
314 [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */
315 [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */
316 [__NR_pselect6] sys_ni_syscall, /* sys_pselect */
317 [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */
318 [__NR_unshare] sys_unshare,
319};
320
321long spu_sys_callback(struct spu_syscall_block *s)
322{
323 long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
324
325 BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls);
326
327 syscall = spu_syscall_table[s->nr_ret];
328
329 if (s->nr_ret >= __NR_syscalls) {
330 pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret);
331 return -ENOSYS;
332 }
333
334#ifdef DEBUG
335 print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall);
336 printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n",
337 s->nr_ret,
338 s->parm[0], s->parm[1], s->parm[2],
339 s->parm[3], s->parm[4], s->parm[5]);
340#endif
341
342 return syscall(s->parm[0], s->parm[1], s->parm[2],
343 s->parm[3], s->parm[4], s->parm[5]);
344}
345EXPORT_SYMBOL_GPL(spu_sys_callback);
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index a5c489a53c61..f1d35ddc9df3 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -285,6 +285,49 @@ static void spu_backing_runcntl_stop(struct spu_context *ctx)
285 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); 285 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
286} 286}
287 287
288static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask,
289 u32 mode)
290{
291 struct spu_problem_collapsed *prob = &ctx->csa.prob;
292 int ret;
293
294 spin_lock(&ctx->csa.register_lock);
295 ret = -EAGAIN;
296 if (prob->dma_querytype_RW)
297 goto out;
298 ret = 0;
299 /* FIXME: what are the side-effects of this? */
300 prob->dma_querymask_RW = mask;
301 prob->dma_querytype_RW = mode;
302out:
303 spin_unlock(&ctx->csa.register_lock);
304
305 return ret;
306}
307
308static u32 spu_backing_read_mfc_tagstatus(struct spu_context * ctx)
309{
310 return ctx->csa.prob.dma_tagstatus_R;
311}
312
313static u32 spu_backing_get_mfc_free_elements(struct spu_context *ctx)
314{
315 return ctx->csa.prob.dma_qstatus_R;
316}
317
318static int spu_backing_send_mfc_command(struct spu_context *ctx,
319 struct mfc_dma_command *cmd)
320{
321 int ret;
322
323 spin_lock(&ctx->csa.register_lock);
324 ret = -EAGAIN;
325 /* FIXME: set up priv2->puq */
326 spin_unlock(&ctx->csa.register_lock);
327
328 return ret;
329}
330
288struct spu_context_ops spu_backing_ops = { 331struct spu_context_ops spu_backing_ops = {
289 .mbox_read = spu_backing_mbox_read, 332 .mbox_read = spu_backing_mbox_read,
290 .mbox_stat_read = spu_backing_mbox_stat_read, 333 .mbox_stat_read = spu_backing_mbox_stat_read,
@@ -305,4 +348,8 @@ struct spu_context_ops spu_backing_ops = {
305 .get_ls = spu_backing_get_ls, 348 .get_ls = spu_backing_get_ls,
306 .runcntl_write = spu_backing_runcntl_write, 349 .runcntl_write = spu_backing_runcntl_write,
307 .runcntl_stop = spu_backing_runcntl_stop, 350 .runcntl_stop = spu_backing_runcntl_stop,
351 .set_mfc_query = spu_backing_set_mfc_query,
352 .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus,
353 .get_mfc_free_elements = spu_backing_get_mfc_free_elements,
354 .send_mfc_command = spu_backing_send_mfc_command,
308}; 355};
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 336f238102fd..8bb33abfad17 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -27,7 +27,7 @@
27#include <asm/spu_csa.h> 27#include <asm/spu_csa.h>
28#include "spufs.h" 28#include "spufs.h"
29 29
30struct spu_context *alloc_spu_context(struct address_space *local_store) 30struct spu_context *alloc_spu_context(void)
31{ 31{
32 struct spu_context *ctx; 32 struct spu_context *ctx;
33 ctx = kmalloc(sizeof *ctx, GFP_KERNEL); 33 ctx = kmalloc(sizeof *ctx, GFP_KERNEL);
@@ -47,10 +47,17 @@ struct spu_context *alloc_spu_context(struct address_space *local_store)
47 init_waitqueue_head(&ctx->ibox_wq); 47 init_waitqueue_head(&ctx->ibox_wq);
48 init_waitqueue_head(&ctx->wbox_wq); 48 init_waitqueue_head(&ctx->wbox_wq);
49 init_waitqueue_head(&ctx->stop_wq); 49 init_waitqueue_head(&ctx->stop_wq);
50 init_waitqueue_head(&ctx->mfc_wq);
50 ctx->ibox_fasync = NULL; 51 ctx->ibox_fasync = NULL;
51 ctx->wbox_fasync = NULL; 52 ctx->wbox_fasync = NULL;
53 ctx->mfc_fasync = NULL;
54 ctx->mfc = NULL;
55 ctx->tagwait = 0;
52 ctx->state = SPU_STATE_SAVED; 56 ctx->state = SPU_STATE_SAVED;
53 ctx->local_store = local_store; 57 ctx->local_store = NULL;
58 ctx->cntl = NULL;
59 ctx->signal1 = NULL;
60 ctx->signal2 = NULL;
54 ctx->spu = NULL; 61 ctx->spu = NULL;
55 ctx->ops = &spu_backing_ops; 62 ctx->ops = &spu_backing_ops;
56 ctx->owner = get_task_mm(current); 63 ctx->owner = get_task_mm(current);
@@ -68,8 +75,6 @@ void destroy_spu_context(struct kref *kref)
68 ctx = container_of(kref, struct spu_context, kref); 75 ctx = container_of(kref, struct spu_context, kref);
69 down_write(&ctx->state_sema); 76 down_write(&ctx->state_sema);
70 spu_deactivate(ctx); 77 spu_deactivate(ctx);
71 ctx->ibox_fasync = NULL;
72 ctx->wbox_fasync = NULL;
73 up_write(&ctx->state_sema); 78 up_write(&ctx->state_sema);
74 spu_fini_csa(&ctx->csa); 79 spu_fini_csa(&ctx->csa);
75 kfree(ctx); 80 kfree(ctx);
@@ -109,7 +114,16 @@ void spu_release(struct spu_context *ctx)
109 114
110void spu_unmap_mappings(struct spu_context *ctx) 115void spu_unmap_mappings(struct spu_context *ctx)
111{ 116{
112 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); 117 if (ctx->local_store)
118 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
119 if (ctx->mfc)
120 unmap_mapping_range(ctx->mfc, 0, 0x4000, 1);
121 if (ctx->cntl)
122 unmap_mapping_range(ctx->cntl, 0, 0x4000, 1);
123 if (ctx->signal1)
124 unmap_mapping_range(ctx->signal1, 0, 0x4000, 1);
125 if (ctx->signal2)
126 unmap_mapping_range(ctx->signal2, 0, 0x4000, 1);
113} 127}
114 128
115int spu_acquire_runnable(struct spu_context *ctx) 129int spu_acquire_runnable(struct spu_context *ctx)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index dfa649c9b956..366185e92667 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -20,6 +20,8 @@
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 21 */
22 22
23#undef DEBUG
24
23#include <linux/fs.h> 25#include <linux/fs.h>
24#include <linux/ioctl.h> 26#include <linux/ioctl.h>
25#include <linux/module.h> 27#include <linux/module.h>
@@ -39,8 +41,10 @@ static int
39spufs_mem_open(struct inode *inode, struct file *file) 41spufs_mem_open(struct inode *inode, struct file *file)
40{ 42{
41 struct spufs_inode_info *i = SPUFS_I(inode); 43 struct spufs_inode_info *i = SPUFS_I(inode);
42 file->private_data = i->i_ctx; 44 struct spu_context *ctx = i->i_ctx;
43 file->f_mapping = i->i_ctx->local_store; 45 file->private_data = ctx;
46 file->f_mapping = inode->i_mapping;
47 ctx->local_store = inode->i_mapping;
44 return 0; 48 return 0;
45} 49}
46 50
@@ -84,7 +88,7 @@ spufs_mem_write(struct file *file, const char __user *buffer,
84 return ret; 88 return ret;
85} 89}
86 90
87#ifdef CONFIG_SPARSEMEM 91#ifdef CONFIG_SPUFS_MMAP
88static struct page * 92static struct page *
89spufs_mem_mmap_nopage(struct vm_area_struct *vma, 93spufs_mem_mmap_nopage(struct vm_area_struct *vma,
90 unsigned long address, int *type) 94 unsigned long address, int *type)
@@ -136,11 +140,113 @@ static struct file_operations spufs_mem_fops = {
136 .read = spufs_mem_read, 140 .read = spufs_mem_read,
137 .write = spufs_mem_write, 141 .write = spufs_mem_write,
138 .llseek = generic_file_llseek, 142 .llseek = generic_file_llseek,
139#ifdef CONFIG_SPARSEMEM 143#ifdef CONFIG_SPUFS_MMAP
140 .mmap = spufs_mem_mmap, 144 .mmap = spufs_mem_mmap,
141#endif 145#endif
142}; 146};
143 147
148#ifdef CONFIG_SPUFS_MMAP
149static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
150 unsigned long address,
151 int *type, unsigned long ps_offs)
152{
153 struct page *page = NOPAGE_SIGBUS;
154 int fault_type = VM_FAULT_SIGBUS;
155 struct spu_context *ctx = vma->vm_file->private_data;
156 unsigned long offset = address - vma->vm_start;
157 unsigned long area;
158 int ret;
159
160 offset += vma->vm_pgoff << PAGE_SHIFT;
161 if (offset >= 0x4000)
162 goto out;
163
164 ret = spu_acquire_runnable(ctx);
165 if (ret)
166 goto out;
167
168 area = ctx->spu->problem_phys + ps_offs;
169 page = pfn_to_page((area + offset) >> PAGE_SHIFT);
170 fault_type = VM_FAULT_MINOR;
171 page_cache_get(page);
172
173 spu_release(ctx);
174
175 out:
176 if (type)
177 *type = fault_type;
178
179 return page;
180}
181
182static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma,
183 unsigned long address, int *type)
184{
185 return spufs_ps_nopage(vma, address, type, 0x4000);
186}
187
188static struct vm_operations_struct spufs_cntl_mmap_vmops = {
189 .nopage = spufs_cntl_mmap_nopage,
190};
191
192/*
193 * mmap support for problem state control area [0x4000 - 0x4fff].
194 * Mapping this area requires that the application have CAP_SYS_RAWIO,
195 * as these registers require special care when read/writing.
196 */
197static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
198{
199 if (!(vma->vm_flags & VM_SHARED))
200 return -EINVAL;
201
202 if (!capable(CAP_SYS_RAWIO))
203 return -EPERM;
204
205 vma->vm_flags |= VM_RESERVED;
206 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
207 | _PAGE_NO_CACHE);
208
209 vma->vm_ops = &spufs_cntl_mmap_vmops;
210 return 0;
211}
212#endif
213
214static int spufs_cntl_open(struct inode *inode, struct file *file)
215{
216 struct spufs_inode_info *i = SPUFS_I(inode);
217 struct spu_context *ctx = i->i_ctx;
218
219 file->private_data = ctx;
220 file->f_mapping = inode->i_mapping;
221 ctx->cntl = inode->i_mapping;
222 return 0;
223}
224
225static ssize_t
226spufs_cntl_read(struct file *file, char __user *buffer,
227 size_t size, loff_t *pos)
228{
229 /* FIXME: read from spu status */
230 return -EINVAL;
231}
232
233static ssize_t
234spufs_cntl_write(struct file *file, const char __user *buffer,
235 size_t size, loff_t *pos)
236{
237 /* FIXME: write to runctl bit */
238 return -EINVAL;
239}
240
241static struct file_operations spufs_cntl_fops = {
242 .open = spufs_cntl_open,
243 .read = spufs_cntl_read,
244 .write = spufs_cntl_write,
245#ifdef CONFIG_SPUFS_MMAP
246 .mmap = spufs_cntl_mmap,
247#endif
248};
249
144static int 250static int
145spufs_regs_open(struct inode *inode, struct file *file) 251spufs_regs_open(struct inode *inode, struct file *file)
146{ 252{
@@ -501,6 +607,16 @@ static struct file_operations spufs_wbox_stat_fops = {
501 .read = spufs_wbox_stat_read, 607 .read = spufs_wbox_stat_read,
502}; 608};
503 609
610static int spufs_signal1_open(struct inode *inode, struct file *file)
611{
612 struct spufs_inode_info *i = SPUFS_I(inode);
613 struct spu_context *ctx = i->i_ctx;
614 file->private_data = ctx;
615 file->f_mapping = inode->i_mapping;
616 ctx->signal1 = inode->i_mapping;
617 return nonseekable_open(inode, file);
618}
619
504static ssize_t spufs_signal1_read(struct file *file, char __user *buf, 620static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
505 size_t len, loff_t *pos) 621 size_t len, loff_t *pos)
506{ 622{
@@ -541,12 +657,50 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
541 return 4; 657 return 4;
542} 658}
543 659
660#ifdef CONFIG_SPUFS_MMAP
661static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma,
662 unsigned long address, int *type)
663{
664 return spufs_ps_nopage(vma, address, type, 0x14000);
665}
666
667static struct vm_operations_struct spufs_signal1_mmap_vmops = {
668 .nopage = spufs_signal1_mmap_nopage,
669};
670
671static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
672{
673 if (!(vma->vm_flags & VM_SHARED))
674 return -EINVAL;
675
676 vma->vm_flags |= VM_RESERVED;
677 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
678 | _PAGE_NO_CACHE);
679
680 vma->vm_ops = &spufs_signal1_mmap_vmops;
681 return 0;
682}
683#endif
684
544static struct file_operations spufs_signal1_fops = { 685static struct file_operations spufs_signal1_fops = {
545 .open = spufs_pipe_open, 686 .open = spufs_signal1_open,
546 .read = spufs_signal1_read, 687 .read = spufs_signal1_read,
547 .write = spufs_signal1_write, 688 .write = spufs_signal1_write,
689#ifdef CONFIG_SPUFS_MMAP
690 .mmap = spufs_signal1_mmap,
691#endif
548}; 692};
549 693
694static int spufs_signal2_open(struct inode *inode, struct file *file)
695{
696 struct spufs_inode_info *i = SPUFS_I(inode);
697 struct spu_context *ctx = i->i_ctx;
698 file->private_data = ctx;
699 file->f_mapping = inode->i_mapping;
700 ctx->signal2 = inode->i_mapping;
701 return nonseekable_open(inode, file);
702}
703
550static ssize_t spufs_signal2_read(struct file *file, char __user *buf, 704static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
551 size_t len, loff_t *pos) 705 size_t len, loff_t *pos)
552{ 706{
@@ -589,10 +743,39 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
589 return 4; 743 return 4;
590} 744}
591 745
746#ifdef CONFIG_SPUFS_MMAP
747static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma,
748 unsigned long address, int *type)
749{
750 return spufs_ps_nopage(vma, address, type, 0x1c000);
751}
752
753static struct vm_operations_struct spufs_signal2_mmap_vmops = {
754 .nopage = spufs_signal2_mmap_nopage,
755};
756
757static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
758{
759 if (!(vma->vm_flags & VM_SHARED))
760 return -EINVAL;
761
762 /* FIXME: */
763 vma->vm_flags |= VM_RESERVED;
764 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
765 | _PAGE_NO_CACHE);
766
767 vma->vm_ops = &spufs_signal2_mmap_vmops;
768 return 0;
769}
770#endif
771
592static struct file_operations spufs_signal2_fops = { 772static struct file_operations spufs_signal2_fops = {
593 .open = spufs_pipe_open, 773 .open = spufs_signal2_open,
594 .read = spufs_signal2_read, 774 .read = spufs_signal2_read,
595 .write = spufs_signal2_write, 775 .write = spufs_signal2_write,
776#ifdef CONFIG_SPUFS_MMAP
777 .mmap = spufs_signal2_mmap,
778#endif
596}; 779};
597 780
598static void spufs_signal1_type_set(void *data, u64 val) 781static void spufs_signal1_type_set(void *data, u64 val)
@@ -641,6 +824,332 @@ static u64 spufs_signal2_type_get(void *data)
641DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, 824DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
642 spufs_signal2_type_set, "%llu"); 825 spufs_signal2_type_set, "%llu");
643 826
827#ifdef CONFIG_SPUFS_MMAP
828static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma,
829 unsigned long address, int *type)
830{
831 return spufs_ps_nopage(vma, address, type, 0x3000);
832}
833
834static struct vm_operations_struct spufs_mfc_mmap_vmops = {
835 .nopage = spufs_mfc_mmap_nopage,
836};
837
838/*
839 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
840 * Mapping this area requires that the application have CAP_SYS_RAWIO,
841 * as these registers require special care when read/writing.
842 */
843static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
844{
845 if (!(vma->vm_flags & VM_SHARED))
846 return -EINVAL;
847
848 if (!capable(CAP_SYS_RAWIO))
849 return -EPERM;
850
851 vma->vm_flags |= VM_RESERVED;
852 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
853 | _PAGE_NO_CACHE);
854
855 vma->vm_ops = &spufs_mfc_mmap_vmops;
856 return 0;
857}
858#endif
859
860static int spufs_mfc_open(struct inode *inode, struct file *file)
861{
862 struct spufs_inode_info *i = SPUFS_I(inode);
863 struct spu_context *ctx = i->i_ctx;
864
865 /* we don't want to deal with DMA into other processes */
866 if (ctx->owner != current->mm)
867 return -EINVAL;
868
869 if (atomic_read(&inode->i_count) != 1)
870 return -EBUSY;
871
872 file->private_data = ctx;
873 return nonseekable_open(inode, file);
874}
875
876/* interrupt-level mfc callback function. */
877void spufs_mfc_callback(struct spu *spu)
878{
879 struct spu_context *ctx = spu->ctx;
880
881 wake_up_all(&ctx->mfc_wq);
882
883 pr_debug("%s %s\n", __FUNCTION__, spu->name);
884 if (ctx->mfc_fasync) {
885 u32 free_elements, tagstatus;
886 unsigned int mask;
887
888 /* no need for spu_acquire in interrupt context */
889 free_elements = ctx->ops->get_mfc_free_elements(ctx);
890 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
891
892 mask = 0;
893 if (free_elements & 0xffff)
894 mask |= POLLOUT;
895 if (tagstatus & ctx->tagwait)
896 mask |= POLLIN;
897
898 kill_fasync(&ctx->mfc_fasync, SIGIO, mask);
899 }
900}
901
902static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status)
903{
904 /* See if there is one tag group is complete */
905 /* FIXME we need locking around tagwait */
906 *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait;
907 ctx->tagwait &= ~*status;
908 if (*status)
909 return 1;
910
911 /* enable interrupt waiting for any tag group,
912 may silently fail if interrupts are already enabled */
913 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
914 return 0;
915}
916
917static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
918 size_t size, loff_t *pos)
919{
920 struct spu_context *ctx = file->private_data;
921 int ret = -EINVAL;
922 u32 status;
923
924 if (size != 4)
925 goto out;
926
927 spu_acquire(ctx);
928 if (file->f_flags & O_NONBLOCK) {
929 status = ctx->ops->read_mfc_tagstatus(ctx);
930 if (!(status & ctx->tagwait))
931 ret = -EAGAIN;
932 else
933 ctx->tagwait &= ~status;
934 } else {
935 ret = spufs_wait(ctx->mfc_wq,
936 spufs_read_mfc_tagstatus(ctx, &status));
937 }
938 spu_release(ctx);
939
940 if (ret)
941 goto out;
942
943 ret = 4;
944 if (copy_to_user(buffer, &status, 4))
945 ret = -EFAULT;
946
947out:
948 return ret;
949}
950
951static int spufs_check_valid_dma(struct mfc_dma_command *cmd)
952{
953 pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa,
954 cmd->ea, cmd->size, cmd->tag, cmd->cmd);
955
956 switch (cmd->cmd) {
957 case MFC_PUT_CMD:
958 case MFC_PUTF_CMD:
959 case MFC_PUTB_CMD:
960 case MFC_GET_CMD:
961 case MFC_GETF_CMD:
962 case MFC_GETB_CMD:
963 break;
964 default:
965 pr_debug("invalid DMA opcode %x\n", cmd->cmd);
966 return -EIO;
967 }
968
969 if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) {
970 pr_debug("invalid DMA alignment, ea %lx lsa %x\n",
971 cmd->ea, cmd->lsa);
972 return -EIO;
973 }
974
975 switch (cmd->size & 0xf) {
976 case 1:
977 break;
978 case 2:
979 if (cmd->lsa & 1)
980 goto error;
981 break;
982 case 4:
983 if (cmd->lsa & 3)
984 goto error;
985 break;
986 case 8:
987 if (cmd->lsa & 7)
988 goto error;
989 break;
990 case 0:
991 if (cmd->lsa & 15)
992 goto error;
993 break;
994 error:
995 default:
996 pr_debug("invalid DMA alignment %x for size %x\n",
997 cmd->lsa & 0xf, cmd->size);
998 return -EIO;
999 }
1000
1001 if (cmd->size > 16 * 1024) {
1002 pr_debug("invalid DMA size %x\n", cmd->size);
1003 return -EIO;
1004 }
1005
1006 if (cmd->tag & 0xfff0) {
1007 /* we reserve the higher tag numbers for kernel use */
1008 pr_debug("invalid DMA tag\n");
1009 return -EIO;
1010 }
1011
1012 if (cmd->class) {
1013 /* not supported in this version */
1014 pr_debug("invalid DMA class\n");
1015 return -EIO;
1016 }
1017
1018 return 0;
1019}
1020
1021static int spu_send_mfc_command(struct spu_context *ctx,
1022 struct mfc_dma_command cmd,
1023 int *error)
1024{
1025 *error = ctx->ops->send_mfc_command(ctx, &cmd);
1026 if (*error == -EAGAIN) {
1027 /* wait for any tag group to complete
1028 so we have space for the new command */
1029 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
1030 /* try again, because the queue might be
1031 empty again */
1032 *error = ctx->ops->send_mfc_command(ctx, &cmd);
1033 if (*error == -EAGAIN)
1034 return 0;
1035 }
1036 return 1;
1037}
1038
1039static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1040 size_t size, loff_t *pos)
1041{
1042 struct spu_context *ctx = file->private_data;
1043 struct mfc_dma_command cmd;
1044 int ret = -EINVAL;
1045
1046 if (size != sizeof cmd)
1047 goto out;
1048
1049 ret = -EFAULT;
1050 if (copy_from_user(&cmd, buffer, sizeof cmd))
1051 goto out;
1052
1053 ret = spufs_check_valid_dma(&cmd);
1054 if (ret)
1055 goto out;
1056
1057 spu_acquire_runnable(ctx);
1058 if (file->f_flags & O_NONBLOCK) {
1059 ret = ctx->ops->send_mfc_command(ctx, &cmd);
1060 } else {
1061 int status;
1062 ret = spufs_wait(ctx->mfc_wq,
1063 spu_send_mfc_command(ctx, cmd, &status));
1064 if (status)
1065 ret = status;
1066 }
1067 spu_release(ctx);
1068
1069 if (ret)
1070 goto out;
1071
1072 ctx->tagwait |= 1 << cmd.tag;
1073
1074out:
1075 return ret;
1076}
1077
1078static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1079{
1080 struct spu_context *ctx = file->private_data;
1081 u32 free_elements, tagstatus;
1082 unsigned int mask;
1083
1084 spu_acquire(ctx);
1085 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1086 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1087 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1088 spu_release(ctx);
1089
1090 poll_wait(file, &ctx->mfc_wq, wait);
1091
1092 mask = 0;
1093 if (free_elements & 0xffff)
1094 mask |= POLLOUT | POLLWRNORM;
1095 if (tagstatus & ctx->tagwait)
1096 mask |= POLLIN | POLLRDNORM;
1097
1098 pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__,
1099 free_elements, tagstatus, ctx->tagwait);
1100
1101 return mask;
1102}
1103
1104static int spufs_mfc_flush(struct file *file)
1105{
1106 struct spu_context *ctx = file->private_data;
1107 int ret;
1108
1109 spu_acquire(ctx);
1110#if 0
1111/* this currently hangs */
1112 ret = spufs_wait(ctx->mfc_wq,
1113 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2));
1114 if (ret)
1115 goto out;
1116 ret = spufs_wait(ctx->mfc_wq,
1117 ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
1118out:
1119#else
1120 ret = 0;
1121#endif
1122 spu_release(ctx);
1123
1124 return ret;
1125}
1126
1127static int spufs_mfc_fsync(struct file *file, struct dentry *dentry,
1128 int datasync)
1129{
1130 return spufs_mfc_flush(file);
1131}
1132
1133static int spufs_mfc_fasync(int fd, struct file *file, int on)
1134{
1135 struct spu_context *ctx = file->private_data;
1136
1137 return fasync_helper(fd, file, on, &ctx->mfc_fasync);
1138}
1139
1140static struct file_operations spufs_mfc_fops = {
1141 .open = spufs_mfc_open,
1142 .read = spufs_mfc_read,
1143 .write = spufs_mfc_write,
1144 .poll = spufs_mfc_poll,
1145 .flush = spufs_mfc_flush,
1146 .fsync = spufs_mfc_fsync,
1147 .fasync = spufs_mfc_fasync,
1148#ifdef CONFIG_SPUFS_MMAP
1149 .mmap = spufs_mfc_mmap,
1150#endif
1151};
1152
644static void spufs_npc_set(void *data, u64 val) 1153static void spufs_npc_set(void *data, u64 val)
645{ 1154{
646 struct spu_context *ctx = data; 1155 struct spu_context *ctx = data;
@@ -783,6 +1292,8 @@ struct tree_descr spufs_dir_contents[] = {
783 { "signal2", &spufs_signal2_fops, 0666, }, 1292 { "signal2", &spufs_signal2_fops, 0666, },
784 { "signal1_type", &spufs_signal1_type, 0666, }, 1293 { "signal1_type", &spufs_signal1_type, 0666, },
785 { "signal2_type", &spufs_signal2_type, 0666, }, 1294 { "signal2_type", &spufs_signal2_type, 0666, },
1295 { "mfc", &spufs_mfc_fops, 0666, },
1296 { "cntl", &spufs_cntl_fops, 0666, },
786 { "npc", &spufs_npc_ops, 0666, }, 1297 { "npc", &spufs_npc_ops, 0666, },
787 { "fpcr", &spufs_fpcr_fops, 0666, }, 1298 { "fpcr", &spufs_fpcr_fops, 0666, },
788 { "decr", &spufs_decr_ops, 0666, }, 1299 { "decr", &spufs_decr_ops, 0666, },
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 5445719bff79..a13a8b5a014d 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -232,6 +232,59 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
232 spin_unlock_irq(&ctx->spu->register_lock); 232 spin_unlock_irq(&ctx->spu->register_lock);
233} 233}
234 234
235static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
236{
237 struct spu_problem *prob = ctx->spu->problem;
238 int ret;
239
240 spin_lock_irq(&ctx->spu->register_lock);
241 ret = -EAGAIN;
242 if (in_be32(&prob->dma_querytype_RW))
243 goto out;
244 ret = 0;
245 out_be32(&prob->dma_querymask_RW, mask);
246 out_be32(&prob->dma_querytype_RW, mode);
247out:
248 spin_unlock_irq(&ctx->spu->register_lock);
249 return ret;
250}
251
252static u32 spu_hw_read_mfc_tagstatus(struct spu_context * ctx)
253{
254 return in_be32(&ctx->spu->problem->dma_tagstatus_R);
255}
256
257static u32 spu_hw_get_mfc_free_elements(struct spu_context *ctx)
258{
259 return in_be32(&ctx->spu->problem->dma_qstatus_R);
260}
261
262static int spu_hw_send_mfc_command(struct spu_context *ctx,
263 struct mfc_dma_command *cmd)
264{
265 u32 status;
266 struct spu_problem *prob = ctx->spu->problem;
267
268 spin_lock_irq(&ctx->spu->register_lock);
269 out_be32(&prob->mfc_lsa_W, cmd->lsa);
270 out_be64(&prob->mfc_ea_W, cmd->ea);
271 out_be32(&prob->mfc_union_W.by32.mfc_size_tag32,
272 cmd->size << 16 | cmd->tag);
273 out_be32(&prob->mfc_union_W.by32.mfc_class_cmd32,
274 cmd->class << 16 | cmd->cmd);
275 status = in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32);
276 spin_unlock_irq(&ctx->spu->register_lock);
277
278 switch (status & 0xffff) {
279 case 0:
280 return 0;
281 case 2:
282 return -EAGAIN;
283 default:
284 return -EINVAL;
285 }
286}
287
235struct spu_context_ops spu_hw_ops = { 288struct spu_context_ops spu_hw_ops = {
236 .mbox_read = spu_hw_mbox_read, 289 .mbox_read = spu_hw_mbox_read,
237 .mbox_stat_read = spu_hw_mbox_stat_read, 290 .mbox_stat_read = spu_hw_mbox_stat_read,
@@ -252,4 +305,8 @@ struct spu_context_ops spu_hw_ops = {
252 .get_ls = spu_hw_get_ls, 305 .get_ls = spu_hw_get_ls,
253 .runcntl_write = spu_hw_runcntl_write, 306 .runcntl_write = spu_hw_runcntl_write,
254 .runcntl_stop = spu_hw_runcntl_stop, 307 .runcntl_stop = spu_hw_runcntl_stop,
308 .set_mfc_query = spu_hw_set_mfc_query,
309 .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus,
310 .get_mfc_free_elements = spu_hw_get_mfc_free_elements,
311 .send_mfc_command = spu_hw_send_mfc_command,
255}; 312};
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index b3962c3a0348..d9554199afa7 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -103,7 +103,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
103 103
104static int 104static int
105spufs_new_file(struct super_block *sb, struct dentry *dentry, 105spufs_new_file(struct super_block *sb, struct dentry *dentry,
106 struct file_operations *fops, int mode, 106 const struct file_operations *fops, int mode,
107 struct spu_context *ctx) 107 struct spu_context *ctx)
108{ 108{
109 static struct inode_operations spufs_file_iops = { 109 static struct inode_operations spufs_file_iops = {
@@ -241,7 +241,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
241 inode->i_gid = dir->i_gid; 241 inode->i_gid = dir->i_gid;
242 inode->i_mode &= S_ISGID; 242 inode->i_mode &= S_ISGID;
243 } 243 }
244 ctx = alloc_spu_context(inode->i_mapping); 244 ctx = alloc_spu_context();
245 SPUFS_I(inode)->i_ctx = ctx; 245 SPUFS_I(inode)->i_ctx = ctx;
246 if (!ctx) 246 if (!ctx)
247 goto out_iput; 247 goto out_iput;
@@ -442,7 +442,7 @@ static struct file_system_type spufs_type = {
442 .kill_sb = kill_litter_super, 442 .kill_sb = kill_litter_super,
443}; 443};
444 444
445static int spufs_init(void) 445static int __init spufs_init(void)
446{ 446{
447 int ret; 447 int ret;
448 ret = -ENOMEM; 448 ret = -ENOMEM;
@@ -472,7 +472,7 @@ out:
472} 472}
473module_init(spufs_init); 473module_init(spufs_init);
474 474
475static void spufs_exit(void) 475static void __exit spufs_exit(void)
476{ 476{
477 spu_sched_exit(); 477 spu_sched_exit();
478 unregister_spu_syscalls(&spufs_calls); 478 unregister_spu_syscalls(&spufs_calls);
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 18ea8866c61a..c04e078c0fe5 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -76,6 +76,90 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
76 return 0; 76 return 0;
77} 77}
78 78
79/*
80 * SPU syscall restarting is tricky because we violate the basic
81 * assumption that the signal handler is running on the interrupted
82 * thread. Here instead, the handler runs on PowerPC user space code,
83 * while the syscall was called from the SPU.
84 * This means we can only do a very rough approximation of POSIX
85 * signal semantics.
86 */
87int spu_handle_restartsys(struct spu_context *ctx, long *spu_ret,
88 unsigned int *npc)
89{
90 int ret;
91
92 switch (*spu_ret) {
93 case -ERESTARTSYS:
94 case -ERESTARTNOINTR:
95 /*
96 * Enter the regular syscall restarting for
97 * sys_spu_run, then restart the SPU syscall
98 * callback.
99 */
100 *npc -= 8;
101 ret = -ERESTARTSYS;
102 break;
103 case -ERESTARTNOHAND:
104 case -ERESTART_RESTARTBLOCK:
105 /*
106 * Restart block is too hard for now, just return -EINTR
107 * to the SPU.
108 * ERESTARTNOHAND comes from sys_pause, we also return
109 * -EINTR from there.
110 * Assume that we need to be restarted ourselves though.
111 */
112 *spu_ret = -EINTR;
113 ret = -ERESTARTSYS;
114 break;
115 default:
116 printk(KERN_WARNING "%s: unexpected return code %ld\n",
117 __FUNCTION__, *spu_ret);
118 ret = 0;
119 }
120 return ret;
121}
122
123int spu_process_callback(struct spu_context *ctx)
124{
125 struct spu_syscall_block s;
126 u32 ls_pointer, npc;
127 char *ls;
128 long spu_ret;
129 int ret;
130
131 /* get syscall block from local store */
132 npc = ctx->ops->npc_read(ctx);
133 ls = ctx->ops->get_ls(ctx);
134 ls_pointer = *(u32*)(ls + npc);
135 if (ls_pointer > (LS_SIZE - sizeof(s)))
136 return -EFAULT;
137 memcpy(&s, ls + ls_pointer, sizeof (s));
138
139 /* do actual syscall without pinning the spu */
140 ret = 0;
141 spu_ret = -ENOSYS;
142 npc += 4;
143
144 if (s.nr_ret < __NR_syscalls) {
145 spu_release(ctx);
146 /* do actual system call from here */
147 spu_ret = spu_sys_callback(&s);
148 if (spu_ret <= -ERESTARTSYS) {
149 ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
150 }
151 spu_acquire(ctx);
152 if (ret == -ERESTARTSYS)
153 return ret;
154 }
155
156 /* write result, jump over indirect pointer */
157 memcpy(ls + ls_pointer, &spu_ret, sizeof (spu_ret));
158 ctx->ops->npc_write(ctx, npc);
159 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
160 return ret;
161}
162
79static inline int spu_process_events(struct spu_context *ctx) 163static inline int spu_process_events(struct spu_context *ctx)
80{ 164{
81 struct spu *spu = ctx->spu; 165 struct spu *spu = ctx->spu;
@@ -107,6 +191,13 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
107 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); 191 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
108 if (unlikely(ret)) 192 if (unlikely(ret))
109 break; 193 break;
194 if ((*status & SPU_STATUS_STOPPED_BY_STOP) &&
195 (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
196 ret = spu_process_callback(ctx);
197 if (ret)
198 break;
199 *status &= ~SPU_STATUS_STOPPED_BY_STOP;
200 }
110 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 201 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
111 ret = spu_reacquire_runnable(ctx, npc, status); 202 ret = spu_reacquire_runnable(ctx, npc, status);
112 if (ret) 203 if (ret)
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 963182fbd1aa..bf652cd77000 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -180,6 +180,7 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
180 spu->ibox_callback = spufs_ibox_callback; 180 spu->ibox_callback = spufs_ibox_callback;
181 spu->wbox_callback = spufs_wbox_callback; 181 spu->wbox_callback = spufs_wbox_callback;
182 spu->stop_callback = spufs_stop_callback; 182 spu->stop_callback = spufs_stop_callback;
183 spu->mfc_callback = spufs_mfc_callback;
183 mb(); 184 mb();
184 spu_unmap_mappings(ctx); 185 spu_unmap_mappings(ctx);
185 spu_restore(&ctx->csa, spu); 186 spu_restore(&ctx->csa, spu);
@@ -197,6 +198,7 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
197 spu->ibox_callback = NULL; 198 spu->ibox_callback = NULL;
198 spu->wbox_callback = NULL; 199 spu->wbox_callback = NULL;
199 spu->stop_callback = NULL; 200 spu->stop_callback = NULL;
201 spu->mfc_callback = NULL;
200 spu->mm = NULL; 202 spu->mm = NULL;
201 spu->pid = 0; 203 spu->pid = 0;
202 spu->prio = MAX_PRIO; 204 spu->prio = MAX_PRIO;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index db2601f0abd5..4485738e2102 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -43,7 +43,11 @@ struct spu_context {
43 struct spu *spu; /* pointer to a physical SPU */ 43 struct spu *spu; /* pointer to a physical SPU */
44 struct spu_state csa; /* SPU context save area. */ 44 struct spu_state csa; /* SPU context save area. */
45 spinlock_t mmio_lock; /* protects mmio access */ 45 spinlock_t mmio_lock; /* protects mmio access */
46 struct address_space *local_store;/* local store backing store */ 46 struct address_space *local_store; /* local store mapping. */
47 struct address_space *mfc; /* 'mfc' area mappings. */
48 struct address_space *cntl; /* 'control' area mappings. */
49 struct address_space *signal1; /* 'signal1' area mappings. */
50 struct address_space *signal2; /* 'signal2' area mappings. */
47 51
48 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 52 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
49 struct rw_semaphore state_sema; 53 struct rw_semaphore state_sema;
@@ -55,13 +59,27 @@ struct spu_context {
55 wait_queue_head_t ibox_wq; 59 wait_queue_head_t ibox_wq;
56 wait_queue_head_t wbox_wq; 60 wait_queue_head_t wbox_wq;
57 wait_queue_head_t stop_wq; 61 wait_queue_head_t stop_wq;
62 wait_queue_head_t mfc_wq;
58 struct fasync_struct *ibox_fasync; 63 struct fasync_struct *ibox_fasync;
59 struct fasync_struct *wbox_fasync; 64 struct fasync_struct *wbox_fasync;
65 struct fasync_struct *mfc_fasync;
66 u32 tagwait;
60 struct spu_context_ops *ops; 67 struct spu_context_ops *ops;
61 struct work_struct reap_work; 68 struct work_struct reap_work;
62 u64 flags; 69 u64 flags;
63}; 70};
64 71
72struct mfc_dma_command {
73 int32_t pad; /* reserved */
74 uint32_t lsa; /* local storage address */
75 uint64_t ea; /* effective address */
76 uint16_t size; /* transfer size */
77 uint16_t tag; /* command tag */
78 uint16_t class; /* class ID */
79 uint16_t cmd; /* command opcode */
80};
81
82
65/* SPU context query/set operations. */ 83/* SPU context query/set operations. */
66struct spu_context_ops { 84struct spu_context_ops {
67 int (*mbox_read) (struct spu_context * ctx, u32 * data); 85 int (*mbox_read) (struct spu_context * ctx, u32 * data);
@@ -84,6 +102,11 @@ struct spu_context_ops {
84 char*(*get_ls) (struct spu_context * ctx); 102 char*(*get_ls) (struct spu_context * ctx);
85 void (*runcntl_write) (struct spu_context * ctx, u32 data); 103 void (*runcntl_write) (struct spu_context * ctx, u32 data);
86 void (*runcntl_stop) (struct spu_context * ctx); 104 void (*runcntl_stop) (struct spu_context * ctx);
105 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
106 u32 (*read_mfc_tagstatus)(struct spu_context * ctx);
107 u32 (*get_mfc_free_elements)(struct spu_context *ctx);
108 int (*send_mfc_command)(struct spu_context *ctx,
109 struct mfc_dma_command *cmd);
87}; 110};
88 111
89extern struct spu_context_ops spu_hw_ops; 112extern struct spu_context_ops spu_hw_ops;
@@ -106,7 +129,7 @@ long spufs_create_thread(struct nameidata *nd,
106extern struct file_operations spufs_context_fops; 129extern struct file_operations spufs_context_fops;
107 130
108/* context management */ 131/* context management */
109struct spu_context * alloc_spu_context(struct address_space *local_store); 132struct spu_context * alloc_spu_context(void);
110void destroy_spu_context(struct kref *kref); 133void destroy_spu_context(struct kref *kref);
111struct spu_context * get_spu_context(struct spu_context *ctx); 134struct spu_context * get_spu_context(struct spu_context *ctx);
112int put_spu_context(struct spu_context *ctx); 135int put_spu_context(struct spu_context *ctx);
@@ -159,5 +182,6 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
159void spufs_ibox_callback(struct spu *spu); 182void spufs_ibox_callback(struct spu *spu);
160void spufs_wbox_callback(struct spu *spu); 183void spufs_wbox_callback(struct spu *spu);
161void spufs_stop_callback(struct spu *spu); 184void spufs_stop_callback(struct spu *spu);
185void spufs_mfc_callback(struct spu *spu);
162 186
163#endif 187#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 212db28531fa..97898d5d34e5 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -2145,7 +2145,8 @@ static void init_priv1(struct spu_state *csa)
2145 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | 2145 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
2146 CLASS1_ENABLE_STORAGE_FAULT_INTR; 2146 CLASS1_ENABLE_STORAGE_FAULT_INTR;
2147 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR | 2147 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR |
2148 CLASS2_ENABLE_SPU_HALT_INTR; 2148 CLASS2_ENABLE_SPU_HALT_INTR |
2149 CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR;
2149} 2150}
2150 2151
2151static void init_priv2(struct spu_state *csa) 2152static void init_priv2(struct spu_state *csa)
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
index 814f54742e0f..63f0aee4c158 100644
--- a/arch/powerpc/platforms/chrp/chrp.h
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -8,4 +8,4 @@ extern int chrp_set_rtc_time(struct rtc_time *);
8extern long chrp_time_init(void); 8extern long chrp_time_init(void);
9 9
10extern void chrp_find_bridges(void); 10extern void chrp_find_bridges(void);
11extern void chrp_event_scan(void); 11extern void chrp_event_scan(unsigned long);
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 29c86781c493..6ad4b1a72c96 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/chrp_pegasos_eth.c
3 *
4 * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de> 2 * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
5 * Thanks to : 3 * Thanks to :
6 * Dale Farnsworth <dale@farnsworth.org> 4 * Dale Farnsworth <dale@farnsworth.org>
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index e1fadbf49150..23a201718704 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds 2 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas 3 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu) 4 * Modified by Cort Dougan (cort@cs.nmt.edu)
@@ -37,6 +35,7 @@
37#include <linux/root_dev.h> 35#include <linux/root_dev.h>
38#include <linux/initrd.h> 36#include <linux/initrd.h>
39#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/timer.h>
40 39
41#include <asm/io.h> 40#include <asm/io.h>
42#include <asm/pgtable.h> 41#include <asm/pgtable.h>
@@ -63,6 +62,10 @@ EXPORT_SYMBOL(_chrp_type);
63 62
64struct mpic *chrp_mpic; 63struct mpic *chrp_mpic;
65 64
65/* Used for doing CHRP event-scans */
66DEFINE_PER_CPU(struct timer_list, heartbeat_timer);
67unsigned long event_scan_interval;
68
66/* 69/*
67 * XXX this should be in xmon.h, but putting it there means xmon.h 70 * XXX this should be in xmon.h, but putting it there means xmon.h
68 * has to include <linux/interrupt.h> (to get irqreturn_t), which 71 * has to include <linux/interrupt.h> (to get irqreturn_t), which
@@ -231,8 +234,6 @@ void __init chrp_setup_arch(void)
231{ 234{
232 struct device_node *root = find_path_device ("/"); 235 struct device_node *root = find_path_device ("/");
233 char *machine = NULL; 236 char *machine = NULL;
234 struct device_node *device;
235 unsigned int *p = NULL;
236 237
237 /* init to some ~sane value until calibrate_delay() runs */ 238 /* init to some ~sane value until calibrate_delay() runs */
238 loops_per_jiffy = 50000000/HZ; 239 loops_per_jiffy = 50000000/HZ;
@@ -289,23 +290,12 @@ void __init chrp_setup_arch(void)
289 */ 290 */
290 sio_init(); 291 sio_init();
291 292
292 /* Get the event scan rate for the rtas so we know how
293 * often it expects a heartbeat. -- Cort
294 */
295 device = find_devices("rtas");
296 if (device)
297 p = (unsigned int *) get_property
298 (device, "rtas-event-scan-rate", NULL);
299 if (p && *p) {
300 ppc_md.heartbeat = chrp_event_scan;
301 ppc_md.heartbeat_reset = HZ / (*p * 30) - 1;
302 ppc_md.heartbeat_count = 1;
303 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
304 *p, ppc_md.heartbeat_reset);
305 }
306
307 pci_create_OF_bus_map(); 293 pci_create_OF_bus_map();
308 294
295#ifdef CONFIG_SMP
296 smp_ops = &chrp_smp_ops;
297#endif /* CONFIG_SMP */
298
309 /* 299 /*
310 * Print the banner, then scroll down so boot progress 300 * Print the banner, then scroll down so boot progress
311 * can be printed. -- Cort 301 * can be printed. -- Cort
@@ -314,7 +304,7 @@ void __init chrp_setup_arch(void)
314} 304}
315 305
316void 306void
317chrp_event_scan(void) 307chrp_event_scan(unsigned long unused)
318{ 308{
319 unsigned char log[1024]; 309 unsigned char log[1024];
320 int ret = 0; 310 int ret = 0;
@@ -322,7 +312,8 @@ chrp_event_scan(void)
322 /* XXX: we should loop until the hardware says no more error logs -- Cort */ 312 /* XXX: we should loop until the hardware says no more error logs -- Cort */
323 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, 313 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
324 __pa(log), 1024); 314 __pa(log), 1024);
325 ppc_md.heartbeat_count = ppc_md.heartbeat_reset; 315 mod_timer(&__get_cpu_var(heartbeat_timer),
316 jiffies + event_scan_interval);
326} 317}
327 318
328/* 319/*
@@ -467,6 +458,9 @@ void __init chrp_init_IRQ(void)
467void __init 458void __init
468chrp_init2(void) 459chrp_init2(void)
469{ 460{
461 struct device_node *device;
462 unsigned int *p = NULL;
463
470#ifdef CONFIG_NVRAM 464#ifdef CONFIG_NVRAM
471 chrp_nvram_init(); 465 chrp_nvram_init();
472#endif 466#endif
@@ -478,12 +472,53 @@ chrp_init2(void)
478 request_region(0x80,0x10,"dma page reg"); 472 request_region(0x80,0x10,"dma page reg");
479 request_region(0xc0,0x20,"dma2"); 473 request_region(0xc0,0x20,"dma2");
480 474
475 /* Get the event scan rate for the rtas so we know how
476 * often it expects a heartbeat. -- Cort
477 */
478 device = find_devices("rtas");
479 if (device)
480 p = (unsigned int *) get_property
481 (device, "rtas-event-scan-rate", NULL);
482 if (p && *p) {
483 /*
484 * Arrange to call chrp_event_scan at least *p times
485 * per minute. We use 59 rather than 60 here so that
486 * the rate will be slightly higher than the minimum.
487 * This all assumes we don't do hotplug CPU on any
488 * machine that needs the event scans done.
489 */
490 unsigned long interval, offset;
491 int cpu, ncpus;
492 struct timer_list *timer;
493
494 interval = HZ * 59 / *p;
495 offset = HZ;
496 ncpus = num_online_cpus();
497 event_scan_interval = ncpus * interval;
498 for (cpu = 0; cpu < ncpus; ++cpu) {
499 timer = &per_cpu(heartbeat_timer, cpu);
500 setup_timer(timer, chrp_event_scan, 0);
501 timer->expires = jiffies + offset;
502 add_timer_on(timer, cpu);
503 offset += interval;
504 }
505 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
506 *p, interval);
507 }
508
481 if (ppc_md.progress) 509 if (ppc_md.progress)
482 ppc_md.progress(" Have fun! ", 0x7777); 510 ppc_md.progress(" Have fun! ", 0x7777);
483} 511}
484 512
485void __init chrp_init(void) 513static int __init chrp_probe(void)
486{ 514{
515 char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
516 "device_type", NULL);
517 if (dtype == NULL)
518 return 0;
519 if (strcmp(dtype, "chrp"))
520 return 0;
521
487 ISA_DMA_THRESHOLD = ~0L; 522 ISA_DMA_THRESHOLD = ~0L;
488 DMA_MODE_READ = 0x44; 523 DMA_MODE_READ = 0x44;
489 DMA_MODE_WRITE = 0x48; 524 DMA_MODE_WRITE = 0x48;
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 78df2e7ca88a..7d7889026936 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/chrp_time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 2 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 * 3 *
6 * Adapted for PowerPC (PReP) by Gary Thomas 4 * Adapted for PowerPC (PReP) by Gary Thomas
@@ -122,33 +120,15 @@ int chrp_set_rtc_time(struct rtc_time *tmarg)
122void chrp_get_rtc_time(struct rtc_time *tm) 120void chrp_get_rtc_time(struct rtc_time *tm)
123{ 121{
124 unsigned int year, mon, day, hour, min, sec; 122 unsigned int year, mon, day, hour, min, sec;
125 int uip, i;
126
127 /* The Linux interpretation of the CMOS clock register contents:
128 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
129 * RTC registers show the second which has precisely just started.
130 * Let's hope other operating systems interpret the RTC the same way.
131 */
132 123
133 /* Since the UIP flag is set for about 2.2 ms and the clock 124 do {
134 * is typically written with a precision of 1 jiffy, trying
135 * to obtain a precision better than a few milliseconds is
136 * an illusion. Only consistency is interesting, this also
137 * allows to use the routine for /dev/rtc without a potential
138 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
139 */
140
141 for ( i = 0; i<1000000; i++) {
142 uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
143 sec = chrp_cmos_clock_read(RTC_SECONDS); 125 sec = chrp_cmos_clock_read(RTC_SECONDS);
144 min = chrp_cmos_clock_read(RTC_MINUTES); 126 min = chrp_cmos_clock_read(RTC_MINUTES);
145 hour = chrp_cmos_clock_read(RTC_HOURS); 127 hour = chrp_cmos_clock_read(RTC_HOURS);
146 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); 128 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
147 mon = chrp_cmos_clock_read(RTC_MONTH); 129 mon = chrp_cmos_clock_read(RTC_MONTH);
148 year = chrp_cmos_clock_read(RTC_YEAR); 130 year = chrp_cmos_clock_read(RTC_YEAR);
149 uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT); 131 } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
150 if ((uip & RTC_UIP)==0) break;
151 }
152 132
153 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 133 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
154 BCD_TO_BIN(sec); 134 BCD_TO_BIN(sec);
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index a41d8b78c0cd..d771b8ee857d 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -46,6 +46,7 @@
46#include "setup.h" 46#include "setup.h"
47 47
48extern int piranha_simulator; 48extern int piranha_simulator;
49static int mf_initialized;
49 50
50/* 51/*
51 * This is the structure layout for the Machine Facilites LPAR event 52 * This is the structure layout for the Machine Facilites LPAR event
@@ -143,7 +144,8 @@ static spinlock_t pending_event_spinlock;
143static struct pending_event *pending_event_head; 144static struct pending_event *pending_event_head;
144static struct pending_event *pending_event_tail; 145static struct pending_event *pending_event_tail;
145static struct pending_event *pending_event_avail; 146static struct pending_event *pending_event_avail;
146static struct pending_event pending_event_prealloc[16]; 147#define PENDING_EVENT_PREALLOC_LEN 16
148static struct pending_event pending_event_prealloc[PENDING_EVENT_PREALLOC_LEN];
147 149
148/* 150/*
149 * Put a pending event onto the available queue, so it can get reused. 151 * Put a pending event onto the available queue, so it can get reused.
@@ -597,7 +599,7 @@ void mf_power_off(void)
597 * Global kernel interface to tell the VSP object in the primary 599 * Global kernel interface to tell the VSP object in the primary
598 * partition to reboot this partition. 600 * partition to reboot this partition.
599 */ 601 */
600void mf_reboot(void) 602void mf_reboot(char *cmd)
601{ 603{
602 printk(KERN_INFO "mf.c: Preparing to bounce...\n"); 604 printk(KERN_INFO "mf.c: Preparing to bounce...\n");
603 signal_ce_msg_simple(0x4e, NULL); 605 signal_ce_msg_simple(0x4e, NULL);
@@ -625,7 +627,7 @@ void mf_display_src(u32 word)
625/* 627/*
626 * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. 628 * Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
627 */ 629 */
628void mf_display_progress(u16 value) 630static __init void mf_display_progress_src(u16 value)
629{ 631{
630 u8 ce[12]; 632 u8 ce[12];
631 u8 src[72]; 633 u8 src[72];
@@ -649,30 +651,42 @@ void mf_display_progress(u16 value)
649 * Clear the VSP control panel. Used to "erase" an SRC that was 651 * Clear the VSP control panel. Used to "erase" an SRC that was
650 * previously displayed. 652 * previously displayed.
651 */ 653 */
652void mf_clear_src(void) 654static void mf_clear_src(void)
653{ 655{
654 signal_ce_msg_simple(0x4b, NULL); 656 signal_ce_msg_simple(0x4b, NULL);
655} 657}
656 658
659void __init mf_display_progress(u16 value)
660{
661 if (piranha_simulator || !mf_initialized)
662 return;
663
664 if (0xFFFF == value)
665 mf_clear_src();
666 else
667 mf_display_progress_src(value);
668}
669
657/* 670/*
658 * Initialization code here. 671 * Initialization code here.
659 */ 672 */
660void mf_init(void) 673void __init mf_init(void)
661{ 674{
662 int i; 675 int i;
663 676
664 /* initialize */
665 spin_lock_init(&pending_event_spinlock); 677 spin_lock_init(&pending_event_spinlock);
666 for (i = 0; 678
667 i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc); 679 for (i = 0; i < PENDING_EVENT_PREALLOC_LEN; i++)
668 ++i)
669 free_pending_event(&pending_event_prealloc[i]); 680 free_pending_event(&pending_event_prealloc[i]);
681
670 HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler); 682 HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler);
671 683
672 /* virtual continue ack */ 684 /* virtual continue ack */
673 signal_ce_msg_simple(0x57, NULL); 685 signal_ce_msg_simple(0x57, NULL);
674 686
675 /* initialization complete */ 687 mf_initialized = 1;
688 mb();
689
676 printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities " 690 printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities "
677 "initialized\n"); 691 "initialized\n");
678} 692}
@@ -692,6 +706,43 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
692 complete(&rtc->com); 706 complete(&rtc->com);
693} 707}
694 708
709static int mf_set_rtc(struct rtc_time *tm)
710{
711 char ce_time[12];
712 u8 day, mon, hour, min, sec, y1, y2;
713 unsigned year;
714
715 year = 1900 + tm->tm_year;
716 y1 = year / 100;
717 y2 = year % 100;
718
719 sec = tm->tm_sec;
720 min = tm->tm_min;
721 hour = tm->tm_hour;
722 day = tm->tm_mday;
723 mon = tm->tm_mon + 1;
724
725 BIN_TO_BCD(sec);
726 BIN_TO_BCD(min);
727 BIN_TO_BCD(hour);
728 BIN_TO_BCD(mon);
729 BIN_TO_BCD(day);
730 BIN_TO_BCD(y1);
731 BIN_TO_BCD(y2);
732
733 memset(ce_time, 0, sizeof(ce_time));
734 ce_time[3] = 0x41;
735 ce_time[4] = y1;
736 ce_time[5] = y2;
737 ce_time[6] = sec;
738 ce_time[7] = min;
739 ce_time[8] = hour;
740 ce_time[10] = day;
741 ce_time[11] = mon;
742
743 return signal_ce_msg(ce_time, NULL);
744}
745
695static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) 746static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
696{ 747{
697 tm->tm_wday = 0; 748 tm->tm_wday = 0;
@@ -747,7 +798,7 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
747 return 0; 798 return 0;
748} 799}
749 800
750int mf_get_rtc(struct rtc_time *tm) 801static int mf_get_rtc(struct rtc_time *tm)
751{ 802{
752 struct ce_msg_comp_data ce_complete; 803 struct ce_msg_comp_data ce_complete;
753 struct rtc_time_data rtc_data; 804 struct rtc_time_data rtc_data;
@@ -780,7 +831,7 @@ static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
780 rtc->busy = 0; 831 rtc->busy = 0;
781} 832}
782 833
783int mf_get_boot_rtc(struct rtc_time *tm) 834static int mf_get_boot_rtc(struct rtc_time *tm)
784{ 835{
785 struct ce_msg_comp_data ce_complete; 836 struct ce_msg_comp_data ce_complete;
786 struct boot_rtc_time_data rtc_data; 837 struct boot_rtc_time_data rtc_data;
@@ -802,43 +853,6 @@ int mf_get_boot_rtc(struct rtc_time *tm)
802 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); 853 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
803} 854}
804 855
805int mf_set_rtc(struct rtc_time *tm)
806{
807 char ce_time[12];
808 u8 day, mon, hour, min, sec, y1, y2;
809 unsigned year;
810
811 year = 1900 + tm->tm_year;
812 y1 = year / 100;
813 y2 = year % 100;
814
815 sec = tm->tm_sec;
816 min = tm->tm_min;
817 hour = tm->tm_hour;
818 day = tm->tm_mday;
819 mon = tm->tm_mon + 1;
820
821 BIN_TO_BCD(sec);
822 BIN_TO_BCD(min);
823 BIN_TO_BCD(hour);
824 BIN_TO_BCD(mon);
825 BIN_TO_BCD(day);
826 BIN_TO_BCD(y1);
827 BIN_TO_BCD(y2);
828
829 memset(ce_time, 0, sizeof(ce_time));
830 ce_time[3] = 0x41;
831 ce_time[4] = y1;
832 ce_time[5] = y2;
833 ce_time[6] = sec;
834 ce_time[7] = min;
835 ce_time[8] = hour;
836 ce_time[10] = day;
837 ce_time[11] = mon;
838
839 return signal_ce_msg(ce_time, NULL);
840}
841
842#ifdef CONFIG_PROC_FS 856#ifdef CONFIG_PROC_FS
843 857
844static int proc_mf_dump_cmdline(char *page, char **start, off_t off, 858static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3ecc4a652d82..6ce8a404ba6b 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -50,6 +50,7 @@
50#include <asm/iseries/hv_call_xm.h> 50#include <asm/iseries/hv_call_xm.h>
51#include <asm/iseries/it_lp_queue.h> 51#include <asm/iseries/it_lp_queue.h>
52#include <asm/iseries/mf.h> 52#include <asm/iseries/mf.h>
53#include <asm/iseries/it_exp_vpd_panel.h>
53#include <asm/iseries/hv_lp_event.h> 54#include <asm/iseries/hv_lp_event.h>
54#include <asm/iseries/lpar_map.h> 55#include <asm/iseries/lpar_map.h>
55#include <asm/udbg.h> 56#include <asm/udbg.h>
@@ -89,8 +90,6 @@ extern unsigned long embedded_sysmap_end;
89extern unsigned long iSeries_recal_tb; 90extern unsigned long iSeries_recal_tb;
90extern unsigned long iSeries_recal_titan; 91extern unsigned long iSeries_recal_titan;
91 92
92static int mf_initialized;
93
94static unsigned long cmd_mem_limit; 93static unsigned long cmd_mem_limit;
95 94
96struct MemoryBlock { 95struct MemoryBlock {
@@ -303,8 +302,6 @@ static void __init iSeries_init_early(void)
303{ 302{
304 DBG(" -> iSeries_init_early()\n"); 303 DBG(" -> iSeries_init_early()\n");
305 304
306 ppc64_firmware_features = FW_FEATURE_ISERIES;
307
308 ppc64_interrupt_controller = IC_ISERIES; 305 ppc64_interrupt_controller = IC_ISERIES;
309 306
310#if defined(CONFIG_BLK_DEV_INITRD) 307#if defined(CONFIG_BLK_DEV_INITRD)
@@ -349,8 +346,6 @@ static void __init iSeries_init_early(void)
349 HvCallEvent_setLpEventQueueInterruptProc(0, 0); 346 HvCallEvent_setLpEventQueueInterruptProc(0, 0);
350 347
351 mf_init(); 348 mf_init();
352 mf_initialized = 1;
353 mb();
354 349
355 /* If we were passed an initrd, set the ROOT_DEV properly if the values 350 /* If we were passed an initrd, set the ROOT_DEV properly if the values
356 * look sensible. If not, clear initrd reference. 351 * look sensible. If not, clear initrd reference.
@@ -560,39 +555,10 @@ static void iSeries_show_cpuinfo(struct seq_file *m)
560 seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n"); 555 seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
561} 556}
562 557
563/*
564 * Document me.
565 */
566static void iSeries_restart(char *cmd)
567{
568 mf_reboot();
569}
570
571/*
572 * Document me.
573 */
574static void iSeries_power_off(void)
575{
576 mf_power_off();
577}
578
579/*
580 * Document me.
581 */
582static void iSeries_halt(void)
583{
584 mf_power_off();
585}
586
587static void __init iSeries_progress(char * st, unsigned short code) 558static void __init iSeries_progress(char * st, unsigned short code)
588{ 559{
589 printk("Progress: [%04x] - %s\n", (unsigned)code, st); 560 printk("Progress: [%04x] - %s\n", (unsigned)code, st);
590 if (!piranha_simulator && mf_initialized) { 561 mf_display_progress(code);
591 if (code != 0xffff)
592 mf_display_progress(code);
593 else
594 mf_clear_src();
595 }
596} 562}
597 563
598static void __init iSeries_fixup_klimit(void) 564static void __init iSeries_fixup_klimit(void)
@@ -709,21 +675,29 @@ static void iseries_dedicated_idle(void)
709void __init iSeries_init_IRQ(void) { } 675void __init iSeries_init_IRQ(void) { }
710#endif 676#endif
711 677
712static int __init iseries_probe(int platform) 678static int __init iseries_probe(void)
713{ 679{
714 return PLATFORM_ISERIES_LPAR == platform; 680 unsigned long root = of_get_flat_dt_root();
681 if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
682 return 0;
683
684 powerpc_firmware_features |= FW_FEATURE_ISERIES;
685 powerpc_firmware_features |= FW_FEATURE_LPAR;
686
687 return 1;
715} 688}
716 689
717struct machdep_calls __initdata iseries_md = { 690define_machine(iseries) {
691 .name = "iSeries",
718 .setup_arch = iSeries_setup_arch, 692 .setup_arch = iSeries_setup_arch,
719 .show_cpuinfo = iSeries_show_cpuinfo, 693 .show_cpuinfo = iSeries_show_cpuinfo,
720 .init_IRQ = iSeries_init_IRQ, 694 .init_IRQ = iSeries_init_IRQ,
721 .get_irq = iSeries_get_irq, 695 .get_irq = iSeries_get_irq,
722 .init_early = iSeries_init_early, 696 .init_early = iSeries_init_early,
723 .pcibios_fixup = iSeries_pci_final_fixup, 697 .pcibios_fixup = iSeries_pci_final_fixup,
724 .restart = iSeries_restart, 698 .restart = mf_reboot,
725 .power_off = iSeries_power_off, 699 .power_off = mf_power_off,
726 .halt = iSeries_halt, 700 .halt = mf_power_off,
727 .get_boot_time = iSeries_get_boot_time, 701 .get_boot_time = iSeries_get_boot_time,
728 .set_rtc_time = iSeries_set_rtc_time, 702 .set_rtc_time = iSeries_set_rtc_time,
729 .get_rtc_time = iSeries_get_rtc_time, 703 .get_rtc_time = iSeries_get_rtc_time,
@@ -917,6 +891,24 @@ void dt_cpus(struct iseries_flat_dt *dt)
917 dt_end_node(dt); 891 dt_end_node(dt);
918} 892}
919 893
894void dt_model(struct iseries_flat_dt *dt)
895{
896 char buf[16] = "IBM,";
897
898 /* "IBM," + mfgId[2:3] + systemSerial[1:5] */
899 strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
900 strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
901 buf[11] = '\0';
902 dt_prop_str(dt, "system-id", buf);
903
904 /* "IBM," + machineType[0:4] */
905 strne2a(buf + 4, xItExtVpdPanel.machineType, 4);
906 buf[8] = '\0';
907 dt_prop_str(dt, "model", buf);
908
909 dt_prop_str(dt, "compatible", "IBM,iSeries");
910}
911
920void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) 912void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
921{ 913{
922 u64 tmp[2]; 914 u64 tmp[2];
@@ -927,6 +919,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
927 919
928 dt_prop_u32(dt, "#address-cells", 2); 920 dt_prop_u32(dt, "#address-cells", 2);
929 dt_prop_u32(dt, "#size-cells", 2); 921 dt_prop_u32(dt, "#size-cells", 2);
922 dt_model(dt);
930 923
931 /* /memory */ 924 /* /memory */
932 dt_start_node(dt, "memory@0"); 925 dt_start_node(dt, "memory@0");
@@ -939,7 +932,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
939 932
940 /* /chosen */ 933 /* /chosen */
941 dt_start_node(dt, "chosen"); 934 dt_start_node(dt, "chosen");
942 dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); 935 dt_prop_str(dt, "bootargs", cmd_line);
943 if (cmd_mem_limit) 936 if (cmd_mem_limit)
944 dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); 937 dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
945 dt_end_node(dt); 938 dt_end_node(dt);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ec5c1e10c407..24c0aef4ea39 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -259,9 +259,10 @@ static void __init maple_progress(char *s, unsigned short hex)
259/* 259/*
260 * Called very early, MMU is off, device-tree isn't unflattened 260 * Called very early, MMU is off, device-tree isn't unflattened
261 */ 261 */
262static int __init maple_probe(int platform) 262static int __init maple_probe(void)
263{ 263{
264 if (platform != PLATFORM_MAPLE) 264 unsigned long root = of_get_flat_dt_root();
265 if (!of_flat_dt_is_compatible(root, "Momentum,Maple"))
265 return 0; 266 return 0;
266 /* 267 /*
267 * On U3, the DART (iommu) must be allocated now since it 268 * On U3, the DART (iommu) must be allocated now since it
@@ -274,7 +275,8 @@ static int __init maple_probe(int platform)
274 return 1; 275 return 1;
275} 276}
276 277
277struct machdep_calls __initdata maple_md = { 278define_machine(maple_md) {
279 .name = "Maple",
278 .probe = maple_probe, 280 .probe = maple_probe,
279 .setup_arch = maple_setup_arch, 281 .setup_arch = maple_setup_arch,
280 .init_early = maple_init_early, 282 .init_early = maple_init_early,
@@ -290,7 +292,7 @@ struct machdep_calls __initdata maple_md = {
290 .get_rtc_time = maple_get_rtc_time, 292 .get_rtc_time = maple_get_rtc_time,
291 .calibrate_decr = generic_calibrate_decr, 293 .calibrate_decr = generic_calibrate_decr,
292 .progress = maple_progress, 294 .progress = maple_progress,
293 .idle_loop = native_idle, 295 .power_save = power4_idle,
294#ifdef CONFIG_KEXEC 296#ifdef CONFIG_KEXEC
295 .machine_kexec = default_machine_kexec, 297 .machine_kexec = default_machine_kexec,
296 .machine_kexec_prepare = default_machine_kexec_prepare, 298 .machine_kexec_prepare = default_machine_kexec_prepare,
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 50bc4eb85353..b9a2b3d4bf33 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/maple_time.c
3 *
4 * (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org), 2 * (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
5 * IBM Corp. 3 * IBM Corp.
6 * 4 *
@@ -62,34 +60,14 @@ static void maple_clock_write(unsigned long val, int addr)
62 60
63void maple_get_rtc_time(struct rtc_time *tm) 61void maple_get_rtc_time(struct rtc_time *tm)
64{ 62{
65 int uip, i; 63 do {
66
67 /* The Linux interpretation of the CMOS clock register contents:
68 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
69 * RTC registers show the second which has precisely just started.
70 * Let's hope other operating systems interpret the RTC the same way.
71 */
72
73 /* Since the UIP flag is set for about 2.2 ms and the clock
74 * is typically written with a precision of 1 jiffy, trying
75 * to obtain a precision better than a few milliseconds is
76 * an illusion. Only consistency is interesting, this also
77 * allows to use the routine for /dev/rtc without a potential
78 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
79 */
80
81 for (i = 0; i<1000000; i++) {
82 uip = maple_clock_read(RTC_FREQ_SELECT);
83 tm->tm_sec = maple_clock_read(RTC_SECONDS); 64 tm->tm_sec = maple_clock_read(RTC_SECONDS);
84 tm->tm_min = maple_clock_read(RTC_MINUTES); 65 tm->tm_min = maple_clock_read(RTC_MINUTES);
85 tm->tm_hour = maple_clock_read(RTC_HOURS); 66 tm->tm_hour = maple_clock_read(RTC_HOURS);
86 tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH); 67 tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
87 tm->tm_mon = maple_clock_read(RTC_MONTH); 68 tm->tm_mon = maple_clock_read(RTC_MONTH);
88 tm->tm_year = maple_clock_read(RTC_YEAR); 69 tm->tm_year = maple_clock_read(RTC_YEAR);
89 uip |= maple_clock_read(RTC_FREQ_SELECT); 70 } while (tm->tm_sec != maple_clock_read(RTC_SECONDS));
90 if ((uip & RTC_UIP)==0)
91 break;
92 }
93 71
94 if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY) 72 if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
95 || RTC_ALWAYS_BCD) { 73 || RTC_ALWAYS_BCD) {
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index fa8b4d7b5ded..eacbfd9beabc 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -161,9 +161,7 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size,
161static void __init bootx_add_chosen_props(unsigned long base, 161static void __init bootx_add_chosen_props(unsigned long base,
162 unsigned long *mem_end) 162 unsigned long *mem_end)
163{ 163{
164 u32 val = _MACH_Pmac; 164 u32 val;
165
166 bootx_dt_add_prop("linux,platform", &val, 4, mem_end);
167 165
168 if (bootx_info->kernelParamsOffset) { 166 if (bootx_info->kernelParamsOffset) {
169 char *args = (char *)((unsigned long)bootx_info) + 167 char *args = (char *)((unsigned long)bootx_info) +
@@ -493,7 +491,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
493 && (strcmp(model, "iMac,1") == 0 491 && (strcmp(model, "iMac,1") == 0
494 || strcmp(model, "PowerMac1,1") == 0)) { 492 || strcmp(model, "PowerMac1,1") == 0)) {
495 bootx_printf("iMac,1 detected, shutting down USB \n"); 493 bootx_printf("iMac,1 detected, shutting down USB \n");
496 out_le32((unsigned *)0x80880008, 1); /* XXX */ 494 out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */
497 } 495 }
498 } 496 }
499 497
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 56fd4e05fede..cfd6527a0d7e 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/pmac_cpufreq.c
3 *
4 * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> 2 * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 * Copyright (C) 2004 John Steele Scott <toojays@toojays.net> 3 * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
6 * 4 *
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index a415e8d2f7af..b57e465a1b71 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -21,6 +21,7 @@
21#include <linux/cpufreq.h> 21#include <linux/cpufreq.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/completion.h> 23#include <linux/completion.h>
24#include <linux/mutex.h>
24#include <asm/prom.h> 25#include <asm/prom.h>
25#include <asm/machdep.h> 26#include <asm/machdep.h>
26#include <asm/irq.h> 27#include <asm/irq.h>
@@ -90,7 +91,7 @@ static void (*g5_switch_volt)(int speed_mode);
90static int (*g5_switch_freq)(int speed_mode); 91static int (*g5_switch_freq)(int speed_mode);
91static int (*g5_query_freq)(void); 92static int (*g5_query_freq)(void);
92 93
93static DECLARE_MUTEX(g5_switch_mutex); 94static DEFINE_MUTEX(g5_switch_mutex);
94 95
95 96
96static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ 97static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -327,7 +328,7 @@ static int g5_cpufreq_target(struct cpufreq_policy *policy,
327 if (g5_pmode_cur == newstate) 328 if (g5_pmode_cur == newstate)
328 return 0; 329 return 0;
329 330
330 down(&g5_switch_mutex); 331 mutex_lock(&g5_switch_mutex);
331 332
332 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; 333 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
333 freqs.new = g5_cpu_freqs[newstate].frequency; 334 freqs.new = g5_cpu_freqs[newstate].frequency;
@@ -337,7 +338,7 @@ static int g5_cpufreq_target(struct cpufreq_policy *policy,
337 rc = g5_switch_freq(newstate); 338 rc = g5_switch_freq(newstate);
338 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 339 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
339 340
340 up(&g5_switch_mutex); 341 mutex_unlock(&g5_switch_mutex);
341 342
342 return rc; 343 return rc;
343} 344}
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 34714d3ea69a..a5063cd675c5 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/pmac_feature.c
3 *
4 * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au) 2 * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
5 * Ben. Herrenschmidt (benh@kernel.crashing.org) 3 * Ben. Herrenschmidt (benh@kernel.crashing.org)
6 * 4 *
@@ -2491,9 +2489,7 @@ found:
2491 pmac_mb.model_id = PMAC_TYPE_COMET; 2489 pmac_mb.model_id = PMAC_TYPE_COMET;
2492 iounmap(mach_id_ptr); 2490 iounmap(mach_id_ptr);
2493 } 2491 }
2494#endif /* CONFIG_POWER4 */
2495 2492
2496#ifdef CONFIG_6xx
2497 /* Set default value of powersave_nap on machines that support it. 2493 /* Set default value of powersave_nap on machines that support it.
2498 * It appears that uninorth rev 3 has a problem with it, we don't 2494 * It appears that uninorth rev 3 has a problem with it, we don't
2499 * enable it on those. In theory, the flush-on-lock property is 2495 * enable it on those. In theory, the flush-on-lock property is
@@ -2522,10 +2518,11 @@ found:
2522 * NAP mode 2518 * NAP mode
2523 */ 2519 */
2524 powersave_lowspeed = 1; 2520 powersave_lowspeed = 1;
2525#endif /* CONFIG_6xx */ 2521
2526#ifdef CONFIG_POWER4 2522#else /* CONFIG_POWER4 */
2527 powersave_nap = 1; 2523 powersave_nap = 1;
2528#endif 2524#endif /* CONFIG_POWER4 */
2525
2529 /* Check for "mobile" machine */ 2526 /* Check for "mobile" machine */
2530 if (model && (strncmp(model, "PowerBook", 9) == 0 2527 if (model && (strncmp(model, "PowerBook", 9) == 0
2531 || strncmp(model, "iBook", 5) == 0)) 2528 || strncmp(model, "iBook", 5) == 0))
@@ -2954,7 +2951,7 @@ static void *pmac_early_vresume_data;
2954 2951
2955void pmac_set_early_video_resume(void (*proc)(void *data), void *data) 2952void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
2956{ 2953{
2957 if (_machine != _MACH_Pmac) 2954 if (!machine_is(powermac))
2958 return; 2955 return;
2959 preempt_disable(); 2956 preempt_disable();
2960 pmac_early_vresume_proc = proc; 2957 pmac_early_vresume_proc = proc;
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 87eb6bb7f0e7..e14f9ac55cf4 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1457,6 +1457,9 @@ int __init pmac_i2c_init(void)
1457 return 0; 1457 return 0;
1458 i2c_inited = 1; 1458 i2c_inited = 1;
1459 1459
1460 if (!machine_is(powermac))
1461 return 0;
1462
1460 /* Probe keywest-i2c busses */ 1463 /* Probe keywest-i2c busses */
1461 kw_i2c_probe(); 1464 kw_i2c_probe();
1462 1465
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 3ebd045a3350..262f967b880a 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/platforms/pmac_nvram.c
3 *
4 * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org) 2 * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
5 * 3 *
6 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
@@ -76,7 +74,7 @@ struct core99_header {
76 * Read and write the non-volatile RAM on PowerMacs and CHRP machines. 74 * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
77 */ 75 */
78static int nvram_naddrs; 76static int nvram_naddrs;
79static volatile unsigned char *nvram_data; 77static volatile unsigned char __iomem *nvram_data;
80static int is_core_99; 78static int is_core_99;
81static int core99_bank = 0; 79static int core99_bank = 0;
82static int nvram_partitions[3]; 80static int nvram_partitions[3];
@@ -150,7 +148,7 @@ static ssize_t core99_nvram_size(void)
150} 148}
151 149
152#ifdef CONFIG_PPC32 150#ifdef CONFIG_PPC32
153static volatile unsigned char *nvram_addr; 151static volatile unsigned char __iomem *nvram_addr;
154static int nvram_mult; 152static int nvram_mult;
155 153
156static unsigned char direct_nvram_read_byte(int addr) 154static unsigned char direct_nvram_read_byte(int addr)
@@ -287,7 +285,7 @@ static int sm_erase_bank(int bank)
287 int stat, i; 285 int stat, i;
288 unsigned long timeout; 286 unsigned long timeout;
289 287
290 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 288 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
291 289
292 DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); 290 DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
293 291
@@ -319,7 +317,7 @@ static int sm_write_bank(int bank, u8* datas)
319 int i, stat = 0; 317 int i, stat = 0;
320 unsigned long timeout; 318 unsigned long timeout;
321 319
322 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 320 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
323 321
324 DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); 322 DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
325 323
@@ -354,7 +352,7 @@ static int amd_erase_bank(int bank)
354 int i, stat = 0; 352 int i, stat = 0;
355 unsigned long timeout; 353 unsigned long timeout;
356 354
357 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 355 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
358 356
359 DBG("nvram: AMD Erasing bank %d...\n", bank); 357 DBG("nvram: AMD Erasing bank %d...\n", bank);
360 358
@@ -401,7 +399,7 @@ static int amd_write_bank(int bank, u8* datas)
401 int i, stat = 0; 399 int i, stat = 0;
402 unsigned long timeout; 400 unsigned long timeout;
403 401
404 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 402 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
405 403
406 DBG("nvram: AMD Writing bank %d...\n", bank); 404 DBG("nvram: AMD Writing bank %d...\n", bank);
407 405
@@ -599,7 +597,7 @@ int __init pmac_nvram_init(void)
599 } 597 }
600 598
601#ifdef CONFIG_PPC32 599#ifdef CONFIG_PPC32
602 if (_machine == _MACH_chrp && nvram_naddrs == 1) { 600 if (machine_is(chrp) && nvram_naddrs == 1) {
603 nvram_data = ioremap(r1.start, s1); 601 nvram_data = ioremap(r1.start, s1);
604 nvram_mult = 1; 602 nvram_mult = 1;
605 ppc_md.nvram_read_val = direct_nvram_read_byte; 603 ppc_md.nvram_read_val = direct_nvram_read_byte;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index de3f30e6b333..f5d8d15d74fa 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1201,7 +1201,7 @@ void __init pmac_pcibios_after_init(void)
1201#ifdef CONFIG_PPC32 1201#ifdef CONFIG_PPC32
1202void pmac_pci_fixup_cardbus(struct pci_dev* dev) 1202void pmac_pci_fixup_cardbus(struct pci_dev* dev)
1203{ 1203{
1204 if (_machine != _MACH_Pmac) 1204 if (!machine_is(powermac))
1205 return; 1205 return;
1206 /* 1206 /*
1207 * Fix the interrupt routing on the various cardbus bridges 1207 * Fix the interrupt routing on the various cardbus bridges
@@ -1244,8 +1244,9 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev)
1244 * On PowerMacs, we try to switch any PCI ATA controller to 1244 * On PowerMacs, we try to switch any PCI ATA controller to
1245 * fully native mode 1245 * fully native mode
1246 */ 1246 */
1247 if (_machine != _MACH_Pmac) 1247 if (!machine_is(powermac))
1248 return; 1248 return;
1249
1249 /* Some controllers don't have the class IDE */ 1250 /* Some controllers don't have the class IDE */
1250 if (dev->vendor == PCI_VENDOR_ID_PROMISE) 1251 if (dev->vendor == PCI_VENDOR_ID_PROMISE)
1251 switch(dev->device) { 1252 switch(dev->device) {
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index 9b7150f10414..a3bd3e728fa3 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -336,6 +336,8 @@ int __init pmac_pfunc_base_install(void)
336 return 0; 336 return 0;
337 pfbase_inited = 1; 337 pfbase_inited = 1;
338 338
339 if (!machine_is(powermac))
340 return 0;
339 341
340 DBG("Installing base platform functions...\n"); 342 DBG("Installing base platform functions...\n");
341 343
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 1955462f4082..4d15e396655c 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -86,11 +86,10 @@ int ppc_override_l2cr = 0;
86int ppc_override_l2cr_value; 86int ppc_override_l2cr_value;
87int has_l2cache = 0; 87int has_l2cache = 0;
88 88
89int pmac_newworld = 1; 89int pmac_newworld;
90 90
91static int current_root_goodness = -1; 91static int current_root_goodness = -1;
92 92
93extern int pmac_newworld;
94extern struct machdep_calls pmac_md; 93extern struct machdep_calls pmac_md;
95 94
96#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ 95#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
@@ -308,9 +307,10 @@ static void __init pmac_setup_arch(void)
308 for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) 307 for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
309 if (get_property(ic, "interrupt-controller", NULL)) 308 if (get_property(ic, "interrupt-controller", NULL))
310 break; 309 break;
311 pmac_newworld = (ic != NULL); 310 if (ic) {
312 if (ic) 311 pmac_newworld = 1;
313 of_node_put(ic); 312 of_node_put(ic);
313 }
314 314
315 /* Lookup PCI hosts */ 315 /* Lookup PCI hosts */
316 pmac_pci_init(); 316 pmac_pci_init();
@@ -350,6 +350,13 @@ static void __init pmac_setup_arch(void)
350 smp_ops = &psurge_smp_ops; 350 smp_ops = &psurge_smp_ops;
351#endif 351#endif
352#endif /* CONFIG_SMP */ 352#endif /* CONFIG_SMP */
353
354#ifdef CONFIG_ADB
355 if (strstr(cmd_line, "adb_sync")) {
356 extern int __adb_probe_sync;
357 __adb_probe_sync = 1;
358 }
359#endif /* CONFIG_ADB */
353} 360}
354 361
355char *bootpath; 362char *bootpath;
@@ -576,30 +583,6 @@ pmac_halt(void)
576 pmac_power_off(); 583 pmac_power_off();
577} 584}
578 585
579#ifdef CONFIG_PPC32
580void __init pmac_init(void)
581{
582 /* isa_io_base gets set in pmac_pci_init */
583 isa_mem_base = PMAC_ISA_MEM_BASE;
584 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
585 ISA_DMA_THRESHOLD = ~0L;
586 DMA_MODE_READ = 1;
587 DMA_MODE_WRITE = 2;
588
589 ppc_md = pmac_md;
590
591#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
592#ifdef CONFIG_BLK_DEV_IDE_PMAC
593 ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
594 ppc_ide_md.default_io_base = pmac_ide_get_base;
595#endif /* CONFIG_BLK_DEV_IDE_PMAC */
596#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
597
598 if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
599
600}
601#endif
602
603/* 586/*
604 * Early initialization. 587 * Early initialization.
605 */ 588 */
@@ -621,10 +604,6 @@ static void __init pmac_init_early(void)
621 /* Probe motherboard chipset */ 604 /* Probe motherboard chipset */
622 pmac_feature_init(); 605 pmac_feature_init();
623 606
624 /* We can NAP */
625 powersave_nap = 1;
626 printk(KERN_INFO "Using native/NAP idle loop\n");
627
628 /* Initialize debug stuff */ 607 /* Initialize debug stuff */
629 udbg_scc_init(!!strstr(cmd_line, "sccdbg")); 608 udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
630 udbg_adb_init(!!strstr(cmd_line, "btextdbg")); 609 udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
@@ -650,6 +629,12 @@ static int __init pmac_declare_of_platform_devices(void)
650{ 629{
651 struct device_node *np; 630 struct device_node *np;
652 631
632 if (machine_is(chrp))
633 return -1;
634
635 if (!machine_is(powermac))
636 return 0;
637
653 np = of_find_node_by_name(NULL, "valkyrie"); 638 np = of_find_node_by_name(NULL, "valkyrie");
654 if (np) 639 if (np)
655 of_platform_device_create(np, "valkyrie", NULL); 640 of_platform_device_create(np, "valkyrie", NULL);
@@ -670,12 +655,15 @@ device_initcall(pmac_declare_of_platform_devices);
670/* 655/*
671 * Called very early, MMU is off, device-tree isn't unflattened 656 * Called very early, MMU is off, device-tree isn't unflattened
672 */ 657 */
673static int __init pmac_probe(int platform) 658static int __init pmac_probe(void)
674{ 659{
675#ifdef CONFIG_PPC64 660 unsigned long root = of_get_flat_dt_root();
676 if (platform != PLATFORM_POWERMAC) 661
662 if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
663 !of_flat_dt_is_compatible(root, "MacRISC"))
677 return 0; 664 return 0;
678 665
666#ifdef CONFIG_PPC64
679 /* 667 /*
680 * On U3, the DART (iommu) must be allocated now since it 668 * On U3, the DART (iommu) must be allocated now since it
681 * has an impact on htab_initialize (due to the large page it 669 * has an impact on htab_initialize (due to the large page it
@@ -685,6 +673,23 @@ static int __init pmac_probe(int platform)
685 alloc_dart_table(); 673 alloc_dart_table();
686#endif 674#endif
687 675
676#ifdef CONFIG_PPC32
677 /* isa_io_base gets set in pmac_pci_init */
678 isa_mem_base = PMAC_ISA_MEM_BASE;
679 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
680 ISA_DMA_THRESHOLD = ~0L;
681 DMA_MODE_READ = 1;
682 DMA_MODE_WRITE = 2;
683
684#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
685#ifdef CONFIG_BLK_DEV_IDE_PMAC
686 ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
687 ppc_ide_md.default_io_base = pmac_ide_get_base;
688#endif /* CONFIG_BLK_DEV_IDE_PMAC */
689#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
690
691#endif /* CONFIG_PPC32 */
692
688#ifdef CONFIG_PMAC_SMU 693#ifdef CONFIG_PMAC_SMU
689 /* 694 /*
690 * SMU based G5s need some memory below 2Gb, at least the current 695 * SMU based G5s need some memory below 2Gb, at least the current
@@ -713,10 +718,8 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
713} 718}
714#endif 719#endif
715 720
716struct machdep_calls __initdata pmac_md = { 721define_machine(powermac) {
717#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) 722 .name = "PowerMac",
718 .cpu_die = generic_mach_cpu_die,
719#endif
720 .probe = pmac_probe, 723 .probe = pmac_probe,
721 .setup_arch = pmac_setup_arch, 724 .setup_arch = pmac_setup_arch,
722 .init_early = pmac_init_early, 725 .init_early = pmac_init_early,
@@ -737,7 +740,7 @@ struct machdep_calls __initdata pmac_md = {
737 .progress = udbg_progress, 740 .progress = udbg_progress,
738#ifdef CONFIG_PPC64 741#ifdef CONFIG_PPC64
739 .pci_probe_mode = pmac_pci_probe_mode, 742 .pci_probe_mode = pmac_pci_probe_mode,
740 .idle_loop = native_idle, 743 .power_save = power4_idle,
741 .enable_pmcs = power4_enable_pmcs, 744 .enable_pmcs = power4_enable_pmcs,
742#ifdef CONFIG_KEXEC 745#ifdef CONFIG_KEXEC
743 .machine_kexec = default_machine_kexec, 746 .machine_kexec = default_machine_kexec,
@@ -750,4 +753,7 @@ struct machdep_calls __initdata pmac_md = {
750 .pcibios_after_init = pmac_pcibios_after_init, 753 .pcibios_after_init = pmac_pcibios_after_init,
751 .phys_mem_access_prot = pci_phys_mem_access_prot, 754 .phys_mem_access_prot = pci_phys_mem_access_prot,
752#endif 755#endif
756#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
757 .cpu_die = generic_mach_cpu_die,
758#endif
753}; 759};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6d64a9bf3474..1065d87fc279 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -191,9 +191,7 @@ static void smp_psurge_message_pass(int target, int msg)
191 if (num_online_cpus() < 2) 191 if (num_online_cpus() < 2)
192 return; 192 return;
193 193
194 for (i = 0; i < NR_CPUS; i++) { 194 for_each_online_cpu(i) {
195 if (!cpu_online(i))
196 continue;
197 if (target == MSG_ALL 195 if (target == MSG_ALL
198 || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) 196 || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
199 || target == i) { 197 || target == i) {
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index 5d9afa1fa02d..890758aa9667 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -336,10 +336,10 @@ static struct pmu_sleep_notifier time_sleep_notifier = {
336 */ 336 */
337void __init pmac_calibrate_decr(void) 337void __init pmac_calibrate_decr(void)
338{ 338{
339#ifdef CONFIG_PM 339#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU)
340 /* XXX why here? */ 340 /* XXX why here? */
341 pmu_register_sleep_notifier(&time_sleep_notifier); 341 pmu_register_sleep_notifier(&time_sleep_notifier);
342#endif /* CONFIG_PM */ 342#endif
343 343
344 generic_calibrate_decr(); 344 generic_calibrate_decr();
345 345
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index c4352a8db644..b4fa9f03b461 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -116,7 +116,7 @@ void udbg_scc_init(int force_scc)
116 /* Setup for 57600 8N1 */ 116 /* Setup for 57600 8N1 */
117 if (ch == ch_a) 117 if (ch == ch_a)
118 addr += 0x20; 118 addr += 0x20;
119 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 119 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
120 sccc += addr & ~PAGE_MASK; 120 sccc += addr & ~PAGE_MASK;
121 sccd = sccc + 0x10; 121 sccd = sccc + 0x10;
122 122
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 4e5c8f8d869d..a57032cf6f1b 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -19,7 +19,7 @@ config SCANLOG
19 depends on RTAS_PROC && PPC_PSERIES 19 depends on RTAS_PROC && PPC_PSERIES
20 20
21config LPARCFG 21config LPARCFG
22 tristate "LPAR Configuration Data" 22 bool "LPAR Configuration Data"
23 depends on PPC_PSERIES || PPC_ISERIES 23 depends on PPC_PSERIES || PPC_ISERIES
24 help 24 help
25 Provide system capacity information via human readable 25 Provide system capacity information via human readable
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 61616d144072..930898635c9f 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,5 +1,6 @@
1obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ 1obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
2 setup.o iommu.o ras.o rtasd.o pci_dlpar.o 2 setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
3 firmware.o
3obj-$(CONFIG_SMP) += smp.o 4obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_IBMVIO) += vio.o 5obj-$(CONFIG_IBMVIO) += vio.o
5obj-$(CONFIG_XICS) += xics.o 6obj-$(CONFIG_XICS) += xics.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 2ab9dcdfb415..9b2b1cb117b3 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1018,7 +1018,7 @@ static int __init eeh_init_proc(void)
1018{ 1018{
1019 struct proc_dir_entry *e; 1019 struct proc_dir_entry *e;
1020 1020
1021 if (platform_is_pseries()) { 1021 if (machine_is(pseries)) {
1022 e = create_proc_entry("ppc64/eeh", 0, NULL); 1022 e = create_proc_entry("ppc64/eeh", 0, NULL);
1023 if (e) 1023 if (e)
1024 e->proc_fops = &proc_eeh_operations; 1024 e->proc_fops = &proc_eeh_operations;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index b811d5ff92fe..cc2495a0cdd5 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -257,6 +257,7 @@ void handle_eeh_events (struct eeh_event *event)
257 struct pci_bus *frozen_bus; 257 struct pci_bus *frozen_bus;
258 int rc = 0; 258 int rc = 0;
259 enum pci_ers_result result = PCI_ERS_RESULT_NONE; 259 enum pci_ers_result result = PCI_ERS_RESULT_NONE;
260 const char *pci_str, *drv_str;
260 261
261 frozen_dn = find_device_pe(event->dn); 262 frozen_dn = find_device_pe(event->dn);
262 frozen_bus = pcibios_find_pci_bus(frozen_dn); 263 frozen_bus = pcibios_find_pci_bus(frozen_dn);
@@ -291,6 +292,13 @@ void handle_eeh_events (struct eeh_event *event)
291 292
292 frozen_pdn = PCI_DN(frozen_dn); 293 frozen_pdn = PCI_DN(frozen_dn);
293 frozen_pdn->eeh_freeze_count++; 294 frozen_pdn->eeh_freeze_count++;
295
296 pci_str = pci_name (frozen_pdn->pcidev);
297 drv_str = pcid_name (frozen_pdn->pcidev);
298 if (!pci_str) {
299 pci_str = pci_name (event->dev);
300 drv_str = pcid_name (event->dev);
301 }
294 302
295 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) 303 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
296 goto hard_fail; 304 goto hard_fail;
@@ -306,9 +314,7 @@ void handle_eeh_events (struct eeh_event *event)
306 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); 314 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
307 printk(KERN_WARNING 315 printk(KERN_WARNING
308 "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", 316 "EEH: This PCI device has failed %d times since last reboot: %s - %s\n",
309 frozen_pdn->eeh_freeze_count, 317 frozen_pdn->eeh_freeze_count, drv_str, pci_str);
310 pci_name (frozen_pdn->pcidev),
311 pcid_name(frozen_pdn->pcidev));
312 318
313 /* Walk the various device drivers attached to this slot through 319 /* Walk the various device drivers attached to this slot through
314 * a reset sequence, giving each an opportunity to do what it needs 320 * a reset sequence, giving each an opportunity to do what it needs
@@ -360,9 +366,7 @@ hard_fail:
360 "EEH: PCI device %s - %s has failed %d times \n" 366 "EEH: PCI device %s - %s has failed %d times \n"
361 "and has been permanently disabled. Please try reseating\n" 367 "and has been permanently disabled. Please try reseating\n"
362 "this device or replacing it.\n", 368 "this device or replacing it.\n",
363 pci_name (frozen_pdn->pcidev), 369 drv_str, pci_str, frozen_pdn->eeh_freeze_count);
364 pcid_name(frozen_pdn->pcidev),
365 frozen_pdn->eeh_freeze_count);
366 370
367 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); 371 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
368 372
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
new file mode 100644
index 000000000000..c01d8f0cbe6d
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -0,0 +1,103 @@
1/*
2 * pSeries firmware setup code.
3 *
4 * Portions from arch/powerpc/platforms/pseries/setup.c:
5 * Copyright (C) 1995 Linus Torvalds
6 * Adapted from 'alpha' version by Gary Thomas
7 * Modified by Cort Dougan (cort@cs.nmt.edu)
8 * Modified by PPC64 Team, IBM Corp
9 *
10 * Portions from arch/powerpc/kernel/firmware.c
11 * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
12 * Modifications for ppc64:
13 * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
14 * Copyright (C) 2005 Stephen Rothwell, IBM Corporation
15 *
16 * Copyright 2006 IBM Corporation.
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version
21 * 2 of the License, or (at your option) any later version.
22 */
23
24#undef DEBUG
25
26#include <asm/firmware.h>
27#include <asm/prom.h>
28
29#ifdef DEBUG
30#define DBG(fmt...) udbg_printf(fmt)
31#else
32#define DBG(fmt...)
33#endif
34
35typedef struct {
36 unsigned long val;
37 char * name;
38} firmware_feature_t;
39
40static __initdata firmware_feature_t
41firmware_features_table[FIRMWARE_MAX_FEATURES] = {
42 {FW_FEATURE_PFT, "hcall-pft"},
43 {FW_FEATURE_TCE, "hcall-tce"},
44 {FW_FEATURE_SPRG0, "hcall-sprg0"},
45 {FW_FEATURE_DABR, "hcall-dabr"},
46 {FW_FEATURE_COPY, "hcall-copy"},
47 {FW_FEATURE_ASR, "hcall-asr"},
48 {FW_FEATURE_DEBUG, "hcall-debug"},
49 {FW_FEATURE_PERF, "hcall-perf"},
50 {FW_FEATURE_DUMP, "hcall-dump"},
51 {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
52 {FW_FEATURE_MIGRATE, "hcall-migrate"},
53 {FW_FEATURE_PERFMON, "hcall-perfmon"},
54 {FW_FEATURE_CRQ, "hcall-crq"},
55 {FW_FEATURE_VIO, "hcall-vio"},
56 {FW_FEATURE_RDMA, "hcall-rdma"},
57 {FW_FEATURE_LLAN, "hcall-lLAN"},
58 {FW_FEATURE_BULK, "hcall-bulk"},
59 {FW_FEATURE_XDABR, "hcall-xdabr"},
60 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
61 {FW_FEATURE_SPLPAR, "hcall-splpar"},
62};
63
64/* Build up the firmware features bitmask using the contents of
65 * device-tree/ibm,hypertas-functions. Ultimately this functionality may
66 * be moved into prom.c prom_init().
67 */
68void __init fw_feature_init(void)
69{
70 struct device_node *dn;
71 char *hypertas, *s;
72 int len, i;
73
74 DBG(" -> fw_feature_init()\n");
75
76 dn = of_find_node_by_path("/rtas");
77 if (dn == NULL) {
78 printk(KERN_ERR "WARNING! Cannot find RTAS in device-tree!\n");
79 goto out;
80 }
81
82 hypertas = get_property(dn, "ibm,hypertas-functions", &len);
83 if (hypertas == NULL)
84 goto out;
85
86 for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
87 for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) {
88 /* check value against table of strings */
89 if (!firmware_features_table[i].name ||
90 strcmp(firmware_features_table[i].name, s))
91 continue;
92
93 /* we have a match */
94 powerpc_firmware_features |=
95 firmware_features_table[i].val;
96 break;
97 }
98 }
99
100out:
101 of_node_put(dn);
102 DBG(" <- fw_feature_init()\n");
103}
diff --git a/arch/powerpc/platforms/pseries/firmware.h b/arch/powerpc/platforms/pseries/firmware.h
new file mode 100644
index 000000000000..714f56f55362
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/firmware.h
@@ -0,0 +1,17 @@
1/*
2 * Copyright 2006 IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef _PSERIES_FIRMWARE_H
11#define _PSERIES_FIRMWARE_H
12
13#include <asm/firmware.h>
14
15extern void __init fw_feature_init(void);
16
17#endif /* _PSERIES_FIRMWARE_H */
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 176e8da76466..db7c19fe9297 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/pSeries_hvCall.S
3 *
4 * This file contains the generic code to perform a call to the 2 * This file contains the generic code to perform a call to the
5 * pSeries LPAR hypervisor. 3 * pSeries LPAR hypervisor.
6 * NOTE: this file will go away when we move to inline this work. 4 * NOTE: this file will go away when we move to inline this work.
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 138e128a3886..ba6befd96636 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -62,6 +62,11 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
62 unsigned long *lbuf = (unsigned long *) buf; 62 unsigned long *lbuf = (unsigned long *) buf;
63 long ret; 63 long ret;
64 64
65
66 /* hcall will ret H_PARAMETER if 'count' exceeds firmware max.*/
67 if (count > MAX_VIO_PUT_CHARS)
68 count = MAX_VIO_PUT_CHARS;
69
65 ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0], 70 ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0],
66 lbuf[1]); 71 lbuf[1]);
67 if (ret == H_Success) 72 if (ret == H_Success)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 48cfbfc43f99..2643078433f0 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/pSeries_iommu.c
3 *
4 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
5 * 3 *
6 * Rewrite, cleanup: 4 * Rewrite, cleanup:
@@ -582,7 +580,7 @@ void iommu_init_early_pSeries(void)
582 return; 580 return;
583 } 581 }
584 582
585 if (platform_is_lpar()) { 583 if (firmware_has_feature(FW_FEATURE_LPAR)) {
586 if (firmware_has_feature(FW_FEATURE_MULTITCE)) { 584 if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
587 ppc_md.tce_build = tce_buildmulti_pSeriesLP; 585 ppc_md.tce_build = tce_buildmulti_pSeriesLP;
588 ppc_md.tce_free = tce_freemulti_pSeriesLP; 586 ppc_md.tce_free = tce_freemulti_pSeriesLP;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 999a9620b5ce..e97e67f5e079 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/pSeries_pci.c
3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 4 *
@@ -122,7 +120,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
122 int i; 120 int i;
123 unsigned int reg; 121 unsigned int reg;
124 122
125 if (!platform_is_pseries()) 123 if (!machine_is(pseries))
126 return; 124 return;
127 125
128 printk("Using INTC for W82c105 IDE controller.\n"); 126 printk("Using INTC for W82c105 IDE controller.\n");
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index f3bad900bbcf..6bfacc217085 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -27,6 +27,8 @@
27 27
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <asm/pci-bridge.h> 29#include <asm/pci-bridge.h>
30#include <asm/ppc-pci.h>
31#include <asm/firmware.h>
30 32
31static struct pci_bus * 33static struct pci_bus *
32find_bus_among_children(struct pci_bus *bus, 34find_bus_among_children(struct pci_bus *bus,
@@ -151,20 +153,24 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
151void 153void
152pcibios_add_pci_devices(struct pci_bus * bus) 154pcibios_add_pci_devices(struct pci_bus * bus)
153{ 155{
154 int slotno, num; 156 int slotno, num, mode;
155 struct pci_dev *dev; 157 struct pci_dev *dev;
156 struct device_node *dn = pci_bus_to_OF_node(bus); 158 struct device_node *dn = pci_bus_to_OF_node(bus);
157 159
158 eeh_add_device_tree_early(dn); 160 eeh_add_device_tree_early(dn);
159 161
160 if (_machine == PLATFORM_PSERIES_LPAR) { 162 mode = PCI_PROBE_NORMAL;
163 if (ppc_md.pci_probe_mode)
164 mode = ppc_md.pci_probe_mode(bus);
165
166 if (mode == PCI_PROBE_DEVTREE) {
161 /* use ofdt-based probe */ 167 /* use ofdt-based probe */
162 of_scan_bus(dn, bus); 168 of_scan_bus(dn, bus);
163 if (!list_empty(&bus->devices)) { 169 if (!list_empty(&bus->devices)) {
164 pcibios_fixup_new_pci_devices(bus, 0); 170 pcibios_fixup_new_pci_devices(bus, 0);
165 pci_bus_add_devices(bus); 171 pci_bus_add_devices(bus);
166 } 172 }
167 } else { 173 } else if (mode == PCI_PROBE_NORMAL) {
168 /* use legacy probe */ 174 /* use legacy probe */
169 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 175 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
170 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 176 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
@@ -179,3 +185,30 @@ pcibios_add_pci_devices(struct pci_bus * bus)
179 } 185 }
180} 186}
181EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); 187EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
188
189struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
190{
191 struct pci_controller *phb;
192 int primary;
193
194 primary = list_empty(&hose_list);
195 phb = pcibios_alloc_controller(dn);
196 if (!phb)
197 return NULL;
198 setup_phb(dn, phb);
199 pci_process_bridge_OF_ranges(phb, dn, 0);
200
201 pci_setup_phb_io_dynamic(phb, primary);
202
203 pci_devs_phb_init_dynamic(phb);
204
205 if (dn->child)
206 eeh_add_device_tree_early(dn);
207
208 scan_phb(phb);
209 pcibios_fixup_new_pci_devices(phb->bus, 0);
210 pci_bus_add_devices(phb->bus);
211
212 return phb;
213}
214EXPORT_SYMBOL_GPL(init_phb_dynamic);
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index b046bcf7443d..9639c66b453d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -132,7 +132,7 @@ static int __init init_ras_IRQ(void)
132 of_node_put(np); 132 of_node_put(np);
133 } 133 }
134 134
135 return 1; 135 return 0;
136} 136}
137__initcall(init_ras_IRQ); 137__initcall(init_ras_IRQ);
138 138
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 86cfa6ecdcf3..1773103354be 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -17,8 +17,9 @@
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18 18
19#include <asm/prom.h> 19#include <asm/prom.h>
20#include <asm/pSeries_reconfig.h> 20#include <asm/machdep.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22#include <asm/pSeries_reconfig.h>
22 23
23 24
24 25
@@ -94,16 +95,16 @@ static struct device_node *derive_parent(const char *path)
94 return parent; 95 return parent;
95} 96}
96 97
97static struct notifier_block *pSeries_reconfig_chain; 98static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
98 99
99int pSeries_reconfig_notifier_register(struct notifier_block *nb) 100int pSeries_reconfig_notifier_register(struct notifier_block *nb)
100{ 101{
101 return notifier_chain_register(&pSeries_reconfig_chain, nb); 102 return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
102} 103}
103 104
104void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) 105void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
105{ 106{
106 notifier_chain_unregister(&pSeries_reconfig_chain, nb); 107 blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
107} 108}
108 109
109static int pSeries_reconfig_add_node(const char *path, struct property *proplist) 110static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
@@ -131,7 +132,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
131 goto out_err; 132 goto out_err;
132 } 133 }
133 134
134 err = notifier_call_chain(&pSeries_reconfig_chain, 135 err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
135 PSERIES_RECONFIG_ADD, np); 136 PSERIES_RECONFIG_ADD, np);
136 if (err == NOTIFY_BAD) { 137 if (err == NOTIFY_BAD) {
137 printk(KERN_ERR "Failed to add device node %s\n", path); 138 printk(KERN_ERR "Failed to add device node %s\n", path);
@@ -171,7 +172,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
171 172
172 remove_node_proc_entries(np); 173 remove_node_proc_entries(np);
173 174
174 notifier_call_chain(&pSeries_reconfig_chain, 175 blocking_notifier_call_chain(&pSeries_reconfig_chain,
175 PSERIES_RECONFIG_REMOVE, np); 176 PSERIES_RECONFIG_REMOVE, np);
176 of_detach_node(np); 177 of_detach_node(np);
177 178
@@ -508,7 +509,7 @@ static int proc_ppc64_create_ofdt(void)
508{ 509{
509 struct proc_dir_entry *ent; 510 struct proc_dir_entry *ent;
510 511
511 if (!platform_is_pseries()) 512 if (!machine_is(pseries))
512 return 0; 513 return 0;
513 514
514 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); 515 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index a6f628d4c9dc..fcc4d561a236 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -27,6 +27,7 @@
27#include <asm/prom.h> 27#include <asm/prom.h>
28#include <asm/nvram.h> 28#include <asm/nvram.h>
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30#include <asm/machdep.h>
30 31
31#if 0 32#if 0
32#define DEBUG(A...) printk(KERN_ERR A) 33#define DEBUG(A...) printk(KERN_ERR A)
@@ -481,7 +482,7 @@ static int __init rtas_init(void)
481{ 482{
482 struct proc_dir_entry *entry; 483 struct proc_dir_entry *entry;
483 484
484 if (!platform_is_pseries()) 485 if (!machine_is(pseries))
485 return 0; 486 return 0;
486 487
487 /* No RTAS */ 488 /* No RTAS */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 9edeca83f434..b2fbf8ba8fbb 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -60,7 +60,6 @@
60#include <asm/time.h> 60#include <asm/time.h>
61#include <asm/nvram.h> 61#include <asm/nvram.h>
62#include "xics.h" 62#include "xics.h"
63#include <asm/firmware.h>
64#include <asm/pmc.h> 63#include <asm/pmc.h>
65#include <asm/mpic.h> 64#include <asm/mpic.h>
66#include <asm/ppc-pci.h> 65#include <asm/ppc-pci.h>
@@ -70,6 +69,7 @@
70 69
71#include "plpar_wrappers.h" 70#include "plpar_wrappers.h"
72#include "ras.h" 71#include "ras.h"
72#include "firmware.h"
73 73
74#ifdef DEBUG 74#ifdef DEBUG
75#define DBG(fmt...) udbg_printf(fmt) 75#define DBG(fmt...) udbg_printf(fmt)
@@ -81,8 +81,8 @@ extern void find_udbg_vterm(void);
81 81
82int fwnmi_active; /* TRUE if an FWNMI handler is present */ 82int fwnmi_active; /* TRUE if an FWNMI handler is present */
83 83
84static void pseries_shared_idle(void); 84static void pseries_shared_idle_sleep(void);
85static void pseries_dedicated_idle(void); 85static void pseries_dedicated_idle_sleep(void);
86 86
87struct mpic *pSeries_mpic; 87struct mpic *pSeries_mpic;
88 88
@@ -236,17 +236,16 @@ static void __init pSeries_setup_arch(void)
236 vpa_init(boot_cpuid); 236 vpa_init(boot_cpuid);
237 if (get_lppaca()->shared_proc) { 237 if (get_lppaca()->shared_proc) {
238 printk(KERN_INFO "Using shared processor idle loop\n"); 238 printk(KERN_INFO "Using shared processor idle loop\n");
239 ppc_md.idle_loop = pseries_shared_idle; 239 ppc_md.power_save = pseries_shared_idle_sleep;
240 } else { 240 } else {
241 printk(KERN_INFO "Using dedicated idle loop\n"); 241 printk(KERN_INFO "Using dedicated idle loop\n");
242 ppc_md.idle_loop = pseries_dedicated_idle; 242 ppc_md.power_save = pseries_dedicated_idle_sleep;
243 } 243 }
244 } else { 244 } else {
245 printk(KERN_INFO "Using default idle loop\n"); 245 printk(KERN_INFO "Using default idle loop\n");
246 ppc_md.idle_loop = default_idle;
247 } 246 }
248 247
249 if (platform_is_lpar()) 248 if (firmware_has_feature(FW_FEATURE_LPAR))
250 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; 249 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
251 else 250 else
252 ppc_md.enable_pmcs = power4_enable_pmcs; 251 ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -262,53 +261,6 @@ static int __init pSeries_init_panel(void)
262} 261}
263arch_initcall(pSeries_init_panel); 262arch_initcall(pSeries_init_panel);
264 263
265
266/* Build up the ppc64_firmware_features bitmask field
267 * using contents of device-tree/ibm,hypertas-functions.
268 * Ultimately this functionality may be moved into prom.c prom_init().
269 */
270static void __init fw_feature_init(void)
271{
272 struct device_node * dn;
273 char * hypertas;
274 unsigned int len;
275
276 DBG(" -> fw_feature_init()\n");
277
278 ppc64_firmware_features = 0;
279 dn = of_find_node_by_path("/rtas");
280 if (dn == NULL) {
281 printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n");
282 goto no_rtas;
283 }
284
285 hypertas = get_property(dn, "ibm,hypertas-functions", &len);
286 if (hypertas) {
287 while (len > 0){
288 int i, hypertas_len;
289 /* check value against table of strings */
290 for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
291 if ((firmware_features_table[i].name) &&
292 (strcmp(firmware_features_table[i].name,hypertas))==0) {
293 /* we have a match */
294 ppc64_firmware_features |=
295 (firmware_features_table[i].val);
296 break;
297 }
298 }
299 hypertas_len = strlen(hypertas);
300 len -= hypertas_len +1;
301 hypertas+= hypertas_len +1;
302 }
303 }
304
305 of_node_put(dn);
306no_rtas:
307
308 DBG(" <- fw_feature_init()\n");
309}
310
311
312static void __init pSeries_discover_pic(void) 264static void __init pSeries_discover_pic(void)
313{ 265{
314 struct device_node *np; 266 struct device_node *np;
@@ -367,21 +319,16 @@ static int pseries_set_xdabr(unsigned long dabr)
367 */ 319 */
368static void __init pSeries_init_early(void) 320static void __init pSeries_init_early(void)
369{ 321{
370 int iommu_off = 0;
371
372 DBG(" -> pSeries_init_early()\n"); 322 DBG(" -> pSeries_init_early()\n");
373 323
374 fw_feature_init(); 324 fw_feature_init();
375 325
376 if (platform_is_lpar()) 326 if (firmware_has_feature(FW_FEATURE_LPAR))
377 hpte_init_lpar(); 327 hpte_init_lpar();
378 else { 328 else
379 hpte_init_native(); 329 hpte_init_native();
380 iommu_off = (of_chosen &&
381 get_property(of_chosen, "linux,iommu-off", NULL));
382 }
383 330
384 if (platform_is_lpar()) 331 if (firmware_has_feature(FW_FEATURE_LPAR))
385 find_udbg_vterm(); 332 find_udbg_vterm();
386 333
387 if (firmware_has_feature(FW_FEATURE_DABR)) 334 if (firmware_has_feature(FW_FEATURE_DABR))
@@ -425,158 +372,128 @@ static int pSeries_check_legacy_ioport(unsigned int baseport)
425/* 372/*
426 * Called very early, MMU is off, device-tree isn't unflattened 373 * Called very early, MMU is off, device-tree isn't unflattened
427 */ 374 */
428extern struct machdep_calls pSeries_md;
429 375
430static int __init pSeries_probe(int platform) 376static int __init pSeries_probe_hypertas(unsigned long node,
377 const char *uname, int depth,
378 void *data)
431{ 379{
432 if (platform != PLATFORM_PSERIES && 380 if (depth != 1 ||
433 platform != PLATFORM_PSERIES_LPAR) 381 (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0))
434 return 0; 382 return 0;
435 383
436 /* if we have some ppc_md fixups for LPAR to do, do 384 if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
437 * it here ... 385 powerpc_firmware_features |= FW_FEATURE_LPAR;
438 */
439 386
440 return 1; 387 return 1;
441} 388}
442 389
443DECLARE_PER_CPU(unsigned long, smt_snooze_delay); 390static int __init pSeries_probe(void)
444
445static inline void dedicated_idle_sleep(unsigned int cpu)
446{ 391{
447 struct lppaca *plppaca = &lppaca[cpu ^ 1]; 392 char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
393 "device_type", NULL);
394 if (dtype == NULL)
395 return 0;
396 if (strcmp(dtype, "chrp"))
397 return 0;
448 398
449 /* Only sleep if the other thread is not idle */ 399 DBG("pSeries detected, looking for LPAR capability...\n");
450 if (!(plppaca->idle)) {
451 local_irq_disable();
452 400
453 /* 401 /* Now try to figure out if we are running on LPAR */
454 * We are about to sleep the thread and so wont be polling any 402 of_scan_flat_dt(pSeries_probe_hypertas, NULL);
455 * more. 403
456 */ 404 DBG("Machine is%s LPAR !\n",
457 clear_thread_flag(TIF_POLLING_NRFLAG); 405 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
458 smp_mb__after_clear_bit(); 406
459 407 return 1;
460 /*
461 * SMT dynamic mode. Cede will result in this thread going
462 * dormant, if the partner thread is still doing work. Thread
463 * wakes up if partner goes idle, an interrupt is presented, or
464 * a prod occurs. Returning from the cede enables external
465 * interrupts.
466 */
467 if (!need_resched())
468 cede_processor();
469 else
470 local_irq_enable();
471 set_thread_flag(TIF_POLLING_NRFLAG);
472 } else {
473 /*
474 * Give the HV an opportunity at the processor, since we are
475 * not doing any work.
476 */
477 poll_pending();
478 }
479} 408}
480 409
481static void pseries_dedicated_idle(void) 410
411DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
412
413static void pseries_dedicated_idle_sleep(void)
482{ 414{
483 unsigned int cpu = smp_processor_id(); 415 unsigned int cpu = smp_processor_id();
484 unsigned long start_snooze; 416 unsigned long start_snooze;
485 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); 417 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
486 set_thread_flag(TIF_POLLING_NRFLAG);
487
488 while (1) {
489 /*
490 * Indicate to the HV that we are idle. Now would be
491 * a good time to find other work to dispatch.
492 */
493 get_lppaca()->idle = 1;
494
495 if (!need_resched()) {
496 start_snooze = get_tb() +
497 *smt_snooze_delay * tb_ticks_per_usec;
498
499 while (!need_resched() && !cpu_is_offline(cpu)) {
500 ppc64_runlatch_off();
501
502 /*
503 * Go into low thread priority and possibly
504 * low power mode.
505 */
506 HMT_low();
507 HMT_very_low();
508
509 if (*smt_snooze_delay != 0 &&
510 get_tb() > start_snooze) {
511 HMT_medium();
512 dedicated_idle_sleep(cpu);
513 }
514
515 }
516
517 HMT_medium();
518 }
519 418
520 get_lppaca()->idle = 0; 419 /*
521 ppc64_runlatch_on(); 420 * Indicate to the HV that we are idle. Now would be
522 421 * a good time to find other work to dispatch.
523 preempt_enable_no_resched(); 422 */
524 schedule(); 423 get_lppaca()->idle = 1;
525 preempt_disable();
526 424
527 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 425 /*
528 cpu_die(); 426 * We come in with interrupts disabled, and need_resched()
529 } 427 * has been checked recently. If we should poll for a little
530} 428 * while, do so.
429 */
430 if (*smt_snooze_delay) {
431 start_snooze = get_tb() +
432 *smt_snooze_delay * tb_ticks_per_usec;
433 local_irq_enable();
434 set_thread_flag(TIF_POLLING_NRFLAG);
531 435
532static void pseries_shared_idle(void) 436 while (get_tb() < start_snooze) {
533{ 437 if (need_resched() || cpu_is_offline(cpu))
534 unsigned int cpu = smp_processor_id(); 438 goto out;
439 ppc64_runlatch_off();
440 HMT_low();
441 HMT_very_low();
442 }
535 443
536 while (1) { 444 HMT_medium();
537 /* 445 clear_thread_flag(TIF_POLLING_NRFLAG);
538 * Indicate to the HV that we are idle. Now would be 446 smp_mb();
539 * a good time to find other work to dispatch. 447 local_irq_disable();
540 */ 448 if (need_resched() || cpu_is_offline(cpu))
541 get_lppaca()->idle = 1; 449 goto out;
450 }
542 451
543 while (!need_resched() && !cpu_is_offline(cpu)) { 452 /*
544 local_irq_disable(); 453 * Cede if the other thread is not idle, so that it can
545 ppc64_runlatch_off(); 454 * go single-threaded. If the other thread is idle,
455 * we ask the hypervisor if it has pending work it
456 * wants to do and cede if it does. Otherwise we keep
457 * polling in order to reduce interrupt latency.
458 *
459 * Doing the cede when the other thread is active will
460 * result in this thread going dormant, meaning the other
461 * thread gets to run in single-threaded (ST) mode, which
462 * is slightly faster than SMT mode with this thread at
463 * very low priority. The cede enables interrupts, which
464 * doesn't matter here.
465 */
466 if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending)
467 cede_processor();
546 468
547 /* 469out:
548 * Yield the processor to the hypervisor. We return if 470 HMT_medium();
549 * an external interrupt occurs (which are driven prior 471 get_lppaca()->idle = 0;
550 * to returning here) or if a prod occurs from another 472}
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 473
565 get_lppaca()->idle = 0; 474static void pseries_shared_idle_sleep(void)
566 ppc64_runlatch_on(); 475{
476 /*
477 * Indicate to the HV that we are idle. Now would be
478 * a good time to find other work to dispatch.
479 */
480 get_lppaca()->idle = 1;
567 481
568 preempt_enable_no_resched(); 482 /*
569 schedule(); 483 * Yield the processor to the hypervisor. We return if
570 preempt_disable(); 484 * an external interrupt occurs (which are driven prior
485 * to returning here) or if a prod occurs from another
486 * processor. When returning here, external interrupts
487 * are enabled.
488 */
489 cede_processor();
571 490
572 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 491 get_lppaca()->idle = 0;
573 cpu_die();
574 }
575} 492}
576 493
577static int pSeries_pci_probe_mode(struct pci_bus *bus) 494static int pSeries_pci_probe_mode(struct pci_bus *bus)
578{ 495{
579 if (platform_is_lpar()) 496 if (firmware_has_feature(FW_FEATURE_LPAR))
580 return PCI_PROBE_DEVTREE; 497 return PCI_PROBE_DEVTREE;
581 return PCI_PROBE_NORMAL; 498 return PCI_PROBE_NORMAL;
582} 499}
@@ -602,7 +519,8 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
602} 519}
603#endif 520#endif
604 521
605struct machdep_calls __initdata pSeries_md = { 522define_machine(pseries) {
523 .name = "pSeries",
606 .probe = pSeries_probe, 524 .probe = pSeries_probe,
607 .setup_arch = pSeries_setup_arch, 525 .setup_arch = pSeries_setup_arch,
608 .init_early = pSeries_init_early, 526 .init_early = pSeries_init_early,
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 8d710af50756..3cf78a6cd27c 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -443,7 +443,7 @@ void __init smp_init_pSeries(void)
443 smp_ops->cpu_die = pSeries_cpu_die; 443 smp_ops->cpu_die = pSeries_cpu_die;
444 444
445 /* Processors can be added/removed only on LPAR */ 445 /* Processors can be added/removed only on LPAR */
446 if (platform_is_lpar()) 446 if (firmware_has_feature(FW_FEATURE_LPAR))
447 pSeries_reconfig_notifier_register(&pSeries_smp_nb); 447 pSeries_reconfig_notifier_register(&pSeries_smp_nb);
448#endif 448#endif
449 449
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index fd823c7c9ac8..4864cb32be25 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -20,6 +20,7 @@
20#include <linux/gfp.h> 20#include <linux/gfp.h>
21#include <linux/radix-tree.h> 21#include <linux/radix-tree.h>
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <asm/firmware.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/pgtable.h> 26#include <asm/pgtable.h>
@@ -499,7 +500,7 @@ nextnode:
499 np; 500 np;
500 np = of_find_node_by_type(np, "cpu")) { 501 np = of_find_node_by_type(np, "cpu")) {
501 ireg = (uint *)get_property(np, "reg", &ilen); 502 ireg = (uint *)get_property(np, "reg", &ilen);
502 if (ireg && ireg[0] == boot_cpuid_phys) { 503 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
503 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", 504 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s",
504 &ilen); 505 &ilen);
505 i = ilen / sizeof(int); 506 i = ilen / sizeof(int);
@@ -536,11 +537,11 @@ nextnode:
536 of_node_put(np); 537 of_node_put(np);
537 } 538 }
538 539
539 if (platform_is_lpar()) 540 if (firmware_has_feature(FW_FEATURE_LPAR))
540 ops = &pSeriesLP_ops; 541 ops = &pSeriesLP_ops;
541 else { 542 else {
542#ifdef CONFIG_SMP 543#ifdef CONFIG_SMP
543 for_each_cpu(i) { 544 for_each_possible_cpu(i) {
544 int hard_id; 545 int hard_id;
545 546
546 /* FIXME: Do this dynamically! --RR */ 547 /* FIXME: Do this dynamically! --RR */
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 6298264efe36..61d317428610 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -194,8 +194,6 @@ static int dart_init(struct device_node *dart_node)
194 * prefetching into invalid pages and corrupting data 194 * prefetching into invalid pages and corrupting data
195 */ 195 */
196 tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); 196 tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
197 if (!tmp)
198 panic("DART: Cannot allocate spare page!");
199 dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & 197 dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) &
200 DARTMAP_RPNMASK); 198 DARTMAP_RPNMASK);
201 199
diff --git a/arch/powerpc/sysdev/dcr.S b/arch/powerpc/sysdev/dcr.S
index 895f10243a43..2078f39e2f17 100644
--- a/arch/powerpc/sysdev/dcr.S
+++ b/arch/powerpc/sysdev/dcr.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/syslib/dcr.S
3 *
4 * "Indirect" DCR access 2 * "Indirect" DCR access
5 * 3 *
6 * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net> 4 * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net>
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 064c9de47732..ceb584682fa3 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -40,7 +40,7 @@ phys_addr_t get_immrbase(void)
40 return immrbase; 40 return immrbase;
41 41
42 soc = of_find_node_by_type(NULL, "soc"); 42 soc = of_find_node_by_type(NULL, "soc");
43 if (soc != 0) { 43 if (soc) {
44 unsigned int size; 44 unsigned int size;
45 void *prop = get_property(soc, "reg", &size); 45 void *prop = get_property(soc, "reg", &size);
46 immrbase = of_translate_address(soc, prop); 46 immrbase = of_translate_address(soc, prop);
@@ -49,21 +49,20 @@ phys_addr_t get_immrbase(void)
49 49
50 return immrbase; 50 return immrbase;
51} 51}
52EXPORT_SYMBOL(get_immrbase);
53 52
54static const char * gfar_tx_intr = "tx"; 53EXPORT_SYMBOL(get_immrbase);
55static const char * gfar_rx_intr = "rx";
56static const char * gfar_err_intr = "error";
57 54
58static int __init gfar_of_init(void) 55static int __init gfar_mdio_of_init(void)
59{ 56{
60 struct device_node *np; 57 struct device_node *np;
61 unsigned int i; 58 unsigned int i;
62 struct platform_device *mdio_dev, *gfar_dev; 59 struct platform_device *mdio_dev;
63 struct resource res; 60 struct resource res;
64 int ret; 61 int ret;
65 62
66 for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) { 63 for (np = NULL, i = 0;
64 (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
65 i++) {
67 int k; 66 int k;
68 struct device_node *child = NULL; 67 struct device_node *child = NULL;
69 struct gianfar_mdio_data mdio_data; 68 struct gianfar_mdio_data mdio_data;
@@ -73,12 +72,14 @@ static int __init gfar_of_init(void)
73 72
74 ret = of_address_to_resource(np, 0, &res); 73 ret = of_address_to_resource(np, 0, &res);
75 if (ret) 74 if (ret)
76 goto mdio_err; 75 goto err;
77 76
78 mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1); 77 mdio_dev =
78 platform_device_register_simple("fsl-gianfar_mdio",
79 res.start, &res, 1);
79 if (IS_ERR(mdio_dev)) { 80 if (IS_ERR(mdio_dev)) {
80 ret = PTR_ERR(mdio_dev); 81 ret = PTR_ERR(mdio_dev);
81 goto mdio_err; 82 goto err;
82 } 83 }
83 84
84 for (k = 0; k < 32; k++) 85 for (k = 0; k < 32; k++)
@@ -86,17 +87,44 @@ static int __init gfar_of_init(void)
86 87
87 while ((child = of_get_next_child(np, child)) != NULL) { 88 while ((child = of_get_next_child(np, child)) != NULL) {
88 if (child->n_intrs) { 89 if (child->n_intrs) {
89 u32 *id = (u32 *) get_property(child, "reg", NULL); 90 u32 *id =
91 (u32 *) get_property(child, "reg", NULL);
90 mdio_data.irq[*id] = child->intrs[0].line; 92 mdio_data.irq[*id] = child->intrs[0].line;
91 } 93 }
92 } 94 }
93 95
94 ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data)); 96 ret =
97 platform_device_add_data(mdio_dev, &mdio_data,
98 sizeof(struct gianfar_mdio_data));
95 if (ret) 99 if (ret)
96 goto mdio_unreg; 100 goto unreg;
97 } 101 }
98 102
99 for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) { 103 return 0;
104
105unreg:
106 platform_device_unregister(mdio_dev);
107err:
108 return ret;
109}
110
111arch_initcall(gfar_mdio_of_init);
112
113static const char *gfar_tx_intr = "tx";
114static const char *gfar_rx_intr = "rx";
115static const char *gfar_err_intr = "error";
116
117static int __init gfar_of_init(void)
118{
119 struct device_node *np;
120 unsigned int i;
121 struct platform_device *gfar_dev;
122 struct resource res;
123 int ret;
124
125 for (np = NULL, i = 0;
126 (np = of_find_compatible_node(np, "network", "gianfar")) != NULL;
127 i++) {
100 struct resource r[4]; 128 struct resource r[4];
101 struct device_node *phy, *mdio; 129 struct device_node *phy, *mdio;
102 struct gianfar_platform_data gfar_data; 130 struct gianfar_platform_data gfar_data;
@@ -110,7 +138,7 @@ static int __init gfar_of_init(void)
110 138
111 ret = of_address_to_resource(np, 0, &r[0]); 139 ret = of_address_to_resource(np, 0, &r[0]);
112 if (ret) 140 if (ret)
113 goto gfar_err; 141 goto err;
114 142
115 r[1].start = np->intrs[0].line; 143 r[1].start = np->intrs[0].line;
116 r[1].end = np->intrs[0].line; 144 r[1].end = np->intrs[0].line;
@@ -133,11 +161,13 @@ static int __init gfar_of_init(void)
133 r[3].flags = IORESOURCE_IRQ; 161 r[3].flags = IORESOURCE_IRQ;
134 } 162 }
135 163
136 gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1); 164 gfar_dev =
165 platform_device_register_simple("fsl-gianfar", i, &r[0],
166 np->n_intrs + 1);
137 167
138 if (IS_ERR(gfar_dev)) { 168 if (IS_ERR(gfar_dev)) {
139 ret = PTR_ERR(gfar_dev); 169 ret = PTR_ERR(gfar_dev);
140 goto gfar_err; 170 goto err;
141 } 171 }
142 172
143 mac_addr = get_property(np, "address", NULL); 173 mac_addr = get_property(np, "address", NULL);
@@ -145,26 +175,26 @@ static int __init gfar_of_init(void)
145 175
146 if (model && !strcasecmp(model, "TSEC")) 176 if (model && !strcasecmp(model, "TSEC"))
147 gfar_data.device_flags = 177 gfar_data.device_flags =
148 FSL_GIANFAR_DEV_HAS_GIGABIT | 178 FSL_GIANFAR_DEV_HAS_GIGABIT |
149 FSL_GIANFAR_DEV_HAS_COALESCE | 179 FSL_GIANFAR_DEV_HAS_COALESCE |
150 FSL_GIANFAR_DEV_HAS_RMON | 180 FSL_GIANFAR_DEV_HAS_RMON |
151 FSL_GIANFAR_DEV_HAS_MULTI_INTR; 181 FSL_GIANFAR_DEV_HAS_MULTI_INTR;
152 if (model && !strcasecmp(model, "eTSEC")) 182 if (model && !strcasecmp(model, "eTSEC"))
153 gfar_data.device_flags = 183 gfar_data.device_flags =
154 FSL_GIANFAR_DEV_HAS_GIGABIT | 184 FSL_GIANFAR_DEV_HAS_GIGABIT |
155 FSL_GIANFAR_DEV_HAS_COALESCE | 185 FSL_GIANFAR_DEV_HAS_COALESCE |
156 FSL_GIANFAR_DEV_HAS_RMON | 186 FSL_GIANFAR_DEV_HAS_RMON |
157 FSL_GIANFAR_DEV_HAS_MULTI_INTR | 187 FSL_GIANFAR_DEV_HAS_MULTI_INTR |
158 FSL_GIANFAR_DEV_HAS_CSUM | 188 FSL_GIANFAR_DEV_HAS_CSUM |
159 FSL_GIANFAR_DEV_HAS_VLAN | 189 FSL_GIANFAR_DEV_HAS_VLAN |
160 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 190 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
161 191
162 ph = (phandle *) get_property(np, "phy-handle", NULL); 192 ph = (phandle *) get_property(np, "phy-handle", NULL);
163 phy = of_find_node_by_phandle(*ph); 193 phy = of_find_node_by_phandle(*ph);
164 194
165 if (phy == NULL) { 195 if (phy == NULL) {
166 ret = -ENODEV; 196 ret = -ENODEV;
167 goto gfar_unreg; 197 goto unreg;
168 } 198 }
169 199
170 mdio = of_get_parent(phy); 200 mdio = of_get_parent(phy);
@@ -174,7 +204,7 @@ static int __init gfar_of_init(void)
174 if (ret) { 204 if (ret) {
175 of_node_put(phy); 205 of_node_put(phy);
176 of_node_put(mdio); 206 of_node_put(mdio);
177 goto gfar_unreg; 207 goto unreg;
178 } 208 }
179 209
180 gfar_data.phy_id = *id; 210 gfar_data.phy_id = *id;
@@ -183,23 +213,22 @@ static int __init gfar_of_init(void)
183 of_node_put(phy); 213 of_node_put(phy);
184 of_node_put(mdio); 214 of_node_put(mdio);
185 215
186 ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data)); 216 ret =
217 platform_device_add_data(gfar_dev, &gfar_data,
218 sizeof(struct
219 gianfar_platform_data));
187 if (ret) 220 if (ret)
188 goto gfar_unreg; 221 goto unreg;
189 } 222 }
190 223
191 return 0; 224 return 0;
192 225
193mdio_unreg: 226unreg:
194 platform_device_unregister(mdio_dev);
195mdio_err:
196 return ret;
197
198gfar_unreg:
199 platform_device_unregister(gfar_dev); 227 platform_device_unregister(gfar_dev);
200gfar_err: 228err:
201 return ret; 229 return ret;
202} 230}
231
203arch_initcall(gfar_of_init); 232arch_initcall(gfar_of_init);
204 233
205static int __init fsl_i2c_of_init(void) 234static int __init fsl_i2c_of_init(void)
@@ -209,17 +238,19 @@ static int __init fsl_i2c_of_init(void)
209 struct platform_device *i2c_dev; 238 struct platform_device *i2c_dev;
210 int ret; 239 int ret;
211 240
212 for (np = NULL, i = 0; (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; i++) { 241 for (np = NULL, i = 0;
242 (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
243 i++) {
213 struct resource r[2]; 244 struct resource r[2];
214 struct fsl_i2c_platform_data i2c_data; 245 struct fsl_i2c_platform_data i2c_data;
215 unsigned char * flags = NULL; 246 unsigned char *flags = NULL;
216 247
217 memset(&r, 0, sizeof(r)); 248 memset(&r, 0, sizeof(r));
218 memset(&i2c_data, 0, sizeof(i2c_data)); 249 memset(&i2c_data, 0, sizeof(i2c_data));
219 250
220 ret = of_address_to_resource(np, 0, &r[0]); 251 ret = of_address_to_resource(np, 0, &r[0]);
221 if (ret) 252 if (ret)
222 goto i2c_err; 253 goto err;
223 254
224 r[1].start = np->intrs[0].line; 255 r[1].start = np->intrs[0].line;
225 r[1].end = np->intrs[0].line; 256 r[1].end = np->intrs[0].line;
@@ -228,7 +259,7 @@ static int __init fsl_i2c_of_init(void)
228 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); 259 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
229 if (IS_ERR(i2c_dev)) { 260 if (IS_ERR(i2c_dev)) {
230 ret = PTR_ERR(i2c_dev); 261 ret = PTR_ERR(i2c_dev);
231 goto i2c_err; 262 goto err;
232 } 263 }
233 264
234 i2c_data.device_flags = 0; 265 i2c_data.device_flags = 0;
@@ -240,18 +271,22 @@ static int __init fsl_i2c_of_init(void)
240 if (flags) 271 if (flags)
241 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; 272 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
242 273
243 ret = platform_device_add_data(i2c_dev, &i2c_data, sizeof(struct fsl_i2c_platform_data)); 274 ret =
275 platform_device_add_data(i2c_dev, &i2c_data,
276 sizeof(struct
277 fsl_i2c_platform_data));
244 if (ret) 278 if (ret)
245 goto i2c_unreg; 279 goto unreg;
246 } 280 }
247 281
248 return 0; 282 return 0;
249 283
250i2c_unreg: 284unreg:
251 platform_device_unregister(i2c_dev); 285 platform_device_unregister(i2c_dev);
252i2c_err: 286err:
253 return ret; 287 return ret;
254} 288}
289
255arch_initcall(fsl_i2c_of_init); 290arch_initcall(fsl_i2c_of_init);
256 291
257#ifdef CONFIG_PPC_83xx 292#ifdef CONFIG_PPC_83xx
@@ -267,51 +302,192 @@ static int __init mpc83xx_wdt_init(void)
267 302
268 if (!np) { 303 if (!np) {
269 ret = -ENODEV; 304 ret = -ENODEV;
270 goto mpc83xx_wdt_nodev; 305 goto nodev;
271 } 306 }
272 307
273 soc = of_find_node_by_type(NULL, "soc"); 308 soc = of_find_node_by_type(NULL, "soc");
274 309
275 if (!soc) { 310 if (!soc) {
276 ret = -ENODEV; 311 ret = -ENODEV;
277 goto mpc83xx_wdt_nosoc; 312 goto nosoc;
278 } 313 }
279 314
280 freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); 315 freq = (unsigned int *)get_property(soc, "bus-frequency", NULL);
281 if (!freq) { 316 if (!freq) {
282 ret = -ENODEV; 317 ret = -ENODEV;
283 goto mpc83xx_wdt_err; 318 goto err;
284 } 319 }
285 320
286 memset(&r, 0, sizeof(r)); 321 memset(&r, 0, sizeof(r));
287 322
288 ret = of_address_to_resource(np, 0, &r); 323 ret = of_address_to_resource(np, 0, &r);
289 if (ret) 324 if (ret)
290 goto mpc83xx_wdt_err; 325 goto err;
291 326
292 dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); 327 dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
293 if (IS_ERR(dev)) { 328 if (IS_ERR(dev)) {
294 ret = PTR_ERR(dev); 329 ret = PTR_ERR(dev);
295 goto mpc83xx_wdt_err; 330 goto err;
296 } 331 }
297 332
298 ret = platform_device_add_data(dev, freq, sizeof(int)); 333 ret = platform_device_add_data(dev, freq, sizeof(int));
299 if (ret) 334 if (ret)
300 goto mpc83xx_wdt_unreg; 335 goto unreg;
301 336
302 of_node_put(soc); 337 of_node_put(soc);
303 of_node_put(np); 338 of_node_put(np);
304 339
305 return 0; 340 return 0;
306 341
307mpc83xx_wdt_unreg: 342unreg:
308 platform_device_unregister(dev); 343 platform_device_unregister(dev);
309mpc83xx_wdt_err: 344err:
310 of_node_put(soc); 345 of_node_put(soc);
311mpc83xx_wdt_nosoc: 346nosoc:
312 of_node_put(np); 347 of_node_put(np);
313mpc83xx_wdt_nodev: 348nodev:
314 return ret; 349 return ret;
315} 350}
351
316arch_initcall(mpc83xx_wdt_init); 352arch_initcall(mpc83xx_wdt_init);
317#endif 353#endif
354
355static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type)
356{
357 if (!phy_type)
358 return FSL_USB2_PHY_NONE;
359 if (!strcasecmp(phy_type, "ulpi"))
360 return FSL_USB2_PHY_ULPI;
361 if (!strcasecmp(phy_type, "utmi"))
362 return FSL_USB2_PHY_UTMI;
363 if (!strcasecmp(phy_type, "utmi_wide"))
364 return FSL_USB2_PHY_UTMI_WIDE;
365 if (!strcasecmp(phy_type, "serial"))
366 return FSL_USB2_PHY_SERIAL;
367
368 return FSL_USB2_PHY_NONE;
369}
370
371static int __init fsl_usb_of_init(void)
372{
373 struct device_node *np;
374 unsigned int i;
375 struct platform_device *usb_dev;
376 int ret;
377
378 for (np = NULL, i = 0;
379 (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
380 i++) {
381 struct resource r[2];
382 struct fsl_usb2_platform_data usb_data;
383 unsigned char *prop = NULL;
384
385 memset(&r, 0, sizeof(r));
386 memset(&usb_data, 0, sizeof(usb_data));
387
388 ret = of_address_to_resource(np, 0, &r[0]);
389 if (ret)
390 goto err;
391
392 r[1].start = np->intrs[0].line;
393 r[1].end = np->intrs[0].line;
394 r[1].flags = IORESOURCE_IRQ;
395
396 usb_dev =
397 platform_device_register_simple("fsl-usb2-mph", i, r, 2);
398 if (IS_ERR(usb_dev)) {
399 ret = PTR_ERR(usb_dev);
400 goto err;
401 }
402
403 usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
404 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
405
406 usb_data.operating_mode = FSL_USB2_MPH_HOST;
407
408 prop = get_property(np, "port0", NULL);
409 if (prop)
410 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
411
412 prop = get_property(np, "port1", NULL);
413 if (prop)
414 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
415
416 prop = get_property(np, "phy_type", NULL);
417 usb_data.phy_mode = determine_usb_phy(prop);
418
419 ret =
420 platform_device_add_data(usb_dev, &usb_data,
421 sizeof(struct
422 fsl_usb2_platform_data));
423 if (ret)
424 goto unreg;
425 }
426
427 return 0;
428
429unreg:
430 platform_device_unregister(usb_dev);
431err:
432 return ret;
433}
434
435arch_initcall(fsl_usb_of_init);
436
437static int __init fsl_usb_dr_of_init(void)
438{
439 struct device_node *np;
440 unsigned int i;
441 struct platform_device *usb_dev;
442 int ret;
443
444 for (np = NULL, i = 0;
445 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
446 i++) {
447 struct resource r[2];
448 struct fsl_usb2_platform_data usb_data;
449 unsigned char *prop = NULL;
450
451 memset(&r, 0, sizeof(r));
452 memset(&usb_data, 0, sizeof(usb_data));
453
454 ret = of_address_to_resource(np, 0, &r[0]);
455 if (ret)
456 goto err;
457
458 r[1].start = np->intrs[0].line;
459 r[1].end = np->intrs[0].line;
460 r[1].flags = IORESOURCE_IRQ;
461
462 usb_dev =
463 platform_device_register_simple("fsl-usb2-dr", i, r, 2);
464 if (IS_ERR(usb_dev)) {
465 ret = PTR_ERR(usb_dev);
466 goto err;
467 }
468
469 usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
470 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
471
472 usb_data.operating_mode = FSL_USB2_DR_HOST;
473
474 prop = get_property(np, "phy_type", NULL);
475 usb_data.phy_mode = determine_usb_phy(prop);
476
477 ret =
478 platform_device_add_data(usb_dev, &usb_data,
479 sizeof(struct
480 fsl_usb2_platform_data));
481 if (ret)
482 goto unreg;
483 }
484
485 return 0;
486
487unreg:
488 platform_device_unregister(usb_dev);
489err:
490 return ret;
491}
492
493arch_initcall(fsl_usb_dr_of_init);
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index a7ce7da8785c..a60c9d18bb7f 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/ipic.h
3 *
4 * IPIC private definitions and structure. 2 * IPIC private definitions and structure.
5 * 3 *
6 * Maintainer: Kumar Gala <galak@kernel.crashing.org> 4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 7d02fa2a8990..4735b41c113c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -191,6 +191,7 @@ Commands:\n\
191 di dump instructions\n\ 191 di dump instructions\n\
192 df dump float values\n\ 192 df dump float values\n\
193 dd dump double values\n\ 193 dd dump double values\n\
194 dr dump stream of raw bytes\n\
194 e print exception information\n\ 195 e print exception information\n\
195 f flush cache\n\ 196 f flush cache\n\
196 la lookup symbol+offset of specified address\n\ 197 la lookup symbol+offset of specified address\n\
@@ -1938,6 +1939,28 @@ bsesc(void)
1938 return c; 1939 return c;
1939} 1940}
1940 1941
1942static void xmon_rawdump (unsigned long adrs, long ndump)
1943{
1944 long n, m, r, nr;
1945 unsigned char temp[16];
1946
1947 for (n = ndump; n > 0;) {
1948 r = n < 16? n: 16;
1949 nr = mread(adrs, temp, r);
1950 adrs += nr;
1951 for (m = 0; m < r; ++m) {
1952 if (m < nr)
1953 printf("%.2x", temp[m]);
1954 else
1955 printf("%s", fault_chars[fault_type]);
1956 }
1957 n -= r;
1958 if (nr < r)
1959 break;
1960 }
1961 printf("\n");
1962}
1963
1941#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 1964#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1942 || ('a' <= (c) && (c) <= 'f') \ 1965 || ('a' <= (c) && (c) <= 'f') \
1943 || ('A' <= (c) && (c) <= 'F')) 1966 || ('A' <= (c) && (c) <= 'F'))
@@ -1960,6 +1983,13 @@ dump(void)
1960 nidump = MAX_DUMP; 1983 nidump = MAX_DUMP;
1961 adrs += ppc_inst_dump(adrs, nidump, 1); 1984 adrs += ppc_inst_dump(adrs, nidump, 1);
1962 last_cmd = "di\n"; 1985 last_cmd = "di\n";
1986 } else if (c == 'r') {
1987 scanhex(&ndump);
1988 if (ndump == 0)
1989 ndump = 64;
1990 xmon_rawdump(adrs, ndump);
1991 adrs += ndump;
1992 last_cmd = "dr\n";
1963 } else { 1993 } else {
1964 scanhex(&ndump); 1994 scanhex(&ndump);
1965 if (ndump == 0) 1995 if (ndump == 0)